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-2025-01-06' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for 6.14:

UAPI Changes:
- Clarify drm memory stats documentation

Cross-subsystem Changes:

Core Changes:
- sched: Documentation fixes,

Driver Changes:
- amdgpu: Track BO memory stats at runtime
- amdxdna: Various fixes
- hisilicon: New HIBMC driver
- bridges:
- Provide default implementation of atomic_check for HDMI bridges
- it605: HDCP improvements, MCCS Support

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

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250106-augmented-kakapo-of-action-0cf000@houat

+2516 -606
+2
Documentation/devicetree/bindings/display/panel/panel-simple.yaml
··· 290 290 - tianma,tm070jvhg33 291 291 # Tianma Micro-electronics TM070RVHG71 7.0" WXGA TFT LCD panel 292 292 - tianma,tm070rvhg71 293 + # Topland TIAN-G07017-01 7.0" WSVGA TFT-LCD panel with capacitive touch 294 + - topland,tian-g07017-01 293 295 # Toshiba 8.9" WXGA (1280x768) TFT LCD panel 294 296 - toshiba,lt089ac29000 295 297 # TPK U.S.A. LLC Fusion 7" 800 x 480 (WVGA) LCD panel with capacitive touch
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 1524 1524 description: Topeet 1525 1525 "^topic,.*": 1526 1526 description: Topic Embedded Systems 1527 + "^topland,.*": 1528 + description: Topland Electronics (H.K) Co., Ltd. 1527 1529 "^toppoly,.*": 1528 1530 description: TPO (deprecated, use tpo) 1529 1531 deprecated: true
+27 -27
Documentation/gpu/drm-usage-stats.rst
··· 145 145 Memory 146 146 ^^^^^^ 147 147 148 - - drm-memory-<region>: <uint> [KiB|MiB] 149 - 150 - Each possible memory type which can be used to store buffer objects by the 151 - GPU in question shall be given a stable and unique name to be returned as the 152 - string here. 148 + Each possible memory type which can be used to store buffer objects by the GPU 149 + in question shall be given a stable and unique name to be used as the "<region>" 150 + string. 153 151 154 152 The region name "memory" is reserved to refer to normal system memory. 155 153 156 - Value shall reflect the amount of storage currently consumed by the buffer 154 + The value shall reflect the amount of storage currently consumed by the buffer 157 155 objects belong to this client, in the respective memory region. 158 156 159 157 Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB' 160 158 indicating kibi- or mebi-bytes. 161 159 162 - This key is deprecated and is an alias for drm-resident-<region>. Only one of 163 - the two should be present in the output. 160 + - drm-total-<region>: <uint> [KiB|MiB] 161 + 162 + The total size of all requested buffers, including both shared and private 163 + memory. The backing store for the buffers does not need to be currently 164 + instantiated to count under this category. To avoid double-counting, if a buffer 165 + has multiple regions where it can be allocated to, the implementation should 166 + consistently select a single region for accounting purposes. 164 167 165 168 - drm-shared-<region>: <uint> [KiB|MiB] 166 169 167 - The total size of buffers that are shared with another file (e.g., have more 168 - than a single handle). 169 - 170 - - drm-total-<region>: <uint> [KiB|MiB] 171 - 172 - The total size of all created buffers including shared and private memory. The 173 - backing store for the buffers does not have to be currently instantiated to be 174 - counted under this category. 170 + The total size of buffers that are shared with another file (i.e., have more 171 + than one handle). The same requirement to avoid double-counting that applies to 172 + drm-total-<region> also applies here. 175 173 176 174 - drm-resident-<region>: <uint> [KiB|MiB] 177 175 178 - The total size of buffers that are resident (have their backing store present or 179 - instantiated) in the specified region. 176 + The total size of buffers that are resident (i.e., have their backing store 177 + present or instantiated) in the specified region. 180 178 181 - This is an alias for drm-memory-<region> and only one of the two should be 182 - present in the output. 179 + - drm-memory-<region>: <uint> [KiB|MiB] 180 + 181 + This key is deprecated and is only printed by amdgpu; it is an alias for 182 + drm-resident-<region>. 183 183 184 184 - drm-purgeable-<region>: <uint> [KiB|MiB] 185 185 186 - The total size of buffers that are purgeable. 186 + The total size of buffers that are resident and purgeable. 187 187 188 - For example drivers which implement a form of 'madvise' like functionality can 189 - here count buffers which have instantiated backing store, but have been marked 190 - with an equivalent of MADV_DONTNEED. 188 + For example, drivers that implement functionality similar to 'madvise' can count 189 + buffers that have instantiated backing stores but have been marked with an 190 + equivalent of MADV_DONTNEED. 191 191 192 192 - drm-active-<region>: <uint> [KiB|MiB] 193 193 194 194 The total size of buffers that are active on one or more engines. 195 195 196 - One practical example of this can be presence of unsignaled fences in an GEM 197 - buffer reservation object. Therefore the active category is a subset of 198 - resident. 196 + One practical example of this could be the presence of unsignaled fences in a 197 + GEM buffer reservation object. Therefore, the active category is a subset of the 198 + resident category. 199 199 200 200 Implementation Details 201 201 ======================
+2 -1
MAINTAINERS
··· 7081 7081 F: drivers/gpu/drm/sun4i/sun8i* 7082 7082 7083 7083 DRM DRIVER FOR ARM PL111 CLCD 7084 - S: Orphan 7084 + M: Linus Walleij <linus.walleij@linaro.org> 7085 + S: Maintained 7085 7086 T: git https://gitlab.freedesktop.org/drm/misc/kernel.git 7086 7087 F: drivers/gpu/drm/pl111/ 7087 7088
+1 -1
drivers/accel/amdxdna/aie2_ctx.c
··· 22 22 #include "amdxdna_mailbox.h" 23 23 #include "amdxdna_pci_drv.h" 24 24 25 - bool force_cmdlist; 25 + static bool force_cmdlist; 26 26 module_param(force_cmdlist, bool, 0600); 27 27 MODULE_PARM_DESC(force_cmdlist, "Force use command list (Default false)"); 28 28
+3 -3
drivers/accel/amdxdna/aie2_pci.c
··· 25 25 #include "amdxdna_mailbox.h" 26 26 #include "amdxdna_pci_drv.h" 27 27 28 - int aie2_max_col = XRS_MAX_COL; 28 + static int aie2_max_col = XRS_MAX_COL; 29 29 module_param(aie2_max_col, uint, 0600); 30 30 MODULE_PARM_DESC(aie2_max_col, "Maximum column could be used"); 31 31 ··· 380 380 goto stop_psp; 381 381 } 382 382 383 - mbox_res.ringbuf_base = (u64)ndev->sram_base; 383 + mbox_res.ringbuf_base = ndev->sram_base; 384 384 mbox_res.ringbuf_size = pci_resource_len(pdev, xdna->dev_info->sram_bar); 385 - mbox_res.mbox_base = (u64)ndev->mbox_base; 385 + mbox_res.mbox_base = ndev->mbox_base; 386 386 mbox_res.mbox_size = MBOX_SIZE(ndev); 387 387 mbox_res.name = "xdna_mailbox"; 388 388 ndev->mbox = xdnam_mailbox_create(&xdna->ddev, &mbox_res);
+1 -1
drivers/accel/amdxdna/aie2_pci.h
··· 269 269 int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx); 270 270 int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx); 271 271 int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size); 272 - int aie2_query_status(struct amdxdna_dev_hdl *ndev, char *buf, u32 size, u32 *cols_filled); 272 + int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf, u32 size, u32 *cols_filled); 273 273 int aie2_register_asyn_event_msg(struct amdxdna_dev_hdl *ndev, dma_addr_t addr, u32 size, 274 274 void *handle, int (*cb)(void*, const u32 *, size_t)); 275 275 int aie2_config_cu(struct amdxdna_hwctx *hwctx);
+12 -12
drivers/accel/amdxdna/amdxdna_mailbox.c
··· 98 98 static void mailbox_reg_write(struct mailbox_channel *mb_chann, u32 mbox_reg, u32 data) 99 99 { 100 100 struct xdna_mailbox_res *mb_res = &mb_chann->mb->res; 101 - u64 ringbuf_addr = mb_res->mbox_base + mbox_reg; 101 + void __iomem *ringbuf_addr = mb_res->mbox_base + mbox_reg; 102 102 103 - writel(data, (void *)ringbuf_addr); 103 + writel(data, ringbuf_addr); 104 104 } 105 105 106 106 static u32 mailbox_reg_read(struct mailbox_channel *mb_chann, u32 mbox_reg) 107 107 { 108 108 struct xdna_mailbox_res *mb_res = &mb_chann->mb->res; 109 - u64 ringbuf_addr = mb_res->mbox_base + mbox_reg; 109 + void __iomem *ringbuf_addr = mb_res->mbox_base + mbox_reg; 110 110 111 - return readl((void *)ringbuf_addr); 111 + return readl(ringbuf_addr); 112 112 } 113 113 114 114 static int mailbox_reg_read_non_zero(struct mailbox_channel *mb_chann, u32 mbox_reg, u32 *val) 115 115 { 116 116 struct xdna_mailbox_res *mb_res = &mb_chann->mb->res; 117 - u64 ringbuf_addr = mb_res->mbox_base + mbox_reg; 117 + void __iomem *ringbuf_addr = mb_res->mbox_base + mbox_reg; 118 118 int ret, value; 119 119 120 120 /* Poll till value is not zero */ 121 - ret = readx_poll_timeout(readl, (void *)ringbuf_addr, value, 121 + ret = readx_poll_timeout(readl, ringbuf_addr, value, 122 122 value, 1 /* us */, 100); 123 123 if (ret < 0) 124 124 return ret; ··· 200 200 static int 201 201 mailbox_send_msg(struct mailbox_channel *mb_chann, struct mailbox_msg *mb_msg) 202 202 { 203 + void __iomem *write_addr; 203 204 u32 ringbuf_size; 204 205 u32 head, tail; 205 206 u32 start_addr; 206 - u64 write_addr; 207 207 u32 tmp_tail; 208 208 209 209 head = mailbox_get_headptr(mb_chann, CHAN_RES_X2I); ··· 221 221 222 222 if (tail >= head && tmp_tail > ringbuf_size - sizeof(u32)) { 223 223 write_addr = mb_chann->mb->res.ringbuf_base + start_addr + tail; 224 - writel(TOMBSTONE, (void *)write_addr); 224 + writel(TOMBSTONE, write_addr); 225 225 226 226 /* tombstone is set. Write from the start of the ringbuf */ 227 227 tail = 0; 228 228 } 229 229 230 230 write_addr = mb_chann->mb->res.ringbuf_base + start_addr + tail; 231 - memcpy_toio((void *)write_addr, &mb_msg->pkg, mb_msg->pkg_size); 231 + memcpy_toio(write_addr, &mb_msg->pkg, mb_msg->pkg_size); 232 232 mailbox_set_tailptr(mb_chann, tail + mb_msg->pkg_size); 233 233 234 234 trace_mbox_set_tail(MAILBOX_NAME, mb_chann->msix_irq, ··· 275 275 static int mailbox_get_msg(struct mailbox_channel *mb_chann) 276 276 { 277 277 struct xdna_msg_header header; 278 + void __iomem *read_addr; 278 279 u32 msg_size, rest; 279 280 u32 ringbuf_size; 280 281 u32 head, tail; 281 282 u32 start_addr; 282 - u64 read_addr; 283 283 int ret; 284 284 285 285 if (mailbox_reg_read_non_zero(mb_chann, mb_chann->res[CHAN_RES_I2X].mb_tail_ptr_reg, &tail)) ··· 302 302 303 303 /* Peek size of the message or TOMBSTONE */ 304 304 read_addr = mb_chann->mb->res.ringbuf_base + start_addr + head; 305 - header.total_size = readl((void *)read_addr); 305 + header.total_size = readl(read_addr); 306 306 /* size is TOMBSTONE, set next read from 0 */ 307 307 if (header.total_size == TOMBSTONE) { 308 308 if (head < tail) { ··· 328 328 329 329 rest = sizeof(header) - sizeof(u32); 330 330 read_addr += sizeof(u32); 331 - memcpy_fromio((u32 *)&header + 1, (void *)read_addr, rest); 331 + memcpy_fromio((u32 *)&header + 1, read_addr, rest); 332 332 read_addr += rest; 333 333 334 334 ret = mailbox_get_resp(mb_chann, &header, (u32 *)read_addr);
+2 -2
drivers/accel/amdxdna/amdxdna_mailbox.h
··· 39 39 * @mbox_size: mailbox size 40 40 */ 41 41 struct xdna_mailbox_res { 42 - u64 ringbuf_base; 42 + void __iomem *ringbuf_base; 43 43 size_t ringbuf_size; 44 - u64 mbox_base; 44 + void __iomem *mbox_base; 45 45 size_t mbox_size; 46 46 const char *name; 47 47 };
+1 -1
drivers/accel/amdxdna/amdxdna_pci_drv.c
··· 61 61 goto put_rpm; 62 62 } 63 63 64 - client->pid = pid_nr(filp->pid); 64 + client->pid = pid_nr(rcu_access_pointer(filp->pid)); 65 65 client->xdna = xdna; 66 66 67 67 client->sva = iommu_sva_bind_device(xdna->ddev.dev, current->mm);
+1 -1
drivers/accel/amdxdna/npu1_regs.c
··· 62 62 { 0 } 63 63 }; 64 64 65 - const struct amdxdna_dev_priv npu1_dev_priv = { 65 + static const struct amdxdna_dev_priv npu1_dev_priv = { 66 66 .fw_path = "amdnpu/1502_00/npu.sbin", 67 67 .protocol_major = 0x5, 68 68 .protocol_minor = 0x7,
+1 -1
drivers/accel/amdxdna/npu2_regs.c
··· 61 61 #define NPU2_SMU_BAR_BASE MMNPU_APERTURE4_BASE 62 62 #define NPU2_SRAM_BAR_BASE MMNPU_APERTURE1_BASE 63 63 64 - const struct amdxdna_dev_priv npu2_dev_priv = { 64 + static const struct amdxdna_dev_priv npu2_dev_priv = { 65 65 .fw_path = "amdnpu/17f0_00/npu.sbin", 66 66 .protocol_major = 0x6, 67 67 .protocol_minor = 0x6,
+1 -1
drivers/accel/amdxdna/npu4_regs.c
··· 82 82 { 0 } 83 83 }; 84 84 85 - const struct amdxdna_dev_priv npu4_dev_priv = { 85 + static const struct amdxdna_dev_priv npu4_dev_priv = { 86 86 .fw_path = "amdnpu/17f0_10/npu.sbin", 87 87 .protocol_major = 0x6, 88 88 .protocol_minor = 12,
+1 -1
drivers/accel/amdxdna/npu5_regs.c
··· 61 61 #define NPU5_SMU_BAR_BASE MMNPU_APERTURE4_BASE 62 62 #define NPU5_SRAM_BAR_BASE MMNPU_APERTURE1_BASE 63 63 64 - const struct amdxdna_dev_priv npu5_dev_priv = { 64 + static const struct amdxdna_dev_priv npu5_dev_priv = { 65 65 .fw_path = "amdnpu/17f0_11/npu.sbin", 66 66 .protocol_major = 0x6, 67 67 .protocol_minor = 12,
+1 -1
drivers/accel/amdxdna/npu6_regs.c
··· 61 61 #define NPU6_SMU_BAR_BASE MMNPU_APERTURE4_BASE 62 62 #define NPU6_SRAM_BAR_BASE MMNPU_APERTURE1_BASE 63 63 64 - const struct amdxdna_dev_priv npu6_dev_priv = { 64 + static const struct amdxdna_dev_priv npu6_dev_priv = { 65 65 .fw_path = "amdnpu/17f0_10/npu.sbin", 66 66 .protocol_major = 0x6, 67 67 .protocol_minor = 12,
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 1105 1105 * We can't use gang submit on with reserved VMIDs when the VM changes 1106 1106 * can't be invalidated by more than one engine at the same time. 1107 1107 */ 1108 - if (p->gang_size > 1 && !p->adev->vm_manager.concurrent_flush) { 1108 + if (p->gang_size > 1 && !adev->vm_manager.concurrent_flush) { 1109 1109 for (i = 0; i < p->gang_size; ++i) { 1110 1110 struct drm_sched_entity *entity = p->entities[i]; 1111 1111 struct drm_gpu_scheduler *sched = entity->rq->sched; ··· 1189 1189 if (!bo) 1190 1190 continue; 1191 1191 1192 - amdgpu_vm_bo_invalidate(adev, bo, false); 1192 + amdgpu_vm_bo_invalidate(bo, false); 1193 1193 } 1194 1194 } 1195 1195
+4 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
··· 36 36 #include "amdgpu_gem.h" 37 37 #include "amdgpu_dma_buf.h" 38 38 #include "amdgpu_xgmi.h" 39 + #include "amdgpu_vm.h" 39 40 #include <drm/amdgpu_drm.h> 40 41 #include <drm/ttm/ttm_tt.h> 41 42 #include <linux/dma-buf.h> ··· 60 59 61 60 if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) 62 61 attach->peer2peer = false; 62 + 63 + amdgpu_vm_bo_update_shared(bo); 63 64 64 65 return 0; 65 66 } ··· 348 345 /* FIXME: This should be after the "if", but needs a fix to make sure 349 346 * DMABuf imports are initialized in the right VM list. 350 347 */ 351 - amdgpu_vm_bo_invalidate(adev, bo, false); 348 + amdgpu_vm_bo_invalidate(bo, false); 352 349 if (!bo->tbo.resource || bo->tbo.resource->mem_type == TTM_PL_SYSTEM) 353 350 return; 354 351
+6 -11
drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
··· 60 60 struct amdgpu_fpriv *fpriv = file->driver_priv; 61 61 struct amdgpu_vm *vm = &fpriv->vm; 62 62 63 - struct amdgpu_mem_stats stats[__AMDGPU_PL_LAST + 1] = { }; 63 + struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]; 64 64 ktime_t usage[AMDGPU_HW_IP_NUM]; 65 65 const char *pl_name[] = { 66 66 [TTM_PL_VRAM] = "vram", ··· 72 72 [AMDGPU_PL_DOORBELL] = "doorbell", 73 73 }; 74 74 unsigned int hw_ip, i; 75 - int ret; 76 75 77 - ret = amdgpu_bo_reserve(vm->root.bo, false); 78 - if (ret) 79 - return; 80 - 81 - amdgpu_vm_get_memory(vm, stats, ARRAY_SIZE(stats)); 82 - amdgpu_bo_unreserve(vm->root.bo); 83 - 76 + amdgpu_vm_get_memory(vm, stats); 84 77 amdgpu_ctx_mgr_usage(&fpriv->ctx_mgr, usage); 85 78 86 79 /* ··· 107 114 drm_printf(p, "amd-evicted-vram:\t%llu KiB\n", 108 115 stats[TTM_PL_VRAM].evicted/1024UL); 109 116 drm_printf(p, "amd-requested-vram:\t%llu KiB\n", 110 - stats[TTM_PL_VRAM].requested/1024UL); 117 + (stats[TTM_PL_VRAM].drm.shared + 118 + stats[TTM_PL_VRAM].drm.private) / 1024UL); 111 119 drm_printf(p, "amd-requested-gtt:\t%llu KiB\n", 112 - stats[TTM_PL_TT].requested/1024UL); 120 + (stats[TTM_PL_TT].drm.shared + 121 + stats[TTM_PL_TT].drm.private) / 1024UL); 113 122 114 123 for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) { 115 124 if (!usage[hw_ip])
+4 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
··· 42 42 #include "amdgpu_dma_buf.h" 43 43 #include "amdgpu_hmm.h" 44 44 #include "amdgpu_xgmi.h" 45 + #include "amdgpu_vm.h" 45 46 46 47 static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf) 47 48 { ··· 180 179 if (r) 181 180 return r; 182 181 182 + amdgpu_vm_bo_update_shared(abo); 183 183 bo_va = amdgpu_vm_bo_find(vm, abo); 184 184 if (!bo_va) 185 185 bo_va = amdgpu_vm_bo_add(adev, vm, abo); ··· 254 252 goto out_unlock; 255 253 256 254 amdgpu_vm_bo_del(adev, bo_va); 255 + amdgpu_vm_bo_update_shared(bo); 257 256 if (!amdgpu_vm_ready(vm)) 258 257 goto out_unlock; 259 258 ··· 842 839 int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, 843 840 struct drm_file *filp) 844 841 { 845 - struct amdgpu_device *adev = drm_to_adev(dev); 846 842 struct drm_amdgpu_gem_op *args = data; 847 843 struct drm_gem_object *gobj; 848 844 struct amdgpu_vm_bo_base *base; ··· 901 899 robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; 902 900 903 901 if (robj->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) 904 - amdgpu_vm_bo_invalidate(adev, robj, true); 902 + amdgpu_vm_bo_invalidate(robj, true); 905 903 906 904 amdgpu_bo_unreserve(robj); 907 905 break;
+40 -71
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
··· 1251 1251 bool evict, 1252 1252 struct ttm_resource *new_mem) 1253 1253 { 1254 - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); 1255 1254 struct ttm_resource *old_mem = bo->resource; 1256 1255 struct amdgpu_bo *abo; 1257 1256 ··· 1258 1259 return; 1259 1260 1260 1261 abo = ttm_to_amdgpu_bo(bo); 1261 - amdgpu_vm_bo_invalidate(adev, abo, evict); 1262 + amdgpu_vm_bo_move(abo, new_mem, evict); 1262 1263 1263 1264 amdgpu_bo_kunmap(abo); 1264 1265 ··· 1269 1270 /* move_notify is called before move happens */ 1270 1271 trace_amdgpu_bo_move(abo, new_mem ? new_mem->mem_type : -1, 1271 1272 old_mem ? old_mem->mem_type : -1); 1272 - } 1273 - 1274 - void amdgpu_bo_get_memory(struct amdgpu_bo *bo, 1275 - struct amdgpu_mem_stats *stats, 1276 - unsigned int sz) 1277 - { 1278 - const unsigned int domain_to_pl[] = { 1279 - [ilog2(AMDGPU_GEM_DOMAIN_CPU)] = TTM_PL_SYSTEM, 1280 - [ilog2(AMDGPU_GEM_DOMAIN_GTT)] = TTM_PL_TT, 1281 - [ilog2(AMDGPU_GEM_DOMAIN_VRAM)] = TTM_PL_VRAM, 1282 - [ilog2(AMDGPU_GEM_DOMAIN_GDS)] = AMDGPU_PL_GDS, 1283 - [ilog2(AMDGPU_GEM_DOMAIN_GWS)] = AMDGPU_PL_GWS, 1284 - [ilog2(AMDGPU_GEM_DOMAIN_OA)] = AMDGPU_PL_OA, 1285 - [ilog2(AMDGPU_GEM_DOMAIN_DOORBELL)] = AMDGPU_PL_DOORBELL, 1286 - }; 1287 - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 1288 - struct ttm_resource *res = bo->tbo.resource; 1289 - struct drm_gem_object *obj = &bo->tbo.base; 1290 - uint64_t size = amdgpu_bo_size(bo); 1291 - unsigned int type; 1292 - 1293 - if (!res) { 1294 - /* 1295 - * If no backing store use one of the preferred domain for basic 1296 - * stats. We take the MSB since that should give a reasonable 1297 - * view. 1298 - */ 1299 - BUILD_BUG_ON(TTM_PL_VRAM < TTM_PL_TT || 1300 - TTM_PL_VRAM < TTM_PL_SYSTEM); 1301 - type = fls(bo->preferred_domains & AMDGPU_GEM_DOMAIN_MASK); 1302 - if (!type) 1303 - return; 1304 - type--; 1305 - if (drm_WARN_ON_ONCE(&adev->ddev, 1306 - type >= ARRAY_SIZE(domain_to_pl))) 1307 - return; 1308 - type = domain_to_pl[type]; 1309 - } else { 1310 - type = res->mem_type; 1311 - } 1312 - 1313 - if (drm_WARN_ON_ONCE(&adev->ddev, type >= sz)) 1314 - return; 1315 - 1316 - /* DRM stats common fields: */ 1317 - 1318 - if (drm_gem_object_is_shared_for_memory_stats(obj)) 1319 - stats[type].drm.shared += size; 1320 - else 1321 - stats[type].drm.private += size; 1322 - 1323 - if (res) { 1324 - stats[type].drm.resident += size; 1325 - 1326 - if (!dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_BOOKKEEP)) 1327 - stats[type].drm.active += size; 1328 - else if (bo->flags & AMDGPU_GEM_CREATE_DISCARDABLE) 1329 - stats[type].drm.purgeable += size; 1330 - } 1331 - 1332 - /* amdgpu specific stats: */ 1333 - 1334 - if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) { 1335 - stats[TTM_PL_VRAM].requested += size; 1336 - if (type != TTM_PL_VRAM) 1337 - stats[TTM_PL_VRAM].evicted += size; 1338 - } else if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_GTT) { 1339 - stats[TTM_PL_TT].requested += size; 1340 - } 1341 1273 } 1342 1274 1343 1275 /** ··· 1483 1553 amdgpu_ttm_domain_start(adev, bo->tbo.resource->mem_type); 1484 1554 1485 1555 return amdgpu_gmc_sign_extend(offset); 1556 + } 1557 + 1558 + /** 1559 + * amdgpu_bo_mem_stats_placement - bo placement for memory accounting 1560 + * @bo: the buffer object we should look at 1561 + * 1562 + * BO can have multiple preferred placements, to avoid double counting we want 1563 + * to file it under a single placement for memory stats. 1564 + * Luckily, if we take the highest set bit in preferred_domains the result is 1565 + * quite sensible. 1566 + * 1567 + * Returns: 1568 + * Which of the placements should the BO be accounted under. 1569 + */ 1570 + uint32_t amdgpu_bo_mem_stats_placement(struct amdgpu_bo *bo) 1571 + { 1572 + uint32_t domain = bo->preferred_domains & AMDGPU_GEM_DOMAIN_MASK; 1573 + 1574 + if (!domain) 1575 + return TTM_PL_SYSTEM; 1576 + 1577 + switch (rounddown_pow_of_two(domain)) { 1578 + case AMDGPU_GEM_DOMAIN_CPU: 1579 + return TTM_PL_SYSTEM; 1580 + case AMDGPU_GEM_DOMAIN_GTT: 1581 + return TTM_PL_TT; 1582 + case AMDGPU_GEM_DOMAIN_VRAM: 1583 + return TTM_PL_VRAM; 1584 + case AMDGPU_GEM_DOMAIN_GDS: 1585 + return AMDGPU_PL_GDS; 1586 + case AMDGPU_GEM_DOMAIN_GWS: 1587 + return AMDGPU_PL_GWS; 1588 + case AMDGPU_GEM_DOMAIN_OA: 1589 + return AMDGPU_PL_OA; 1590 + case AMDGPU_GEM_DOMAIN_DOORBELL: 1591 + return AMDGPU_PL_DOORBELL; 1592 + default: 1593 + return TTM_PL_SYSTEM; 1594 + } 1486 1595 } 1487 1596 1488 1597 /**
+1 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
··· 305 305 int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr); 306 306 u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo); 307 307 u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo); 308 - void amdgpu_bo_get_memory(struct amdgpu_bo *bo, 309 - struct amdgpu_mem_stats *stats, 310 - unsigned int size); 308 + uint32_t amdgpu_bo_mem_stats_placement(struct amdgpu_bo *bo); 311 309 uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev, 312 310 uint32_t domain); 313 311
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
··· 26 26 27 27 #include <linux/dma-direction.h> 28 28 #include <drm/gpu_scheduler.h> 29 + #include <drm/ttm/ttm_placement.h> 29 30 #include "amdgpu_vram_mgr.h" 30 - #include "amdgpu.h" 31 31 32 32 #define AMDGPU_PL_GDS (TTM_PL_PRIV + 0) 33 33 #define AMDGPU_PL_GWS (TTM_PL_PRIV + 1) 34 34 #define AMDGPU_PL_OA (TTM_PL_PRIV + 2) 35 35 #define AMDGPU_PL_PREEMPT (TTM_PL_PRIV + 3) 36 36 #define AMDGPU_PL_DOORBELL (TTM_PL_PRIV + 4) 37 - #define __AMDGPU_PL_LAST (TTM_PL_PRIV + 4) 37 + #define __AMDGPU_PL_NUM (TTM_PL_PRIV + 5) 38 38 39 39 #define AMDGPU_GTT_MAX_TRANSFER_SIZE 512 40 40 #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2
+161 -48
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 36 36 #include <drm/ttm/ttm_tt.h> 37 37 #include <drm/drm_exec.h> 38 38 #include "amdgpu.h" 39 + #include "amdgpu_vm.h" 39 40 #include "amdgpu_trace.h" 40 41 #include "amdgpu_amdkfd.h" 41 42 #include "amdgpu_gmc.h" ··· 312 311 } 313 312 314 313 /** 314 + * amdgpu_vm_update_shared - helper to update shared memory stat 315 + * @base: base structure for tracking BO usage in a VM 316 + * 317 + * Takes the vm status_lock and updates the shared memory stat. If the basic 318 + * stat changed (e.g. buffer was moved) amdgpu_vm_update_stats need to be called 319 + * as well. 320 + */ 321 + static void amdgpu_vm_update_shared(struct amdgpu_vm_bo_base *base) 322 + { 323 + struct amdgpu_vm *vm = base->vm; 324 + struct amdgpu_bo *bo = base->bo; 325 + uint64_t size = amdgpu_bo_size(bo); 326 + uint32_t bo_memtype = amdgpu_bo_mem_stats_placement(bo); 327 + bool shared; 328 + 329 + spin_lock(&vm->status_lock); 330 + shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base); 331 + if (base->shared != shared) { 332 + base->shared = shared; 333 + if (shared) { 334 + vm->stats[bo_memtype].drm.shared += size; 335 + vm->stats[bo_memtype].drm.private -= size; 336 + } else { 337 + vm->stats[bo_memtype].drm.shared -= size; 338 + vm->stats[bo_memtype].drm.private += size; 339 + } 340 + } 341 + spin_unlock(&vm->status_lock); 342 + } 343 + 344 + /** 345 + * amdgpu_vm_bo_update_shared - callback when bo gets shared/unshared 346 + * @bo: amdgpu buffer object 347 + * 348 + * Update the per VM stats for all the vm if needed from private to shared or 349 + * vice versa. 350 + */ 351 + void amdgpu_vm_bo_update_shared(struct amdgpu_bo *bo) 352 + { 353 + struct amdgpu_vm_bo_base *base; 354 + 355 + for (base = bo->vm_bo; base; base = base->next) 356 + amdgpu_vm_update_shared(base); 357 + } 358 + 359 + /** 360 + * amdgpu_vm_update_stats_locked - helper to update normal memory stat 361 + * @base: base structure for tracking BO usage in a VM 362 + * @res: the ttm_resource to use for the purpose of accounting, may or may not 363 + * be bo->tbo.resource 364 + * @sign: if we should add (+1) or subtract (-1) from the stat 365 + * 366 + * Caller need to have the vm status_lock held. Useful for when multiple update 367 + * need to happen at the same time. 368 + */ 369 + static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base, 370 + struct ttm_resource *res, int sign) 371 + { 372 + struct amdgpu_vm *vm = base->vm; 373 + struct amdgpu_bo *bo = base->bo; 374 + int64_t size = sign * amdgpu_bo_size(bo); 375 + uint32_t bo_memtype = amdgpu_bo_mem_stats_placement(bo); 376 + 377 + /* For drm-total- and drm-shared-, BO are accounted by their preferred 378 + * placement, see also amdgpu_bo_mem_stats_placement. 379 + */ 380 + if (base->shared) 381 + vm->stats[bo_memtype].drm.shared += size; 382 + else 383 + vm->stats[bo_memtype].drm.private += size; 384 + 385 + if (res && res->mem_type < __AMDGPU_PL_NUM) { 386 + uint32_t res_memtype = res->mem_type; 387 + 388 + vm->stats[res_memtype].drm.resident += size; 389 + /* BO only count as purgeable if it is resident, 390 + * since otherwise there's nothing to purge. 391 + */ 392 + if (bo->flags & AMDGPU_GEM_CREATE_DISCARDABLE) 393 + vm->stats[res_memtype].drm.purgeable += size; 394 + if (!(bo->preferred_domains & amdgpu_mem_type_to_domain(res_memtype))) 395 + vm->stats[bo_memtype].evicted += size; 396 + } 397 + } 398 + 399 + /** 400 + * amdgpu_vm_update_stats - helper to update normal memory stat 401 + * @base: base structure for tracking BO usage in a VM 402 + * @res: the ttm_resource to use for the purpose of accounting, may or may not 403 + * be bo->tbo.resource 404 + * @sign: if we should add (+1) or subtract (-1) from the stat 405 + * 406 + * Updates the basic memory stat when bo is added/deleted/moved. 407 + */ 408 + void amdgpu_vm_update_stats(struct amdgpu_vm_bo_base *base, 409 + struct ttm_resource *res, int sign) 410 + { 411 + struct amdgpu_vm *vm = base->vm; 412 + 413 + spin_lock(&vm->status_lock); 414 + amdgpu_vm_update_stats_locked(base, res, sign); 415 + spin_unlock(&vm->status_lock); 416 + } 417 + 418 + /** 315 419 * amdgpu_vm_bo_base_init - Adds bo to the list of bos associated with the vm 316 420 * 317 421 * @base: base structure for tracking BO usage in a VM ··· 438 332 return; 439 333 base->next = bo->vm_bo; 440 334 bo->vm_bo = base; 335 + 336 + spin_lock(&vm->status_lock); 337 + base->shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base); 338 + amdgpu_vm_update_stats_locked(base, bo->tbo.resource, +1); 339 + spin_unlock(&vm->status_lock); 441 340 442 341 if (!amdgpu_vm_is_bo_always_valid(vm, bo)) 443 342 return; ··· 1194 1083 return r; 1195 1084 } 1196 1085 1197 - static void amdgpu_vm_bo_get_memory(struct amdgpu_bo_va *bo_va, 1198 - struct amdgpu_mem_stats *stats, 1199 - unsigned int size) 1200 - { 1201 - struct amdgpu_vm *vm = bo_va->base.vm; 1202 - struct amdgpu_bo *bo = bo_va->base.bo; 1203 - 1204 - if (!bo) 1205 - return; 1206 - 1207 - /* 1208 - * For now ignore BOs which are currently locked and potentially 1209 - * changing their location. 1210 - */ 1211 - if (!amdgpu_vm_is_bo_always_valid(vm, bo) && 1212 - !dma_resv_trylock(bo->tbo.base.resv)) 1213 - return; 1214 - 1215 - amdgpu_bo_get_memory(bo, stats, size); 1216 - if (!amdgpu_vm_is_bo_always_valid(vm, bo)) 1217 - dma_resv_unlock(bo->tbo.base.resv); 1218 - } 1219 - 1220 1086 void amdgpu_vm_get_memory(struct amdgpu_vm *vm, 1221 - struct amdgpu_mem_stats *stats, 1222 - unsigned int size) 1087 + struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]) 1223 1088 { 1224 - struct amdgpu_bo_va *bo_va, *tmp; 1225 - 1226 1089 spin_lock(&vm->status_lock); 1227 - list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) 1228 - amdgpu_vm_bo_get_memory(bo_va, stats, size); 1229 - 1230 - list_for_each_entry_safe(bo_va, tmp, &vm->evicted, base.vm_status) 1231 - amdgpu_vm_bo_get_memory(bo_va, stats, size); 1232 - 1233 - list_for_each_entry_safe(bo_va, tmp, &vm->relocated, base.vm_status) 1234 - amdgpu_vm_bo_get_memory(bo_va, stats, size); 1235 - 1236 - list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) 1237 - amdgpu_vm_bo_get_memory(bo_va, stats, size); 1238 - 1239 - list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) 1240 - amdgpu_vm_bo_get_memory(bo_va, stats, size); 1241 - 1242 - list_for_each_entry_safe(bo_va, tmp, &vm->done, base.vm_status) 1243 - amdgpu_vm_bo_get_memory(bo_va, stats, size); 1090 + memcpy(stats, vm->stats, sizeof(*stats) * __AMDGPU_PL_NUM); 1244 1091 spin_unlock(&vm->status_lock); 1245 1092 } 1246 1093 ··· 2144 2075 if (*base != &bo_va->base) 2145 2076 continue; 2146 2077 2078 + amdgpu_vm_update_stats(*base, bo->tbo.resource, -1); 2147 2079 *base = bo_va->base.next; 2148 2080 break; 2149 2081 } ··· 2213 2143 /** 2214 2144 * amdgpu_vm_bo_invalidate - mark the bo as invalid 2215 2145 * 2216 - * @adev: amdgpu_device pointer 2217 2146 * @bo: amdgpu buffer object 2218 2147 * @evicted: is the BO evicted 2219 2148 * 2220 2149 * Mark @bo as invalid. 2221 2150 */ 2222 - void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, 2223 - struct amdgpu_bo *bo, bool evicted) 2151 + void amdgpu_vm_bo_invalidate(struct amdgpu_bo *bo, bool evicted) 2224 2152 { 2225 2153 struct amdgpu_vm_bo_base *bo_base; 2226 2154 ··· 2241 2173 else 2242 2174 amdgpu_vm_bo_invalidated(bo_base); 2243 2175 } 2176 + } 2177 + 2178 + /** 2179 + * amdgpu_vm_bo_move - handle BO move 2180 + * 2181 + * @bo: amdgpu buffer object 2182 + * @new_mem: the new placement of the BO move 2183 + * @evicted: is the BO evicted 2184 + * 2185 + * Update the memory stats for the new placement and mark @bo as invalid. 2186 + */ 2187 + void amdgpu_vm_bo_move(struct amdgpu_bo *bo, struct ttm_resource *new_mem, 2188 + bool evicted) 2189 + { 2190 + struct amdgpu_vm_bo_base *bo_base; 2191 + 2192 + for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) { 2193 + struct amdgpu_vm *vm = bo_base->vm; 2194 + 2195 + spin_lock(&vm->status_lock); 2196 + amdgpu_vm_update_stats_locked(bo_base, bo->tbo.resource, -1); 2197 + amdgpu_vm_update_stats_locked(bo_base, new_mem, +1); 2198 + spin_unlock(&vm->status_lock); 2199 + } 2200 + 2201 + amdgpu_vm_bo_invalidate(bo, evicted); 2244 2202 } 2245 2203 2246 2204 /** ··· 2688 2594 vm->is_compute_context = false; 2689 2595 } 2690 2596 2597 + static int amdgpu_vm_stats_is_zero(struct amdgpu_vm *vm) 2598 + { 2599 + for (int i = 0; i < __AMDGPU_PL_NUM; ++i) { 2600 + if (!(drm_memory_stats_is_zero(&vm->stats[i].drm) && 2601 + vm->stats[i].evicted == 0)) 2602 + return false; 2603 + } 2604 + return true; 2605 + } 2606 + 2691 2607 /** 2692 2608 * amdgpu_vm_fini - tear down a vm instance 2693 2609 * ··· 2721 2617 2722 2618 root = amdgpu_bo_ref(vm->root.bo); 2723 2619 amdgpu_bo_reserve(root, true); 2724 - amdgpu_vm_put_task_info(vm->task_info); 2725 2620 amdgpu_vm_set_pasid(adev, vm, 0); 2726 2621 dma_fence_wait(vm->last_unlocked, false); 2727 2622 dma_fence_put(vm->last_unlocked); ··· 2769 2666 } 2770 2667 2771 2668 ttm_lru_bulk_move_fini(&adev->mman.bdev, &vm->lru_bulk_move); 2669 + 2670 + if (!amdgpu_vm_stats_is_zero(vm)) { 2671 + struct amdgpu_task_info *ti = vm->task_info; 2672 + 2673 + dev_warn(adev->dev, 2674 + "VM memory stats for proc %s(%d) task %s(%d) is non-zero when fini\n", 2675 + ti->process_name, ti->pid, ti->task_name, ti->tgid); 2676 + } 2677 + 2678 + amdgpu_vm_put_task_info(vm->task_info); 2772 2679 } 2773 2680 2774 2681 /**
+17 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 35 35 #include "amdgpu_sync.h" 36 36 #include "amdgpu_ring.h" 37 37 #include "amdgpu_ids.h" 38 + #include "amdgpu_ttm.h" 38 39 39 40 struct drm_exec; 40 41 ··· 203 202 /* protected by bo being reserved */ 204 203 struct amdgpu_vm_bo_base *next; 205 204 206 - /* protected by spinlock */ 205 + /* protected by vm status_lock */ 207 206 struct list_head vm_status; 207 + 208 + /* if the bo is counted as shared in mem stats 209 + * protected by vm status_lock */ 210 + bool shared; 208 211 209 212 /* protected by the BO being reserved */ 210 213 bool moved; ··· 329 324 struct amdgpu_mem_stats { 330 325 struct drm_memory_stats drm; 331 326 332 - /* buffers that requested this placement */ 333 - uint64_t requested; 334 - /* buffers that requested this placement 335 - * but are currently evicted */ 327 + /* buffers that requested this placement but are currently evicted */ 336 328 uint64_t evicted; 337 329 }; 338 330 ··· 346 344 347 345 /* Lock to protect vm_bo add/del/move on all lists of vm */ 348 346 spinlock_t status_lock; 347 + 348 + /* Memory statistics for this vm, protected by status_lock */ 349 + struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]; 349 350 350 351 /* Per-VM and PT BOs who needs a validation */ 351 352 struct list_head evicted; ··· 529 524 struct amdgpu_bo_va *bo_va, 530 525 bool clear); 531 526 bool amdgpu_vm_evictable(struct amdgpu_bo *bo); 532 - void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, 533 - struct amdgpu_bo *bo, bool evicted); 527 + void amdgpu_vm_bo_invalidate(struct amdgpu_bo *bo, bool evicted); 528 + void amdgpu_vm_update_stats(struct amdgpu_vm_bo_base *base, 529 + struct ttm_resource *new_res, int sign); 530 + void amdgpu_vm_bo_update_shared(struct amdgpu_bo *bo); 531 + void amdgpu_vm_bo_move(struct amdgpu_bo *bo, struct ttm_resource *new_mem, 532 + bool evicted); 534 533 uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); 535 534 struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, 536 535 struct amdgpu_bo *bo); ··· 585 576 void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, 586 577 struct amdgpu_vm *vm); 587 578 void amdgpu_vm_get_memory(struct amdgpu_vm *vm, 588 - struct amdgpu_mem_stats *stats, 589 - unsigned int size); 579 + struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]); 590 580 591 581 int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm, 592 582 struct amdgpu_bo_vm *vmbo, bool immediate);
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
··· 537 537 if (!entry->bo) 538 538 return; 539 539 540 + amdgpu_vm_update_stats(entry, entry->bo->tbo.resource, -1); 540 541 entry->bo->vm_bo = NULL; 541 542 ttm_bo_set_bulk_move(&entry->bo->tbo, NULL); 542 543
+2 -1
drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
··· 204 204 } 205 205 206 206 static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component, 207 - struct device_node *endpoint) 207 + struct device_node *endpoint, 208 + void *data) 208 209 { 209 210 struct of_endpoint of_ep; 210 211 int ret;
+31 -45
drivers/gpu/drm/bridge/analogix/anx7625.c
··· 1952 1952 } 1953 1953 1954 1954 static int anx7625_hdmi_i2s_get_dai_id(struct snd_soc_component *component, 1955 - struct device_node *endpoint) 1955 + struct device_node *endpoint, 1956 + void *data) 1956 1957 { 1957 1958 struct of_endpoint of_ep; 1958 1959 int ret; ··· 2138 2137 2139 2138 mutex_unlock(&ctx->hdcp_wq_lock); 2140 2139 drm_modeset_unlock(&drm_dev->mode_config.connection_mutex); 2141 - } 2142 - 2143 - static int anx7625_connector_atomic_check(struct anx7625_data *ctx, 2144 - struct drm_connector_state *state) 2145 - { 2146 - struct device *dev = ctx->dev; 2147 - int cp; 2148 - 2149 - dev_dbg(dev, "hdcp state check\n"); 2150 - cp = state->content_protection; 2151 - 2152 - if (cp == ctx->hdcp_cp) 2153 - return 0; 2154 - 2155 - if (cp == DRM_MODE_CONTENT_PROTECTION_DESIRED) { 2156 - if (ctx->dp_en) { 2157 - dev_dbg(dev, "enable HDCP\n"); 2158 - anx7625_hdcp_enable(ctx); 2159 - 2160 - queue_delayed_work(ctx->hdcp_workqueue, 2161 - &ctx->hdcp_work, 2162 - msecs_to_jiffies(2000)); 2163 - } 2164 - } 2165 - 2166 - if (cp == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { 2167 - if (ctx->hdcp_cp != DRM_MODE_CONTENT_PROTECTION_ENABLED) { 2168 - dev_err(dev, "current CP is not ENABLED\n"); 2169 - return -EINVAL; 2170 - } 2171 - anx7625_hdcp_disable(ctx); 2172 - ctx->hdcp_cp = DRM_MODE_CONTENT_PROTECTION_UNDESIRED; 2173 - drm_hdcp_update_content_protection(ctx->connector, 2174 - ctx->hdcp_cp); 2175 - dev_dbg(dev, "update CP to UNDESIRE\n"); 2176 - } 2177 - 2178 - if (cp == DRM_MODE_CONTENT_PROTECTION_ENABLED) { 2179 - dev_err(dev, "Userspace illegal set to PROTECTION ENABLE\n"); 2180 - return -EINVAL; 2181 - } 2182 - 2183 - return 0; 2184 2140 } 2185 2141 2186 2142 static int anx7625_bridge_attach(struct drm_bridge *bridge, ··· 2376 2418 anx7625_bridge_mode_fixup(bridge, &crtc_state->mode, 2377 2419 &crtc_state->adjusted_mode); 2378 2420 2379 - return anx7625_connector_atomic_check(ctx, conn_state); 2421 + return 0; 2380 2422 } 2381 2423 2382 2424 static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge, ··· 2385 2427 struct anx7625_data *ctx = bridge_to_anx7625(bridge); 2386 2428 struct device *dev = ctx->dev; 2387 2429 struct drm_connector *connector; 2430 + struct drm_connector_state *conn_state; 2388 2431 2389 2432 dev_dbg(dev, "drm atomic enable\n"); 2390 2433 ··· 2400 2441 _anx7625_hpd_polling(ctx, 5000 * 100); 2401 2442 2402 2443 anx7625_dp_start(ctx); 2444 + 2445 + conn_state = drm_atomic_get_new_connector_state(state->base.state, connector); 2446 + 2447 + if (WARN_ON(!conn_state)) 2448 + return; 2449 + 2450 + if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { 2451 + if (ctx->dp_en) { 2452 + dev_dbg(dev, "enable HDCP\n"); 2453 + anx7625_hdcp_enable(ctx); 2454 + 2455 + queue_delayed_work(ctx->hdcp_workqueue, 2456 + &ctx->hdcp_work, 2457 + msecs_to_jiffies(2000)); 2458 + } 2459 + } 2403 2460 } 2404 2461 2405 2462 static void anx7625_bridge_atomic_disable(struct drm_bridge *bridge, ··· 2425 2450 struct device *dev = ctx->dev; 2426 2451 2427 2452 dev_dbg(dev, "drm atomic disable\n"); 2453 + 2454 + flush_workqueue(ctx->hdcp_workqueue); 2455 + 2456 + if (ctx->connector && 2457 + ctx->hdcp_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED) { 2458 + anx7625_hdcp_disable(ctx); 2459 + ctx->hdcp_cp = DRM_MODE_CONTENT_PROTECTION_DESIRED; 2460 + drm_hdcp_update_content_protection(ctx->connector, 2461 + ctx->hdcp_cp); 2462 + dev_dbg(dev, "update CP to DESIRE\n"); 2463 + } 2428 2464 2429 2465 ctx->connector = NULL; 2430 2466 anx7625_dp_stop(ctx);
-10
drivers/gpu/drm/bridge/ite-it6263.c
··· 569 569 return 0; 570 570 } 571 571 572 - static int it6263_bridge_atomic_check(struct drm_bridge *bridge, 573 - struct drm_bridge_state *bridge_state, 574 - struct drm_crtc_state *crtc_state, 575 - struct drm_connector_state *conn_state) 576 - { 577 - return drm_atomic_helper_connector_hdmi_check(conn_state->connector, 578 - conn_state->state); 579 - } 580 - 581 572 static void 582 573 it6263_bridge_atomic_disable(struct drm_bridge *bridge, 583 574 struct drm_bridge_state *old_bridge_state) ··· 803 812 .mode_valid = it6263_bridge_mode_valid, 804 813 .atomic_disable = it6263_bridge_atomic_disable, 805 814 .atomic_enable = it6263_bridge_atomic_enable, 806 - .atomic_check = it6263_bridge_atomic_check, 807 815 .detect = it6263_bridge_detect, 808 816 .edid_read = it6263_bridge_edid_read, 809 817 .atomic_get_input_bus_fmts = it6263_bridge_atomic_get_input_bus_fmts,
+278 -57
drivers/gpu/drm/bridge/ite-it6505.c
··· 19 19 #include <linux/regulator/consumer.h> 20 20 #include <linux/types.h> 21 21 #include <linux/wait.h> 22 + #include <linux/bitfield.h> 22 23 23 24 #include <crypto/hash.h> 24 25 ··· 127 126 #define REG_AUX_OUT_DATA0 0x27 128 127 129 128 #define REG_AUX_CMD_REQ 0x2B 129 + #define M_AUX_REQ_CMD 0x0F 130 130 #define AUX_BUSY BIT(5) 131 131 132 132 #define REG_AUX_DATA_0_7 0x2C ··· 268 266 #define REG_SSC_CTRL1 0x189 269 267 #define REG_SSC_CTRL2 0x18A 270 268 269 + #define REG_AUX_USER_CTRL 0x190 270 + #define EN_USER_AUX BIT(0) 271 + #define USER_AUX_DONE BIT(1) 272 + #define AUX_EVENT BIT(4) 273 + 274 + #define REG_AUX_USER_DATA_REC 0x191 275 + #define M_AUX_IN_REC 0xF0 276 + #define M_AUX_OUT_REC 0x0F 277 + 278 + #define REG_AUX_USER_REPLY 0x19A 279 + #define REG_AUX_USER_RXB(n) (n + 0x19B) 280 + 271 281 #define RBR DP_LINK_BW_1_62 272 282 #define HBR DP_LINK_BW_2_7 273 283 #define HBR2 DP_LINK_BW_5_4 ··· 310 296 #define MAX_LANE_COUNT 4 311 297 #define MAX_LINK_RATE HBR 312 298 #define AUTO_TRAIN_RETRY 3 313 - #define MAX_HDCP_DOWN_STREAM_COUNT 10 299 + #define MAX_HDCP_DOWN_STREAM_COUNT 127 314 300 #define MAX_CR_LEVEL 0x03 315 301 #define MAX_EQ_LEVEL 0x03 316 302 #define AUX_WAIT_TIMEOUT_MS 15 317 - #define AUX_FIFO_MAX_SIZE 32 303 + #define AUX_FIFO_MAX_SIZE 16 304 + #define AUX_I2C_MAX_SIZE 4 305 + #define AUX_I2C_DEFER_RETRY 4 318 306 #define PIXEL_CLK_DELAY 1 319 307 #define PIXEL_CLK_INVERSE 0 320 308 #define ADJUST_PHASE_THRESHOLD 80000 ··· 339 323 enum aux_cmd_type { 340 324 CMD_AUX_NATIVE_READ = 0x0, 341 325 CMD_AUX_NATIVE_WRITE = 0x5, 326 + CMD_AUX_GI2C_ADR = 0x08, 327 + CMD_AUX_GI2C_READ = 0x09, 328 + CMD_AUX_GI2C_WRITE = 0x0A, 342 329 CMD_AUX_I2C_EDID_READ = 0xB, 330 + CMD_AUX_I2C_READ = 0x0D, 331 + CMD_AUX_I2C_WRITE = 0x0C, 332 + 333 + /* KSV read with AUX FIFO extend from CMD_AUX_NATIVE_READ*/ 334 + CMD_AUX_GET_KSV_LIST = 0x10, 343 335 }; 344 336 345 337 enum aux_cmd_reply { ··· 989 965 it6505_set_bits(it6505, REG_AUX_CTRL, AUX_USER_MODE, AUX_USER_MODE); 990 966 991 967 aux_op_start: 992 - if (cmd == CMD_AUX_I2C_EDID_READ) { 968 + /* HW AUX FIFO supports only EDID and DCPD KSV FIFO area */ 969 + if (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) { 993 970 /* AUX EDID FIFO has max length of AUX_FIFO_MAX_SIZE bytes. */ 994 971 size = min_t(size_t, size, AUX_FIFO_MAX_SIZE); 995 972 /* Enable AUX FIFO read back and clear FIFO */ ··· 1021 996 size); 1022 997 1023 998 /* Aux Fire */ 1024 - it6505_write(it6505, REG_AUX_CMD_REQ, cmd); 999 + it6505_write(it6505, REG_AUX_CMD_REQ, FIELD_GET(M_AUX_REQ_CMD, cmd)); 1025 1000 1026 1001 ret = it6505_aux_wait(it6505); 1027 1002 if (ret < 0) ··· 1055 1030 goto aux_op_start; 1056 1031 } 1057 1032 1058 - if (cmd == CMD_AUX_I2C_EDID_READ) { 1033 + if (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) { 1059 1034 for (i = 0; i < size; i++) { 1060 1035 ret = it6505_read(it6505, REG_AUX_DATA_FIFO); 1061 1036 if (ret < 0) ··· 1080 1055 ret = i; 1081 1056 1082 1057 aux_op_err: 1083 - if (cmd == CMD_AUX_I2C_EDID_READ) { 1058 + if (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) { 1084 1059 /* clear AUX FIFO */ 1085 1060 it6505_set_bits(it6505, REG_AUX_CTRL, 1086 1061 AUX_EN_FIFO_READ | CLR_EDID_FIFO, ··· 1101 1076 size_t size, enum aux_cmd_reply *reply) 1102 1077 { 1103 1078 int i, ret_size, ret = 0, request_size; 1079 + int fifo_max_size = (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) ? 1080 + AUX_FIFO_MAX_SIZE : 4; 1104 1081 1105 1082 mutex_lock(&it6505->aux_lock); 1106 - for (i = 0; i < size; i += 4) { 1107 - request_size = min((int)size - i, 4); 1083 + i = 0; 1084 + do { 1085 + request_size = min_t(int, (int)size - i, fifo_max_size); 1086 + 1108 1087 ret_size = it6505_aux_operation(it6505, cmd, address + i, 1109 1088 buffer + i, request_size, 1110 1089 reply); ··· 1117 1088 goto aux_op_err; 1118 1089 } 1119 1090 1091 + i += request_size; 1120 1092 ret += ret_size; 1121 - } 1093 + } while (i < size); 1122 1094 1123 1095 aux_op_err: 1124 1096 mutex_unlock(&it6505->aux_lock); 1125 1097 return ret; 1098 + } 1099 + 1100 + static bool it6505_aux_i2c_reply_defer(u8 reply) 1101 + { 1102 + if (reply == DP_AUX_NATIVE_REPLY_DEFER || reply == DP_AUX_I2C_REPLY_DEFER) 1103 + return true; 1104 + return false; 1105 + } 1106 + 1107 + static bool it6505_aux_i2c_reply_nack(u8 reply) 1108 + { 1109 + if (reply == DP_AUX_NATIVE_REPLY_NACK || reply == DP_AUX_I2C_REPLY_NACK) 1110 + return true; 1111 + return false; 1112 + } 1113 + 1114 + static int it6505_aux_i2c_wait(struct it6505 *it6505, u8 *reply) 1115 + { 1116 + int err = 0; 1117 + unsigned long timeout; 1118 + struct device *dev = it6505->dev; 1119 + 1120 + timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1; 1121 + 1122 + do { 1123 + if (it6505_read(it6505, REG_AUX_USER_CTRL) & AUX_EVENT) 1124 + break; 1125 + if (time_after(jiffies, timeout)) { 1126 + dev_err(dev, "Timed out waiting AUX I2C, BUSY = %X\n", 1127 + it6505_aux_op_finished(it6505)); 1128 + err = -ETIMEDOUT; 1129 + goto end_aux_i2c_wait; 1130 + } 1131 + usleep_range(300, 800); 1132 + } while (!it6505_aux_op_finished(it6505)); 1133 + 1134 + *reply = it6505_read(it6505, REG_AUX_USER_REPLY) >> 4; 1135 + 1136 + if (*reply == 0) 1137 + goto end_aux_i2c_wait; 1138 + 1139 + if (it6505_aux_i2c_reply_defer(*reply)) 1140 + err = -EBUSY; 1141 + else if (it6505_aux_i2c_reply_nack(*reply)) 1142 + err = -ENXIO; 1143 + 1144 + end_aux_i2c_wait: 1145 + it6505_set_bits(it6505, REG_AUX_USER_CTRL, USER_AUX_DONE, USER_AUX_DONE); 1146 + return err; 1147 + } 1148 + 1149 + static int it6505_aux_i2c_readb(struct it6505 *it6505, u8 *buf, size_t size, u8 *reply) 1150 + { 1151 + int ret, i; 1152 + int retry; 1153 + 1154 + for (retry = 0; retry < AUX_I2C_DEFER_RETRY; retry++) { 1155 + it6505_write(it6505, REG_AUX_CMD_REQ, CMD_AUX_GI2C_READ); 1156 + 1157 + ret = it6505_aux_i2c_wait(it6505, reply); 1158 + if (it6505_aux_i2c_reply_defer(*reply)) 1159 + continue; 1160 + if (ret >= 0) 1161 + break; 1162 + } 1163 + 1164 + for (i = 0; i < size; i++) 1165 + buf[i] = it6505_read(it6505, REG_AUX_USER_RXB(0 + i)); 1166 + 1167 + return size; 1168 + } 1169 + 1170 + static int it6505_aux_i2c_writeb(struct it6505 *it6505, u8 *buf, size_t size, u8 *reply) 1171 + { 1172 + int i, ret; 1173 + int retry; 1174 + 1175 + for (i = 0; i < size; i++) 1176 + it6505_write(it6505, REG_AUX_OUT_DATA0 + i, buf[i]); 1177 + 1178 + for (retry = 0; retry < AUX_I2C_DEFER_RETRY; retry++) { 1179 + it6505_write(it6505, REG_AUX_CMD_REQ, CMD_AUX_GI2C_WRITE); 1180 + 1181 + ret = it6505_aux_i2c_wait(it6505, reply); 1182 + if (it6505_aux_i2c_reply_defer(*reply)) 1183 + continue; 1184 + if (ret >= 0) 1185 + break; 1186 + } 1187 + return size; 1188 + } 1189 + 1190 + static ssize_t it6505_aux_i2c_operation(struct it6505 *it6505, 1191 + struct drm_dp_aux_msg *msg) 1192 + { 1193 + int ret; 1194 + ssize_t request_size, data_cnt = 0; 1195 + u8 *buffer = msg->buffer; 1196 + 1197 + /* set AUX user mode */ 1198 + it6505_set_bits(it6505, REG_AUX_CTRL, 1199 + AUX_USER_MODE | AUX_NO_SEGMENT_WR, AUX_USER_MODE); 1200 + it6505_set_bits(it6505, REG_AUX_USER_CTRL, EN_USER_AUX, EN_USER_AUX); 1201 + /* clear AUX FIFO */ 1202 + it6505_set_bits(it6505, REG_AUX_CTRL, 1203 + AUX_EN_FIFO_READ | CLR_EDID_FIFO, 1204 + AUX_EN_FIFO_READ | CLR_EDID_FIFO); 1205 + 1206 + it6505_set_bits(it6505, REG_AUX_CTRL, 1207 + AUX_EN_FIFO_READ | CLR_EDID_FIFO, 0x00); 1208 + 1209 + it6505_write(it6505, REG_AUX_ADR_0_7, 0x00); 1210 + it6505_write(it6505, REG_AUX_ADR_8_15, msg->address << 1); 1211 + 1212 + if (msg->size == 0) { 1213 + /* IIC Start/STOP dummy write */ 1214 + it6505_write(it6505, REG_AUX_ADR_16_19, msg->request); 1215 + it6505_write(it6505, REG_AUX_CMD_REQ, CMD_AUX_GI2C_ADR); 1216 + ret = it6505_aux_i2c_wait(it6505, &msg->reply); 1217 + goto end_aux_i2c_transfer; 1218 + } 1219 + 1220 + /* IIC data transfer */ 1221 + data_cnt = 0; 1222 + do { 1223 + request_size = min_t(ssize_t, msg->size - data_cnt, AUX_I2C_MAX_SIZE); 1224 + it6505_write(it6505, REG_AUX_ADR_16_19, 1225 + msg->request | ((request_size - 1) << 4)); 1226 + if ((msg->request & DP_AUX_I2C_READ) == DP_AUX_I2C_READ) 1227 + ret = it6505_aux_i2c_readb(it6505, &buffer[data_cnt], 1228 + request_size, &msg->reply); 1229 + else 1230 + ret = it6505_aux_i2c_writeb(it6505, &buffer[data_cnt], 1231 + request_size, &msg->reply); 1232 + 1233 + if (ret < 0) 1234 + goto end_aux_i2c_transfer; 1235 + 1236 + data_cnt += request_size; 1237 + } while (data_cnt < msg->size); 1238 + ret = data_cnt; 1239 + end_aux_i2c_transfer: 1240 + 1241 + it6505_set_bits(it6505, REG_AUX_USER_CTRL, EN_USER_AUX, 0); 1242 + it6505_set_bits(it6505, REG_AUX_CTRL, AUX_USER_MODE, 0); 1243 + return ret; 1244 + } 1245 + 1246 + static ssize_t it6505_aux_i2c_transfer(struct drm_dp_aux *aux, 1247 + struct drm_dp_aux_msg *msg) 1248 + { 1249 + struct it6505 *it6505 = container_of(aux, struct it6505, aux); 1250 + 1251 + guard(mutex)(&it6505->aux_lock); 1252 + return it6505_aux_i2c_operation(it6505, msg); 1126 1253 } 1127 1254 1128 1255 static ssize_t it6505_aux_transfer(struct drm_dp_aux *aux, ··· 1290 1105 int ret; 1291 1106 enum aux_cmd_reply reply; 1292 1107 1293 - /* IT6505 doesn't support arbitrary I2C read / write. */ 1294 1108 if (is_i2c) 1295 - return -EINVAL; 1109 + return it6505_aux_i2c_transfer(aux, msg); 1296 1110 1297 1111 switch (msg->request) { 1298 1112 case DP_AUX_NATIVE_READ: ··· 1360 1176 } 1361 1177 1362 1178 return 0; 1179 + } 1180 + 1181 + static int it6505_get_ksvlist(struct it6505 *it6505, u8 *buf, size_t len) 1182 + { 1183 + struct device *dev = it6505->dev; 1184 + enum aux_cmd_reply reply; 1185 + int request_size, ret; 1186 + int i = 0; 1187 + 1188 + do { 1189 + request_size = min_t(int, (int)len - i, 15); 1190 + 1191 + ret = it6505_aux_do_transfer(it6505, CMD_AUX_GET_KSV_LIST, 1192 + DP_AUX_HDCP_KSV_FIFO, 1193 + buf + i, request_size, &reply); 1194 + 1195 + DRM_DEV_DEBUG_DRIVER(dev, "request_size = %d, ret =%d", request_size, ret); 1196 + if (ret < 0) 1197 + return ret; 1198 + 1199 + i += request_size; 1200 + } while (i < len); 1201 + 1202 + DRM_DEV_DEBUG_DRIVER(dev, "ksv read cnt = %d down_stream_cnt=%d ", i, i / 5); 1203 + 1204 + for (i = 0 ; i < len; i += 5) { 1205 + DRM_DEV_DEBUG_DRIVER(dev, "ksv[%d] = %02X%02X%02X%02X%02X", 1206 + i / 5, buf[i], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4]); 1207 + } 1208 + 1209 + return len; 1363 1210 } 1364 1211 1365 1212 static void it6505_variable_config(struct it6505 *it6505) ··· 2174 1959 { 2175 1960 struct device *dev = it6505->dev; 2176 1961 u8 binfo[2]; 2177 - int down_stream_count, i, err, msg_count = 0; 1962 + int down_stream_count, err, msg_count = 0; 2178 1963 2179 1964 err = it6505_get_dpcd(it6505, DP_AUX_HDCP_BINFO, binfo, 2180 1965 ARRAY_SIZE(binfo)); ··· 2199 1984 down_stream_count); 2200 1985 return 0; 2201 1986 } 1987 + err = it6505_get_ksvlist(it6505, sha1_input, down_stream_count * 5); 1988 + if (err < 0) 1989 + return err; 2202 1990 2203 - for (i = 0; i < down_stream_count; i++) { 2204 - err = it6505_get_dpcd(it6505, DP_AUX_HDCP_KSV_FIFO + 2205 - (i % 3) * DRM_HDCP_KSV_LEN, 2206 - sha1_input + msg_count, 2207 - DRM_HDCP_KSV_LEN); 2208 - 2209 - if (err < 0) 2210 - return err; 2211 - 2212 - msg_count += 5; 2213 - } 1991 + msg_count += down_stream_count * 5; 2214 1992 2215 1993 it6505->hdcp_down_stream_count = down_stream_count; 2216 1994 sha1_input[msg_count++] = binfo[0]; ··· 2231 2023 { 2232 2024 struct device *dev = it6505->dev; 2233 2025 u8 av[5][4], bv[5][4]; 2234 - int i, err; 2026 + int i, err, retry; 2235 2027 2236 2028 i = it6505_setup_sha1_input(it6505, it6505->sha1_input); 2237 2029 if (i <= 0) { ··· 2240 2032 } 2241 2033 2242 2034 it6505_sha1_digest(it6505, it6505->sha1_input, i, (u8 *)av); 2035 + /*1B-05 V' must retry 3 times */ 2036 + for (retry = 0; retry < 3; retry++) { 2037 + err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv, 2038 + sizeof(bv)); 2243 2039 2244 - err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv, 2245 - sizeof(bv)); 2040 + if (err < 0) { 2041 + dev_err(dev, "Read V' value Fail %d", retry); 2042 + continue; 2043 + } 2246 2044 2247 - if (err < 0) { 2248 - dev_err(dev, "Read V' value Fail"); 2249 - return false; 2045 + for (i = 0; i < 5; i++) { 2046 + if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] || 2047 + av[i][1] != av[i][2] || bv[i][0] != av[i][3]) 2048 + break; 2049 + 2050 + DRM_DEV_DEBUG_DRIVER(dev, "V' all match!! %d, %d", retry, i); 2051 + return true; 2052 + } 2250 2053 } 2251 2054 2252 - for (i = 0; i < 5; i++) 2253 - if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] || 2254 - bv[i][1] != av[i][2] || bv[i][0] != av[i][3]) 2255 - return false; 2256 - 2257 - DRM_DEV_DEBUG_DRIVER(dev, "V' all match!!"); 2258 - return true; 2055 + DRM_DEV_DEBUG_DRIVER(dev, "V' NOT match!! %d", retry); 2056 + return false; 2259 2057 } 2260 2058 2261 2059 static void it6505_hdcp_wait_ksv_list(struct work_struct *work) ··· 2269 2055 struct it6505 *it6505 = container_of(work, struct it6505, 2270 2056 hdcp_wait_ksv_list); 2271 2057 struct device *dev = it6505->dev; 2272 - unsigned int timeout = 5000; 2273 - u8 bstatus = 0; 2058 + u8 bstatus; 2274 2059 bool ksv_list_check; 2060 + /* 1B-04 wait ksv list for 5s */ 2061 + unsigned long timeout = jiffies + 2062 + msecs_to_jiffies(5000) + 1; 2275 2063 2276 - timeout /= 20; 2277 - while (timeout > 0) { 2064 + for (;;) { 2278 2065 if (!it6505_get_sink_hpd_status(it6505)) 2279 2066 return; 2280 2067 ··· 2284 2069 if (bstatus & DP_BSTATUS_READY) 2285 2070 break; 2286 2071 2287 - msleep(20); 2288 - timeout--; 2289 - } 2072 + if (time_after(jiffies, timeout)) { 2073 + DRM_DEV_DEBUG_DRIVER(dev, "KSV list wait timeout"); 2074 + goto timeout; 2075 + } 2290 2076 2291 - if (timeout == 0) { 2292 - DRM_DEV_DEBUG_DRIVER(dev, "timeout and ksv list wait failed"); 2293 - goto timeout; 2077 + msleep(20); 2294 2078 } 2295 2079 2296 2080 ksv_list_check = it6505_hdcp_part2_ksvlist_check(it6505); 2297 2081 DRM_DEV_DEBUG_DRIVER(dev, "ksv list ready, ksv list check %s", 2298 2082 ksv_list_check ? "pass" : "fail"); 2299 - if (ksv_list_check) { 2300 - it6505_set_bits(it6505, REG_HDCP_TRIGGER, 2301 - HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE); 2083 + 2084 + if (ksv_list_check) 2302 2085 return; 2303 - } 2086 + 2304 2087 timeout: 2305 - it6505_set_bits(it6505, REG_HDCP_TRIGGER, 2306 - HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL, 2307 - HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL); 2088 + it6505_start_hdcp(it6505); 2308 2089 } 2309 2090 2310 2091 static void it6505_hdcp_work(struct work_struct *work) ··· 2523 2312 DRM_DEV_DEBUG_DRIVER(dev, "dp_irq_vector = 0x%02x", dp_irq_vector); 2524 2313 2525 2314 if (dp_irq_vector & DP_CP_IRQ) { 2526 - it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ, 2527 - HDCP_TRIGGER_CPIRQ); 2528 - 2529 2315 bstatus = it6505_dpcd_read(it6505, DP_AUX_HDCP_BSTATUS); 2530 2316 if (bstatus < 0) 2531 2317 return bstatus; 2532 2318 2533 2319 DRM_DEV_DEBUG_DRIVER(dev, "Bstatus = 0x%02x", bstatus); 2320 + 2321 + /*Check BSTATUS when recive CP_IRQ */ 2322 + if (bstatus & DP_BSTATUS_R0_PRIME_READY && 2323 + it6505->hdcp_status == HDCP_AUTH_GOING) 2324 + it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ, 2325 + HDCP_TRIGGER_CPIRQ); 2326 + else if (bstatus & (DP_BSTATUS_REAUTH_REQ | DP_BSTATUS_LINK_FAILURE) && 2327 + it6505->hdcp_status == HDCP_AUTH_DONE) 2328 + it6505_start_hdcp(it6505); 2534 2329 } 2535 2330 2536 2331 ret = drm_dp_dpcd_read_link_status(&it6505->aux, link_status); ··· 2673 2456 { 2674 2457 struct device *dev = it6505->dev; 2675 2458 2676 - DRM_DEV_DEBUG_DRIVER(dev, "HDCP event Interrupt"); 2459 + DRM_DEV_DEBUG_DRIVER(dev, "HDCP repeater R0 event Interrupt"); 2460 + /* 1B01 HDCP encription should start when R0 is ready*/ 2461 + it6505_set_bits(it6505, REG_HDCP_TRIGGER, 2462 + HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE); 2463 + 2677 2464 schedule_work(&it6505->hdcp_wait_ksv_list); 2678 2465 } 2679 2466
+2 -2
drivers/gpu/drm/bridge/ite-it66121.c
··· 1466 1466 .audio_shutdown = it66121_audio_shutdown, 1467 1467 .mute_stream = it66121_audio_mute, 1468 1468 .get_eld = it66121_audio_get_eld, 1469 - .no_capture_mute = 1, 1470 1469 }; 1471 1470 1472 1471 static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev) ··· 1475 1476 .i2s = 1, /* Only i2s support for now */ 1476 1477 .spdif = 0, 1477 1478 .max_i2s_channels = 8, 1479 + .no_capture_mute = 1, 1478 1480 }; 1479 1481 1480 1482 dev_dbg(dev, "%s\n", __func__); 1481 1483 1482 - if (!of_property_read_bool(dev->of_node, "#sound-dai-cells")) { 1484 + if (!of_property_present(dev->of_node, "#sound-dai-cells")) { 1483 1485 dev_info(dev, "No \"#sound-dai-cells\", no audio\n"); 1484 1486 return 0; 1485 1487 }
+68 -111
drivers/gpu/drm/bridge/lontium-lt9611.c
··· 45 45 struct device_node *dsi1_node; 46 46 struct mipi_dsi_device *dsi0; 47 47 struct mipi_dsi_device *dsi1; 48 - struct platform_device *audio_pdev; 49 48 50 49 bool ac_mode; 51 50 ··· 766 767 return MODE_OK; 767 768 } 768 769 769 - static int lt9611_bridge_atomic_check(struct drm_bridge *bridge, 770 - struct drm_bridge_state *bridge_state, 771 - struct drm_crtc_state *crtc_state, 772 - struct drm_connector_state *conn_state) 773 - { 774 - return drm_atomic_helper_connector_hdmi_check(conn_state->connector, 775 - conn_state->state); 776 - } 777 - 778 770 static void lt9611_bridge_atomic_pre_enable(struct drm_bridge *bridge, 779 771 struct drm_bridge_state *old_bridge_state) 780 772 { ··· 854 864 unsigned int mask; 855 865 856 866 switch (type) { 867 + case HDMI_INFOFRAME_TYPE_AUDIO: 868 + mask = LT9611_INFOFRAME_AUDIO; 869 + break; 870 + 857 871 case HDMI_INFOFRAME_TYPE_AVI: 858 872 mask = LT9611_INFOFRAME_AVI; 859 873 break; ··· 891 897 int i; 892 898 893 899 switch (type) { 900 + case HDMI_INFOFRAME_TYPE_AUDIO: 901 + mask = LT9611_INFOFRAME_AUDIO; 902 + addr = 0x84b2; 903 + break; 904 + 894 905 case HDMI_INFOFRAME_TYPE_AVI: 895 906 mask = LT9611_INFOFRAME_AVI; 896 907 addr = 0x8440; ··· 939 940 return MODE_OK; 940 941 } 941 942 943 + static int lt9611_hdmi_audio_startup(struct drm_connector *connector, 944 + struct drm_bridge *bridge) 945 + { 946 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 947 + 948 + regmap_write(lt9611->regmap, 0x82d6, 0x8c); 949 + regmap_write(lt9611->regmap, 0x82d7, 0x04); 950 + 951 + regmap_write(lt9611->regmap, 0x8406, 0x08); 952 + regmap_write(lt9611->regmap, 0x8407, 0x10); 953 + 954 + regmap_write(lt9611->regmap, 0x8434, 0xd5); 955 + 956 + return 0; 957 + } 958 + 959 + static int lt9611_hdmi_audio_prepare(struct drm_connector *connector, 960 + struct drm_bridge *bridge, 961 + struct hdmi_codec_daifmt *fmt, 962 + struct hdmi_codec_params *hparms) 963 + { 964 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 965 + 966 + if (hparms->sample_rate == 48000) 967 + regmap_write(lt9611->regmap, 0x840f, 0x2b); 968 + else if (hparms->sample_rate == 96000) 969 + regmap_write(lt9611->regmap, 0x840f, 0xab); 970 + else 971 + return -EINVAL; 972 + 973 + regmap_write(lt9611->regmap, 0x8435, 0x00); 974 + regmap_write(lt9611->regmap, 0x8436, 0x18); 975 + regmap_write(lt9611->regmap, 0x8437, 0x00); 976 + 977 + return drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector, 978 + &hparms->cea); 979 + } 980 + 981 + static void lt9611_hdmi_audio_shutdown(struct drm_connector *connector, 982 + struct drm_bridge *bridge) 983 + { 984 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 985 + 986 + drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector); 987 + 988 + regmap_write(lt9611->regmap, 0x8406, 0x00); 989 + regmap_write(lt9611->regmap, 0x8407, 0x00); 990 + } 991 + 942 992 static const struct drm_bridge_funcs lt9611_bridge_funcs = { 943 993 .attach = lt9611_bridge_attach, 944 994 .mode_valid = lt9611_bridge_mode_valid, ··· 995 947 .edid_read = lt9611_bridge_edid_read, 996 948 .hpd_enable = lt9611_bridge_hpd_enable, 997 949 998 - .atomic_check = lt9611_bridge_atomic_check, 999 950 .atomic_pre_enable = lt9611_bridge_atomic_pre_enable, 1000 951 .atomic_enable = lt9611_bridge_atomic_enable, 1001 952 .atomic_disable = lt9611_bridge_atomic_disable, ··· 1007 960 .hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid, 1008 961 .hdmi_write_infoframe = lt9611_hdmi_write_infoframe, 1009 962 .hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe, 963 + 964 + .hdmi_audio_startup = lt9611_hdmi_audio_startup, 965 + .hdmi_audio_prepare = lt9611_hdmi_audio_prepare, 966 + .hdmi_audio_shutdown = lt9611_hdmi_audio_shutdown, 1010 967 }; 1011 968 1012 969 static int lt9611_parse_dt(struct device *dev, ··· 1062 1011 dev_info(lt9611->dev, "LT9611 revision: 0x%x\n", rev); 1063 1012 1064 1013 return ret; 1065 - } 1066 - 1067 - static int lt9611_hdmi_hw_params(struct device *dev, void *data, 1068 - struct hdmi_codec_daifmt *fmt, 1069 - struct hdmi_codec_params *hparms) 1070 - { 1071 - struct lt9611 *lt9611 = data; 1072 - 1073 - if (hparms->sample_rate == 48000) 1074 - regmap_write(lt9611->regmap, 0x840f, 0x2b); 1075 - else if (hparms->sample_rate == 96000) 1076 - regmap_write(lt9611->regmap, 0x840f, 0xab); 1077 - else 1078 - return -EINVAL; 1079 - 1080 - regmap_write(lt9611->regmap, 0x8435, 0x00); 1081 - regmap_write(lt9611->regmap, 0x8436, 0x18); 1082 - regmap_write(lt9611->regmap, 0x8437, 0x00); 1083 - 1084 - return 0; 1085 - } 1086 - 1087 - static int lt9611_audio_startup(struct device *dev, void *data) 1088 - { 1089 - struct lt9611 *lt9611 = data; 1090 - 1091 - regmap_write(lt9611->regmap, 0x82d6, 0x8c); 1092 - regmap_write(lt9611->regmap, 0x82d7, 0x04); 1093 - 1094 - regmap_write(lt9611->regmap, 0x8406, 0x08); 1095 - regmap_write(lt9611->regmap, 0x8407, 0x10); 1096 - 1097 - regmap_write(lt9611->regmap, 0x8434, 0xd5); 1098 - 1099 - return 0; 1100 - } 1101 - 1102 - static void lt9611_audio_shutdown(struct device *dev, void *data) 1103 - { 1104 - struct lt9611 *lt9611 = data; 1105 - 1106 - regmap_write(lt9611->regmap, 0x8406, 0x00); 1107 - regmap_write(lt9611->regmap, 0x8407, 0x00); 1108 - } 1109 - 1110 - static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component, 1111 - struct device_node *endpoint) 1112 - { 1113 - struct of_endpoint of_ep; 1114 - int ret; 1115 - 1116 - ret = of_graph_parse_endpoint(endpoint, &of_ep); 1117 - if (ret < 0) 1118 - return ret; 1119 - 1120 - /* 1121 - * HDMI sound should be located as reg = <2> 1122 - * Then, it is sound port 0 1123 - */ 1124 - if (of_ep.port == 2) 1125 - return 0; 1126 - 1127 - return -EINVAL; 1128 - } 1129 - 1130 - static const struct hdmi_codec_ops lt9611_codec_ops = { 1131 - .hw_params = lt9611_hdmi_hw_params, 1132 - .audio_shutdown = lt9611_audio_shutdown, 1133 - .audio_startup = lt9611_audio_startup, 1134 - .get_dai_id = lt9611_hdmi_i2s_get_dai_id, 1135 - }; 1136 - 1137 - static struct hdmi_codec_pdata codec_data = { 1138 - .ops = &lt9611_codec_ops, 1139 - .max_i2s_channels = 8, 1140 - .i2s = 1, 1141 - }; 1142 - 1143 - static int lt9611_audio_init(struct device *dev, struct lt9611 *lt9611) 1144 - { 1145 - codec_data.data = lt9611; 1146 - lt9611->audio_pdev = 1147 - platform_device_register_data(dev, HDMI_CODEC_DRV_NAME, 1148 - PLATFORM_DEVID_AUTO, 1149 - &codec_data, sizeof(codec_data)); 1150 - 1151 - return PTR_ERR_OR_ZERO(lt9611->audio_pdev); 1152 - } 1153 - 1154 - static void lt9611_audio_exit(struct lt9611 *lt9611) 1155 - { 1156 - if (lt9611->audio_pdev) { 1157 - platform_device_unregister(lt9611->audio_pdev); 1158 - lt9611->audio_pdev = NULL; 1159 - } 1160 1014 } 1161 1015 1162 1016 static int lt9611_probe(struct i2c_client *client) ··· 1127 1171 1128 1172 i2c_set_clientdata(client, lt9611); 1129 1173 1174 + /* Disable Audio InfoFrame, enabled by default */ 1175 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0); 1176 + 1130 1177 lt9611->bridge.funcs = &lt9611_bridge_funcs; 1131 1178 lt9611->bridge.of_node = client->dev.of_node; 1132 1179 lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | ··· 1138 1179 lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 1139 1180 lt9611->bridge.vendor = "Lontium"; 1140 1181 lt9611->bridge.product = "LT9611"; 1182 + lt9611->bridge.hdmi_audio_dev = dev; 1183 + lt9611->bridge.hdmi_audio_max_i2s_playback_channels = 8; 1184 + lt9611->bridge.hdmi_audio_dai_port = 2; 1141 1185 1142 1186 drm_bridge_add(&lt9611->bridge); 1143 1187 ··· 1162 1200 1163 1201 lt9611_enable_hpd_interrupts(lt9611); 1164 1202 1165 - ret = lt9611_audio_init(dev, lt9611); 1166 - if (ret) 1167 - goto err_remove_bridge; 1168 - 1169 1203 return 0; 1170 1204 1171 1205 err_remove_bridge: ··· 1182 1224 struct lt9611 *lt9611 = i2c_get_clientdata(client); 1183 1225 1184 1226 disable_irq(client->irq); 1185 - lt9611_audio_exit(lt9611); 1186 1227 drm_bridge_remove(&lt9611->bridge); 1187 1228 1188 1229 regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);
+2 -1
drivers/gpu/drm/bridge/lontium-lt9611uxc.c
··· 522 522 } 523 523 524 524 static int lt9611uxc_hdmi_i2s_get_dai_id(struct snd_soc_component *component, 525 - struct device_node *endpoint) 525 + struct device_node *endpoint, 526 + void *data) 526 527 { 527 528 struct of_endpoint of_ep; 528 529 int ret;
+4 -3
drivers/gpu/drm/bridge/sii902x.c
··· 815 815 } 816 816 817 817 static int sii902x_audio_get_dai_id(struct snd_soc_component *component, 818 - struct device_node *endpoint) 818 + struct device_node *endpoint, 819 + void *data) 819 820 { 820 821 struct of_endpoint of_ep; 821 822 int ret; ··· 841 840 .mute_stream = sii902x_audio_mute, 842 841 .get_eld = sii902x_audio_get_eld, 843 842 .get_dai_id = sii902x_audio_get_dai_id, 844 - .no_capture_mute = 1, 845 843 }; 846 844 847 845 static int sii902x_audio_codec_init(struct sii902x *sii902x, ··· 863 863 .i2s = 1, /* Only i2s support for now. */ 864 864 .spdif = 0, 865 865 .max_i2s_channels = 0, 866 + .no_capture_mute = 1, 866 867 }; 867 868 u8 lanes[4]; 868 869 int num_lanes, i; 869 870 870 - if (!of_property_read_bool(dev->of_node, "#sound-dai-cells")) { 871 + if (!of_property_present(dev->of_node, "#sound-dai-cells")) { 871 872 dev_dbg(dev, "%s: No \"#sound-dai-cells\", no audio\n", 872 873 __func__); 873 874 return 0;
+2 -1
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
··· 148 148 } 149 149 150 150 static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component, 151 - struct device_node *endpoint) 151 + struct device_node *endpoint, 152 + void *data) 152 153 { 153 154 struct of_endpoint of_ep; 154 155 int ret;
-17
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
··· 361 361 return 0; 362 362 } 363 363 364 - static int dw_hdmi_qp_bridge_atomic_check(struct drm_bridge *bridge, 365 - struct drm_bridge_state *bridge_state, 366 - struct drm_crtc_state *crtc_state, 367 - struct drm_connector_state *conn_state) 368 - { 369 - struct dw_hdmi_qp *hdmi = bridge->driver_private; 370 - int ret; 371 - 372 - ret = drm_atomic_helper_connector_hdmi_check(conn_state->connector, 373 - conn_state->state); 374 - if (ret) 375 - dev_dbg(hdmi->dev, "%s failed: %d\n", __func__, ret); 376 - 377 - return ret; 378 - } 379 - 380 364 static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, 381 365 struct drm_bridge_state *old_state) 382 366 { ··· 487 503 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 488 504 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 489 505 .atomic_reset = drm_atomic_helper_bridge_reset, 490 - .atomic_check = dw_hdmi_qp_bridge_atomic_check, 491 506 .atomic_enable = dw_hdmi_qp_bridge_atomic_enable, 492 507 .atomic_disable = dw_hdmi_qp_bridge_atomic_disable, 493 508 .detect = dw_hdmi_qp_bridge_detect,
+8
drivers/gpu/drm/display/Kconfig
··· 15 15 16 16 config DRM_BRIDGE_CONNECTOR 17 17 bool 18 + select DRM_DISPLAY_HDMI_AUDIO_HELPER 18 19 select DRM_DISPLAY_HDMI_STATE_HELPER 19 20 help 20 21 DRM connector implementation terminating DRM bridge chains. ··· 76 75 help 77 76 DRM display helpers for HDCP. 78 77 78 + config DRM_DISPLAY_HDMI_AUDIO_HELPER 79 + bool 80 + help 81 + DRM display helpers for HDMI Audio functionality (generic HDMI Codec 82 + implementation). 83 + 79 84 config DRM_DISPLAY_HDMI_HELPER 80 85 bool 81 86 help ··· 89 82 90 83 config DRM_DISPLAY_HDMI_STATE_HELPER 91 84 bool 85 + select DRM_DISPLAY_HDMI_AUDIO_HELPER 92 86 select DRM_DISPLAY_HDMI_HELPER 93 87 help 94 88 DRM KMS state helpers for HDMI.
+2
drivers/gpu/drm/display/Makefile
··· 14 14 drm_display_helper-$(CONFIG_DRM_DISPLAY_DSC_HELPER) += \ 15 15 drm_dsc_helper.o 16 16 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o 17 + drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_AUDIO_HELPER) += \ 18 + drm_hdmi_audio_helper.o 17 19 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \ 18 20 drm_hdmi_helper.o \ 19 21 drm_scdc_helper.o
+147 -4
drivers/gpu/drm/display/drm_bridge_connector.c
··· 17 17 #include <drm/drm_edid.h> 18 18 #include <drm/drm_managed.h> 19 19 #include <drm/drm_modeset_helper_vtables.h> 20 + #include <drm/drm_print.h> 20 21 #include <drm/drm_probe_helper.h> 22 + #include <drm/display/drm_hdmi_audio_helper.h> 21 23 #include <drm/display/drm_hdmi_helper.h> 22 24 #include <drm/display/drm_hdmi_state_helper.h> 23 25 ··· 182 180 struct drm_bridge_connector *bridge_connector = 183 181 to_drm_bridge_connector(connector); 184 182 struct drm_bridge *detect = bridge_connector->bridge_detect; 183 + struct drm_bridge *hdmi = bridge_connector->bridge_hdmi; 185 184 enum drm_connector_status status; 186 185 187 186 if (detect) { 188 187 status = detect->funcs->detect(detect); 188 + 189 + if (hdmi) 190 + drm_atomic_helper_connector_hdmi_hotplug(connector, status); 189 191 190 192 drm_bridge_connector_hpd_notify(connector, status); 191 193 } else { ··· 207 201 } 208 202 209 203 return status; 204 + } 205 + 206 + static void drm_bridge_connector_force(struct drm_connector *connector) 207 + { 208 + struct drm_bridge_connector *bridge_connector = 209 + to_drm_bridge_connector(connector); 210 + struct drm_bridge *hdmi = bridge_connector->bridge_hdmi; 211 + 212 + if (hdmi) 213 + drm_atomic_helper_connector_hdmi_force(connector); 210 214 } 211 215 212 216 static void drm_bridge_connector_debugfs_init(struct drm_connector *connector, ··· 247 231 static const struct drm_connector_funcs drm_bridge_connector_funcs = { 248 232 .reset = drm_bridge_connector_reset, 249 233 .detect = drm_bridge_connector_detect, 234 + .force = drm_bridge_connector_force, 250 235 .fill_modes = drm_helper_probe_single_connector_modes, 251 236 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 252 237 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, ··· 294 277 struct drm_bridge *bridge; 295 278 296 279 /* 280 + * If there is a HDMI bridge, EDID has been updated as a part of 281 + * the .detect(). Just update the modes here. 282 + */ 283 + bridge = bridge_connector->bridge_hdmi; 284 + if (bridge) 285 + return drm_edid_connector_add_modes(connector); 286 + 287 + /* 297 288 * If display exposes EDID, then we parse that in the normal way to 298 289 * build table of supported modes. 299 290 */ ··· 338 313 return MODE_OK; 339 314 } 340 315 316 + static int drm_bridge_connector_atomic_check(struct drm_connector *connector, 317 + struct drm_atomic_state *state) 318 + { 319 + struct drm_bridge_connector *bridge_connector = 320 + to_drm_bridge_connector(connector); 321 + 322 + if (bridge_connector->bridge_hdmi) 323 + return drm_atomic_helper_connector_hdmi_check(connector, state); 324 + 325 + return 0; 326 + } 327 + 341 328 static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs = { 342 329 .get_modes = drm_bridge_connector_get_modes, 343 330 .mode_valid = drm_bridge_connector_mode_valid, 344 331 .enable_hpd = drm_bridge_connector_enable_hpd, 345 332 .disable_hpd = drm_bridge_connector_disable_hpd, 333 + .atomic_check = drm_bridge_connector_atomic_check, 346 334 }; 347 335 348 336 static enum drm_mode_status ··· 406 368 return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len); 407 369 } 408 370 371 + static const struct drm_edid * 372 + drm_bridge_connector_read_edid(struct drm_connector *connector) 373 + { 374 + struct drm_bridge_connector *bridge_connector = 375 + to_drm_bridge_connector(connector); 376 + struct drm_bridge *bridge; 377 + 378 + bridge = bridge_connector->bridge_edid; 379 + if (!bridge) 380 + return NULL; 381 + 382 + return drm_bridge_edid_read(bridge, connector); 383 + } 384 + 409 385 static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = { 410 386 .tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid, 411 387 .clear_infoframe = drm_bridge_connector_clear_infoframe, 412 388 .write_infoframe = drm_bridge_connector_write_infoframe, 389 + .read_edid = drm_bridge_connector_read_edid, 390 + }; 391 + 392 + static int drm_bridge_connector_audio_startup(struct drm_connector *connector) 393 + { 394 + struct drm_bridge_connector *bridge_connector = 395 + to_drm_bridge_connector(connector); 396 + struct drm_bridge *bridge; 397 + 398 + bridge = bridge_connector->bridge_hdmi; 399 + if (!bridge) 400 + return -EINVAL; 401 + 402 + if (!bridge->funcs->hdmi_audio_startup) 403 + return 0; 404 + 405 + return bridge->funcs->hdmi_audio_startup(connector, bridge); 406 + } 407 + 408 + static int drm_bridge_connector_audio_prepare(struct drm_connector *connector, 409 + struct hdmi_codec_daifmt *fmt, 410 + struct hdmi_codec_params *hparms) 411 + { 412 + struct drm_bridge_connector *bridge_connector = 413 + to_drm_bridge_connector(connector); 414 + struct drm_bridge *bridge; 415 + 416 + bridge = bridge_connector->bridge_hdmi; 417 + if (!bridge) 418 + return -EINVAL; 419 + 420 + return bridge->funcs->hdmi_audio_prepare(connector, bridge, fmt, hparms); 421 + } 422 + 423 + static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector) 424 + { 425 + struct drm_bridge_connector *bridge_connector = 426 + to_drm_bridge_connector(connector); 427 + struct drm_bridge *bridge; 428 + 429 + bridge = bridge_connector->bridge_hdmi; 430 + if (!bridge) 431 + return; 432 + 433 + bridge->funcs->hdmi_audio_shutdown(connector, bridge); 434 + } 435 + 436 + static int drm_bridge_connector_audio_mute_stream(struct drm_connector *connector, 437 + bool enable, int direction) 438 + { 439 + struct drm_bridge_connector *bridge_connector = 440 + to_drm_bridge_connector(connector); 441 + struct drm_bridge *bridge; 442 + 443 + bridge = bridge_connector->bridge_hdmi; 444 + if (!bridge) 445 + return -EINVAL; 446 + 447 + if (bridge->funcs->hdmi_audio_mute_stream) 448 + return bridge->funcs->hdmi_audio_mute_stream(connector, bridge, 449 + enable, direction); 450 + else 451 + return -ENOTSUPP; 452 + } 453 + 454 + static const struct drm_connector_hdmi_audio_funcs drm_bridge_connector_hdmi_audio_funcs = { 455 + .startup = drm_bridge_connector_audio_startup, 456 + .prepare = drm_bridge_connector_audio_prepare, 457 + .shutdown = drm_bridge_connector_audio_shutdown, 458 + .mute_stream = drm_bridge_connector_audio_mute_stream, 413 459 }; 414 460 415 461 /* ----------------------------------------------------------------------------- ··· 595 473 if (connector_type == DRM_MODE_CONNECTOR_Unknown) 596 474 return ERR_PTR(-EINVAL); 597 475 598 - if (bridge_connector->bridge_hdmi) 476 + if (bridge_connector->bridge_hdmi) { 477 + bridge = bridge_connector->bridge_hdmi; 478 + 599 479 ret = drmm_connector_hdmi_init(drm, connector, 600 480 bridge_connector->bridge_hdmi->vendor, 601 481 bridge_connector->bridge_hdmi->product, ··· 606 482 connector_type, ddc, 607 483 supported_formats, 608 484 max_bpc); 609 - else 485 + if (ret) 486 + return ERR_PTR(ret); 487 + 488 + if (bridge->hdmi_audio_max_i2s_playback_channels || 489 + bridge->hdmi_audio_spdif_playback) { 490 + if (!bridge->funcs->hdmi_audio_prepare || 491 + !bridge->funcs->hdmi_audio_shutdown) 492 + return ERR_PTR(-EINVAL); 493 + 494 + ret = drm_connector_hdmi_audio_init(connector, 495 + bridge->hdmi_audio_dev, 496 + &drm_bridge_connector_hdmi_audio_funcs, 497 + bridge->hdmi_audio_max_i2s_playback_channels, 498 + bridge->hdmi_audio_spdif_playback, 499 + bridge->hdmi_audio_dai_port); 500 + if (ret) 501 + return ERR_PTR(ret); 502 + } 503 + } else { 610 504 ret = drmm_connector_init(drm, connector, 611 505 &drm_bridge_connector_funcs, 612 506 connector_type, ddc); 613 - if (ret) 614 - return ERR_PTR(ret); 507 + if (ret) 508 + return ERR_PTR(ret); 509 + } 615 510 616 511 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); 617 512
+190
drivers/gpu/drm/display/drm_hdmi_audio_helper.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright (c) 2024 Linaro Ltd 4 + */ 5 + 6 + #include <linux/mutex.h> 7 + #include <linux/of_graph.h> 8 + #include <linux/platform_device.h> 9 + 10 + #include <drm/drm_connector.h> 11 + #include <drm/drm_device.h> 12 + #include <drm/display/drm_hdmi_audio_helper.h> 13 + 14 + #include <sound/hdmi-codec.h> 15 + 16 + static int drm_connector_hdmi_audio_startup(struct device *dev, void *data) 17 + { 18 + struct drm_connector *connector = data; 19 + const struct drm_connector_hdmi_audio_funcs *funcs = 20 + connector->hdmi_audio.funcs; 21 + 22 + if (funcs->startup) 23 + return funcs->startup(connector); 24 + 25 + return 0; 26 + } 27 + 28 + static int drm_connector_hdmi_audio_prepare(struct device *dev, void *data, 29 + struct hdmi_codec_daifmt *fmt, 30 + struct hdmi_codec_params *hparms) 31 + { 32 + struct drm_connector *connector = data; 33 + const struct drm_connector_hdmi_audio_funcs *funcs = 34 + connector->hdmi_audio.funcs; 35 + 36 + return funcs->prepare(connector, fmt, hparms); 37 + } 38 + 39 + static void drm_connector_hdmi_audio_shutdown(struct device *dev, void *data) 40 + { 41 + struct drm_connector *connector = data; 42 + const struct drm_connector_hdmi_audio_funcs *funcs = 43 + connector->hdmi_audio.funcs; 44 + 45 + return funcs->shutdown(connector); 46 + } 47 + 48 + static int drm_connector_hdmi_audio_mute_stream(struct device *dev, void *data, 49 + bool enable, int direction) 50 + { 51 + struct drm_connector *connector = data; 52 + const struct drm_connector_hdmi_audio_funcs *funcs = 53 + connector->hdmi_audio.funcs; 54 + 55 + if (funcs->mute_stream) 56 + return funcs->mute_stream(connector, enable, direction); 57 + 58 + return -ENOTSUPP; 59 + } 60 + 61 + static int drm_connector_hdmi_audio_get_dai_id(struct snd_soc_component *comment, 62 + struct device_node *endpoint, 63 + void *data) 64 + { 65 + struct drm_connector *connector = data; 66 + struct of_endpoint of_ep; 67 + int ret; 68 + 69 + if (connector->hdmi_audio.dai_port < 0) 70 + return -ENOTSUPP; 71 + 72 + ret = of_graph_parse_endpoint(endpoint, &of_ep); 73 + if (ret < 0) 74 + return ret; 75 + 76 + if (of_ep.port == connector->hdmi_audio.dai_port) 77 + return 0; 78 + 79 + return -EINVAL; 80 + } 81 + 82 + static int drm_connector_hdmi_audio_get_eld(struct device *dev, void *data, 83 + uint8_t *buf, size_t len) 84 + { 85 + struct drm_connector *connector = data; 86 + 87 + mutex_lock(&connector->eld_mutex); 88 + memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); 89 + mutex_unlock(&connector->eld_mutex); 90 + 91 + return 0; 92 + } 93 + 94 + static int drm_connector_hdmi_audio_hook_plugged_cb(struct device *dev, 95 + void *data, 96 + hdmi_codec_plugged_cb fn, 97 + struct device *codec_dev) 98 + { 99 + struct drm_connector *connector = data; 100 + 101 + mutex_lock(&connector->hdmi_audio.lock); 102 + 103 + connector->hdmi_audio.plugged_cb = fn; 104 + connector->hdmi_audio.plugged_cb_dev = codec_dev; 105 + 106 + fn(codec_dev, connector->hdmi_audio.last_state); 107 + 108 + mutex_unlock(&connector->hdmi_audio.lock); 109 + 110 + return 0; 111 + } 112 + 113 + void drm_connector_hdmi_audio_plugged_notify(struct drm_connector *connector, 114 + bool plugged) 115 + { 116 + mutex_lock(&connector->hdmi_audio.lock); 117 + 118 + connector->hdmi_audio.last_state = plugged; 119 + 120 + if (connector->hdmi_audio.plugged_cb && 121 + connector->hdmi_audio.plugged_cb_dev) 122 + connector->hdmi_audio.plugged_cb(connector->hdmi_audio.plugged_cb_dev, 123 + connector->hdmi_audio.last_state); 124 + 125 + mutex_unlock(&connector->hdmi_audio.lock); 126 + } 127 + EXPORT_SYMBOL(drm_connector_hdmi_audio_plugged_notify); 128 + 129 + static const struct hdmi_codec_ops drm_connector_hdmi_audio_ops = { 130 + .audio_startup = drm_connector_hdmi_audio_startup, 131 + .prepare = drm_connector_hdmi_audio_prepare, 132 + .audio_shutdown = drm_connector_hdmi_audio_shutdown, 133 + .mute_stream = drm_connector_hdmi_audio_mute_stream, 134 + .get_eld = drm_connector_hdmi_audio_get_eld, 135 + .get_dai_id = drm_connector_hdmi_audio_get_dai_id, 136 + .hook_plugged_cb = drm_connector_hdmi_audio_hook_plugged_cb, 137 + }; 138 + 139 + /** 140 + * drm_connector_hdmi_audio_init - Initialize HDMI Codec device for the DRM connector 141 + * @connector: A pointer to the connector to allocate codec for 142 + * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec 143 + * @funcs: callbacks for this HDMI Codec 144 + * @max_i2s_playback_channels: maximum number of playback I2S channels 145 + * @spdif_playback: set if HDMI codec has S/PDIF playback port 146 + * @dai_port: sound DAI port, -1 if it is not enabled 147 + * 148 + * Create a HDMI codec device to be used with the specified connector. 149 + * 150 + * Returns: 151 + * Zero on success, error code on failure. 152 + */ 153 + int drm_connector_hdmi_audio_init(struct drm_connector *connector, 154 + struct device *hdmi_codec_dev, 155 + const struct drm_connector_hdmi_audio_funcs *funcs, 156 + unsigned int max_i2s_playback_channels, 157 + bool spdif_playback, 158 + int dai_port) 159 + { 160 + struct hdmi_codec_pdata codec_pdata = { 161 + .ops = &drm_connector_hdmi_audio_ops, 162 + .max_i2s_channels = max_i2s_playback_channels, 163 + .i2s = !!max_i2s_playback_channels, 164 + .spdif = spdif_playback, 165 + .no_i2s_capture = true, 166 + .no_spdif_capture = true, 167 + .data = connector, 168 + }; 169 + struct platform_device *pdev; 170 + 171 + if (!funcs || 172 + !funcs->prepare || 173 + !funcs->shutdown) 174 + return -EINVAL; 175 + 176 + connector->hdmi_audio.funcs = funcs; 177 + connector->hdmi_audio.dai_port = dai_port; 178 + 179 + pdev = platform_device_register_data(hdmi_codec_dev, 180 + HDMI_CODEC_DRV_NAME, 181 + PLATFORM_DEVID_AUTO, 182 + &codec_pdata, sizeof(codec_pdata)); 183 + if (IS_ERR(pdev)) 184 + return PTR_ERR(pdev); 185 + 186 + connector->hdmi_audio.codec_pdev = pdev; 187 + 188 + return 0; 189 + } 190 + EXPORT_SYMBOL(drm_connector_hdmi_audio_init);
+57
drivers/gpu/drm/display/drm_hdmi_state_helper.c
··· 5 5 #include <drm/drm_edid.h> 6 6 #include <drm/drm_print.h> 7 7 8 + #include <drm/display/drm_hdmi_audio_helper.h> 8 9 #include <drm/display/drm_hdmi_helper.h> 9 10 #include <drm/display/drm_hdmi_state_helper.h> 10 11 ··· 778 777 return ret; 779 778 } 780 779 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe); 780 + 781 + static void 782 + drm_atomic_helper_connector_hdmi_update(struct drm_connector *connector, 783 + enum drm_connector_status status) 784 + { 785 + const struct drm_edid *drm_edid; 786 + 787 + if (status == connector_status_disconnected) { 788 + // TODO: also handle CEC and scramber, HDMI sink disconnected. 789 + drm_connector_hdmi_audio_plugged_notify(connector, false); 790 + } 791 + 792 + if (connector->hdmi.funcs->read_edid) 793 + drm_edid = connector->hdmi.funcs->read_edid(connector); 794 + else 795 + drm_edid = drm_edid_read(connector); 796 + 797 + drm_edid_connector_update(connector, drm_edid); 798 + 799 + drm_edid_free(drm_edid); 800 + 801 + if (status == connector_status_connected) { 802 + // TODO: also handle CEC and scramber, HDMI sink is now connected. 803 + drm_connector_hdmi_audio_plugged_notify(connector, true); 804 + } 805 + } 806 + 807 + /** 808 + * drm_atomic_helper_connector_hdmi_hotplug - Handle the hotplug event for the HDMI connector 809 + * @connector: A pointer to the HDMI connector 810 + * @status: Connection status 811 + * 812 + * This function should be called as a part of the .detect() / .detect_ctx() 813 + * callbacks, updating the HDMI-specific connector's data. 814 + */ 815 + void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector, 816 + enum drm_connector_status status) 817 + { 818 + drm_atomic_helper_connector_hdmi_update(connector, status); 819 + } 820 + EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug); 821 + 822 + /** 823 + * drm_atomic_helper_connector_hdmi_force - HDMI Connector implementation of the force callback 824 + * @connector: A pointer to the HDMI connector 825 + * 826 + * This function implements the .force() callback for the HDMI connectors. It 827 + * can either be used directly as the callback or should be called from within 828 + * the .force() callback implementation to maintain the HDMI-specific 829 + * connector's data. 830 + */ 831 + void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector) 832 + { 833 + drm_atomic_helper_connector_hdmi_update(connector, connector->status); 834 + } 835 + EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_force);
+5
drivers/gpu/drm/drm_connector.c
··· 33 33 #include <drm/drm_sysfs.h> 34 34 #include <drm/drm_utils.h> 35 35 36 + #include <linux/platform_device.h> 36 37 #include <linux/property.h> 37 38 #include <linux/uaccess.h> 38 39 ··· 282 281 mutex_init(&connector->eld_mutex); 283 282 mutex_init(&connector->edid_override_mutex); 284 283 mutex_init(&connector->hdmi.infoframes.lock); 284 + mutex_init(&connector->hdmi_audio.lock); 285 285 connector->edid_blob_ptr = NULL; 286 286 connector->epoch_counter = 0; 287 287 connector->tile_blob_ptr = NULL; ··· 716 714 DRM_CONNECTOR_REGISTERED)) 717 715 drm_connector_unregister(connector); 718 716 717 + platform_device_unregister(connector->hdmi_audio.codec_pdev); 718 + 719 719 if (connector->privacy_screen) { 720 720 drm_privacy_screen_put(connector->privacy_screen); 721 721 connector->privacy_screen = NULL; ··· 754 750 connector->funcs->atomic_destroy_state(connector, 755 751 connector->state); 756 752 753 + mutex_destroy(&connector->hdmi_audio.lock); 757 754 mutex_destroy(&connector->hdmi.infoframes.lock); 758 755 mutex_destroy(&connector->mutex); 759 756
+17 -6
drivers/gpu/drm/drm_file.c
··· 845 845 drm_printf(p, "drm-%s-%s:\t%llu%s\n", stat, region, sz, units[u]); 846 846 } 847 847 848 + int drm_memory_stats_is_zero(const struct drm_memory_stats *stats) 849 + { 850 + return (stats->shared == 0 && 851 + stats->private == 0 && 852 + stats->resident == 0 && 853 + stats->purgeable == 0 && 854 + stats->active == 0); 855 + } 856 + EXPORT_SYMBOL(drm_memory_stats_is_zero); 857 + 848 858 /** 849 859 * drm_print_memory_stats - A helper to print memory stats 850 860 * @p: The printer to print output to ··· 870 860 { 871 861 print_size(p, "total", region, stats->private + stats->shared); 872 862 print_size(p, "shared", region, stats->shared); 873 - print_size(p, "active", region, stats->active); 863 + 864 + if (supported_status & DRM_GEM_OBJECT_ACTIVE) 865 + print_size(p, "active", region, stats->active); 874 866 875 867 if (supported_status & DRM_GEM_OBJECT_RESIDENT) 876 868 print_size(p, "resident", region, stats->resident); ··· 905 893 906 894 if (obj->funcs && obj->funcs->status) { 907 895 s = obj->funcs->status(obj); 908 - supported_status = DRM_GEM_OBJECT_RESIDENT | 909 - DRM_GEM_OBJECT_PURGEABLE; 896 + supported_status |= s; 910 897 } 911 898 912 - if (drm_gem_object_is_shared_for_memory_stats(obj)) { 899 + if (drm_gem_object_is_shared_for_memory_stats(obj)) 913 900 status.shared += obj->size; 914 - } else { 901 + else 915 902 status.private += obj->size; 916 - } 917 903 918 904 if (s & DRM_GEM_OBJECT_RESIDENT) { 919 905 status.resident += add_size; ··· 924 914 925 915 if (!dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(true))) { 926 916 status.active += add_size; 917 + supported_status |= DRM_GEM_OBJECT_ACTIVE; 927 918 928 919 /* If still active, don't count as purgeable: */ 929 920 s &= ~DRM_GEM_OBJECT_PURGEABLE;
+1 -1
drivers/gpu/drm/drm_panel.c
··· 414 414 * don't bother trying to parse it here. We just need to know if the 415 415 * property is there. 416 416 */ 417 - return of_property_read_bool(dev->of_node, "panel"); 417 + return of_property_present(dev->of_node, "panel"); 418 418 } 419 419 EXPORT_SYMBOL(drm_is_panel_follower); 420 420
+1 -1
drivers/gpu/drm/exynos/exynos_hdmi.c
··· 1660 1660 .audio_shutdown = hdmi_audio_shutdown, 1661 1661 .mute_stream = hdmi_audio_mute, 1662 1662 .get_eld = hdmi_audio_get_eld, 1663 - .no_capture_mute = 1, 1664 1663 }; 1665 1664 1666 1665 static int hdmi_register_audio_device(struct hdmi_context *hdata) ··· 1668 1669 .ops = &audio_codec_ops, 1669 1670 .max_i2s_channels = 6, 1670 1671 .i2s = 1, 1672 + .no_capture_mute = 1, 1671 1673 }; 1672 1674 1673 1675 hdata->audio.pdev = platform_device_register_data(
+2 -1
drivers/gpu/drm/hisilicon/hibmc/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_i2c.o 2 + hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_i2c.o \ 3 + dp/dp_aux.o dp/dp_link.o dp/dp_hw.o hibmc_drm_dp.o 3 4 4 5 obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
+164
drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/io.h> 5 + #include <linux/iopoll.h> 6 + #include <linux/minmax.h> 7 + #include <drm/drm_device.h> 8 + #include <drm/drm_print.h> 9 + #include "dp_comm.h" 10 + #include "dp_reg.h" 11 + 12 + #define HIBMC_AUX_CMD_REQ_LEN GENMASK(7, 4) 13 + #define HIBMC_AUX_CMD_ADDR GENMASK(27, 8) 14 + #define HIBMC_AUX_CMD_I2C_ADDR_ONLY BIT(28) 15 + #define HIBMC_BYTES_IN_U32 4 16 + #define HIBMC_AUX_I2C_WRITE_SUCCESS 0x1 17 + #define HIBMC_DP_MIN_PULSE_NUM 0x9 18 + #define BITS_IN_U8 8 19 + 20 + static inline void hibmc_dp_aux_reset(struct hibmc_dp_dev *dp) 21 + { 22 + hibmc_dp_reg_write_field(dp, HIBMC_DP_DPTX_RST_CTRL, HIBMC_DP_CFG_AUX_RST_N, 0x0); 23 + usleep_range(10, 15); 24 + hibmc_dp_reg_write_field(dp, HIBMC_DP_DPTX_RST_CTRL, HIBMC_DP_CFG_AUX_RST_N, 0x1); 25 + } 26 + 27 + static void hibmc_dp_aux_read_data(struct hibmc_dp_dev *dp, u8 *buf, u8 size) 28 + { 29 + u32 reg_num; 30 + u32 value; 31 + u32 num; 32 + u8 i, j; 33 + 34 + reg_num = DIV_ROUND_UP(size, HIBMC_BYTES_IN_U32); 35 + for (i = 0; i < reg_num; i++) { 36 + /* number of bytes read from a single register */ 37 + num = min(size - i * HIBMC_BYTES_IN_U32, HIBMC_BYTES_IN_U32); 38 + value = readl(dp->base + HIBMC_DP_AUX_RD_DATA0 + i * HIBMC_BYTES_IN_U32); 39 + /* convert the 32-bit value of the register to the buffer. */ 40 + for (j = 0; j < num; j++) 41 + buf[i * HIBMC_BYTES_IN_U32 + j] = value >> (j * BITS_IN_U8); 42 + } 43 + } 44 + 45 + static void hibmc_dp_aux_write_data(struct hibmc_dp_dev *dp, u8 *buf, u8 size) 46 + { 47 + u32 reg_num; 48 + u32 value; 49 + u32 num; 50 + u8 i, j; 51 + 52 + reg_num = DIV_ROUND_UP(size, HIBMC_BYTES_IN_U32); 53 + for (i = 0; i < reg_num; i++) { 54 + /* number of bytes written to a single register */ 55 + num = min_t(u8, size - i * HIBMC_BYTES_IN_U32, HIBMC_BYTES_IN_U32); 56 + value = 0; 57 + /* obtain the 32-bit value written to a single register. */ 58 + for (j = 0; j < num; j++) 59 + value |= buf[i * HIBMC_BYTES_IN_U32 + j] << (j * BITS_IN_U8); 60 + /* writing data to a single register */ 61 + writel(value, dp->base + HIBMC_DP_AUX_WR_DATA0 + i * HIBMC_BYTES_IN_U32); 62 + } 63 + } 64 + 65 + static u32 hibmc_dp_aux_build_cmd(const struct drm_dp_aux_msg *msg) 66 + { 67 + u32 aux_cmd = msg->request; 68 + 69 + if (msg->size) 70 + aux_cmd |= FIELD_PREP(HIBMC_AUX_CMD_REQ_LEN, (msg->size - 1)); 71 + else 72 + aux_cmd |= FIELD_PREP(HIBMC_AUX_CMD_I2C_ADDR_ONLY, 1); 73 + 74 + aux_cmd |= FIELD_PREP(HIBMC_AUX_CMD_ADDR, msg->address); 75 + 76 + return aux_cmd; 77 + } 78 + 79 + /* ret >= 0, ret is size; ret < 0, ret is err code */ 80 + static int hibmc_dp_aux_parse_xfer(struct hibmc_dp_dev *dp, struct drm_dp_aux_msg *msg) 81 + { 82 + u32 buf_data_cnt; 83 + u32 aux_status; 84 + 85 + aux_status = readl(dp->base + HIBMC_DP_AUX_STATUS); 86 + msg->reply = FIELD_GET(HIBMC_DP_CFG_AUX_STATUS, aux_status); 87 + 88 + if (aux_status & HIBMC_DP_CFG_AUX_TIMEOUT) 89 + return -ETIMEDOUT; 90 + 91 + /* only address */ 92 + if (!msg->size) 93 + return 0; 94 + 95 + if (msg->reply != DP_AUX_NATIVE_REPLY_ACK) 96 + return -EIO; 97 + 98 + buf_data_cnt = FIELD_GET(HIBMC_DP_CFG_AUX_READY_DATA_BYTE, aux_status); 99 + 100 + switch (msg->request) { 101 + case DP_AUX_NATIVE_WRITE: 102 + return msg->size; 103 + case DP_AUX_I2C_WRITE | DP_AUX_I2C_MOT: 104 + if (buf_data_cnt == HIBMC_AUX_I2C_WRITE_SUCCESS) 105 + return msg->size; 106 + else 107 + return FIELD_GET(HIBMC_DP_CFG_AUX, aux_status); 108 + case DP_AUX_NATIVE_READ: 109 + case DP_AUX_I2C_READ | DP_AUX_I2C_MOT: 110 + buf_data_cnt--; 111 + if (buf_data_cnt != msg->size) { 112 + /* only the successful part of data is read */ 113 + return -EBUSY; 114 + } 115 + 116 + /* all data is successfully read */ 117 + hibmc_dp_aux_read_data(dp, msg->buffer, msg->size); 118 + return msg->size; 119 + default: 120 + return -EINVAL; 121 + } 122 + } 123 + 124 + /* ret >= 0 ,ret is size; ret < 0, ret is err code */ 125 + static ssize_t hibmc_dp_aux_xfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) 126 + { 127 + struct hibmc_dp_dev *dp = container_of(aux, struct hibmc_dp_dev, aux); 128 + u32 aux_cmd; 129 + int ret; 130 + u32 val; /* val will be assigned at the beginning of readl_poll_timeout function */ 131 + 132 + writel(0, dp->base + HIBMC_DP_AUX_WR_DATA0); 133 + writel(0, dp->base + HIBMC_DP_AUX_WR_DATA1); 134 + writel(0, dp->base + HIBMC_DP_AUX_WR_DATA2); 135 + writel(0, dp->base + HIBMC_DP_AUX_WR_DATA3); 136 + 137 + hibmc_dp_aux_write_data(dp, msg->buffer, msg->size); 138 + 139 + aux_cmd = hibmc_dp_aux_build_cmd(msg); 140 + writel(aux_cmd, dp->base + HIBMC_DP_AUX_CMD_ADDR); 141 + 142 + /* enable aux transfer */ 143 + hibmc_dp_reg_write_field(dp, HIBMC_DP_AUX_REQ, HIBMC_DP_CFG_AUX_REQ, 0x1); 144 + ret = readl_poll_timeout(dp->base + HIBMC_DP_AUX_REQ, val, 145 + !(val & HIBMC_DP_CFG_AUX_REQ), 50, 5000); 146 + if (ret) { 147 + hibmc_dp_aux_reset(dp); 148 + return ret; 149 + } 150 + 151 + return hibmc_dp_aux_parse_xfer(dp, msg); 152 + } 153 + 154 + void hibmc_dp_aux_init(struct hibmc_dp_dev *dp) 155 + { 156 + hibmc_dp_reg_write_field(dp, HIBMC_DP_AUX_REQ, HIBMC_DP_CFG_AUX_SYNC_LEN_SEL, 0x0); 157 + hibmc_dp_reg_write_field(dp, HIBMC_DP_AUX_REQ, HIBMC_DP_CFG_AUX_TIMER_TIMEOUT, 0x1); 158 + hibmc_dp_reg_write_field(dp, HIBMC_DP_AUX_REQ, HIBMC_DP_CFG_AUX_MIN_PULSE_NUM, 159 + HIBMC_DP_MIN_PULSE_NUM); 160 + 161 + dp->aux.transfer = hibmc_dp_aux_xfer; 162 + dp->aux.is_remote = 0; 163 + drm_dp_aux_init(&dp->aux); 164 + }
+63
drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef DP_COMM_H 5 + #define DP_COMM_H 6 + 7 + #include <linux/types.h> 8 + #include <linux/bitops.h> 9 + #include <linux/errno.h> 10 + #include <linux/mutex.h> 11 + #include <linux/kernel.h> 12 + #include <linux/bitfield.h> 13 + #include <linux/io.h> 14 + #include <drm/display/drm_dp_helper.h> 15 + 16 + #define HIBMC_DP_LANE_NUM_MAX 2 17 + 18 + struct hibmc_link_status { 19 + bool clock_recovered; 20 + bool channel_equalized; 21 + }; 22 + 23 + struct hibmc_link_cap { 24 + u8 link_rate; 25 + u8 lanes; 26 + }; 27 + 28 + struct hibmc_dp_link { 29 + struct hibmc_link_status status; 30 + u8 train_set[HIBMC_DP_LANE_NUM_MAX]; 31 + struct hibmc_link_cap cap; 32 + }; 33 + 34 + struct hibmc_dp_dev { 35 + struct drm_dp_aux aux; 36 + struct drm_device *dev; 37 + void __iomem *base; 38 + struct mutex lock; /* protects concurrent RW in hibmc_dp_reg_write_field() */ 39 + struct hibmc_dp_link link; 40 + u8 dpcd[DP_RECEIVER_CAP_SIZE]; 41 + }; 42 + 43 + #define dp_field_modify(reg_value, mask, val) \ 44 + do { \ 45 + (reg_value) &= ~(mask); \ 46 + (reg_value) |= FIELD_PREP(mask, val); \ 47 + } while (0) \ 48 + 49 + #define hibmc_dp_reg_write_field(dp, offset, mask, val) \ 50 + do { \ 51 + typeof(dp) _dp = dp; \ 52 + typeof(_dp->base) addr = (_dp->base + (offset)); \ 53 + mutex_lock(&_dp->lock); \ 54 + u32 reg_value = readl(addr); \ 55 + dp_field_modify(reg_value, mask, val); \ 56 + writel(reg_value, addr); \ 57 + mutex_unlock(&_dp->lock); \ 58 + } while (0) 59 + 60 + void hibmc_dp_aux_init(struct hibmc_dp_dev *dp); 61 + int hibmc_dp_link_training(struct hibmc_dp_dev *dp); 62 + 63 + #endif
+19
drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef DP_CONFIG_H 5 + #define DP_CONFIG_H 6 + 7 + #define HIBMC_DP_BPP 24 8 + #define HIBMC_DP_SYMBOL_PER_FCLK 4 9 + #define HIBMC_DP_MSA1 0x20 10 + #define HIBMC_DP_MSA2 0x845c00 11 + #define HIBMC_DP_OFFSET 0x1e0000 12 + #define HIBMC_DP_HDCP 0x2 13 + #define HIBMC_DP_INT_RST 0xffff 14 + #define HIBMC_DP_DPTX_RST 0x3ff 15 + #define HIBMC_DP_CLK_EN 0x7 16 + #define HIBMC_DP_SYNC_EN_MASK 0x3 17 + #define HIBMC_DP_LINK_RATE_CAL 27 18 + 19 + #endif
+220
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/io.h> 5 + #include <linux/delay.h> 6 + #include "dp_config.h" 7 + #include "dp_comm.h" 8 + #include "dp_reg.h" 9 + #include "dp_hw.h" 10 + 11 + static void hibmc_dp_set_tu(struct hibmc_dp_dev *dp, struct drm_display_mode *mode) 12 + { 13 + u32 tu_symbol_frac_size; 14 + u32 tu_symbol_size; 15 + u32 rate_ks; 16 + u8 lane_num; 17 + u32 value; 18 + u32 bpp; 19 + 20 + lane_num = dp->link.cap.lanes; 21 + if (lane_num == 0) { 22 + drm_err(dp->dev, "set tu failed, lane num cannot be 0!\n"); 23 + return; 24 + } 25 + 26 + bpp = HIBMC_DP_BPP; 27 + rate_ks = dp->link.cap.link_rate * HIBMC_DP_LINK_RATE_CAL; 28 + value = (mode->clock * bpp * 5) / (61 * lane_num * rate_ks); 29 + 30 + if (value % 10 == 9) { /* 9 carry */ 31 + tu_symbol_size = value / 10 + 1; 32 + tu_symbol_frac_size = 0; 33 + } else { 34 + tu_symbol_size = value / 10; 35 + tu_symbol_frac_size = value % 10 + 1; 36 + } 37 + 38 + drm_dbg_dp(dp->dev, "tu value: %u.%u value: %u\n", 39 + tu_symbol_size, tu_symbol_frac_size, value); 40 + 41 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_PACKET, 42 + HIBMC_DP_CFG_STREAM_TU_SYMBOL_SIZE, tu_symbol_size); 43 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_PACKET, 44 + HIBMC_DP_CFG_STREAM_TU_SYMBOL_FRAC_SIZE, tu_symbol_frac_size); 45 + } 46 + 47 + static void hibmc_dp_set_sst(struct hibmc_dp_dev *dp, struct drm_display_mode *mode) 48 + { 49 + u32 hblank_size; 50 + u32 htotal_size; 51 + u32 htotal_int; 52 + u32 hblank_int; 53 + u32 fclk; /* flink_clock */ 54 + 55 + fclk = dp->link.cap.link_rate * HIBMC_DP_LINK_RATE_CAL; 56 + 57 + /* Considering the effect of spread spectrum, the value may be deviated. 58 + * The coefficient (0.9947) is used to offset the deviation. 59 + */ 60 + htotal_int = mode->htotal * 9947 / 10000; 61 + htotal_size = htotal_int * fclk / (HIBMC_DP_SYMBOL_PER_FCLK * (mode->clock / 1000)); 62 + 63 + hblank_int = mode->htotal - mode->hdisplay - mode->hdisplay * 53 / 10000; 64 + hblank_size = hblank_int * fclk * 9947 / 65 + (mode->clock * 10 * HIBMC_DP_SYMBOL_PER_FCLK); 66 + 67 + drm_dbg_dp(dp->dev, "h_active %u v_active %u htotal_size %u hblank_size %u", 68 + mode->hdisplay, mode->vdisplay, htotal_size, hblank_size); 69 + drm_dbg_dp(dp->dev, "flink_clock %u pixel_clock %d", fclk, mode->clock / 1000); 70 + 71 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_HORIZONTAL_SIZE, 72 + HIBMC_DP_CFG_STREAM_HTOTAL_SIZE, htotal_size); 73 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_HORIZONTAL_SIZE, 74 + HIBMC_DP_CFG_STREAM_HBLANK_SIZE, hblank_size); 75 + } 76 + 77 + static void hibmc_dp_link_cfg(struct hibmc_dp_dev *dp, struct drm_display_mode *mode) 78 + { 79 + u32 timing_delay; 80 + u32 vblank; 81 + u32 hstart; 82 + u32 vstart; 83 + 84 + vblank = mode->vtotal - mode->vdisplay; 85 + timing_delay = mode->htotal - mode->hsync_start; 86 + hstart = mode->htotal - mode->hsync_start; 87 + vstart = mode->vtotal - mode->vsync_start; 88 + 89 + hibmc_dp_reg_write_field(dp, HIBMC_DP_TIMING_GEN_CONFIG0, 90 + HIBMC_DP_CFG_TIMING_GEN0_HBLANK, mode->htotal - mode->hdisplay); 91 + hibmc_dp_reg_write_field(dp, HIBMC_DP_TIMING_GEN_CONFIG0, 92 + HIBMC_DP_CFG_TIMING_GEN0_HACTIVE, mode->hdisplay); 93 + 94 + hibmc_dp_reg_write_field(dp, HIBMC_DP_TIMING_GEN_CONFIG2, 95 + HIBMC_DP_CFG_TIMING_GEN0_VBLANK, vblank); 96 + hibmc_dp_reg_write_field(dp, HIBMC_DP_TIMING_GEN_CONFIG2, 97 + HIBMC_DP_CFG_TIMING_GEN0_VACTIVE, mode->vdisplay); 98 + hibmc_dp_reg_write_field(dp, HIBMC_DP_TIMING_GEN_CONFIG3, 99 + HIBMC_DP_CFG_TIMING_GEN0_VFRONT_PORCH, 100 + mode->vsync_start - mode->vdisplay); 101 + 102 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CONFIG0, 103 + HIBMC_DP_CFG_STREAM_HACTIVE, mode->hdisplay); 104 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CONFIG0, 105 + HIBMC_DP_CFG_STREAM_HBLANK, mode->htotal - mode->hdisplay); 106 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CONFIG2, 107 + HIBMC_DP_CFG_STREAM_HSYNC_WIDTH, 108 + mode->hsync_end - mode->hsync_start); 109 + 110 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CONFIG1, 111 + HIBMC_DP_CFG_STREAM_VACTIVE, mode->vdisplay); 112 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CONFIG1, 113 + HIBMC_DP_CFG_STREAM_VBLANK, vblank); 114 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CONFIG3, 115 + HIBMC_DP_CFG_STREAM_VFRONT_PORCH, 116 + mode->vsync_start - mode->vdisplay); 117 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CONFIG3, 118 + HIBMC_DP_CFG_STREAM_VSYNC_WIDTH, 119 + mode->vsync_end - mode->vsync_start); 120 + 121 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_MSA0, 122 + HIBMC_DP_CFG_STREAM_VSTART, vstart); 123 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_MSA0, 124 + HIBMC_DP_CFG_STREAM_HSTART, hstart); 125 + 126 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CTRL, HIBMC_DP_CFG_STREAM_VSYNC_POLARITY, 127 + mode->flags & DRM_MODE_FLAG_PVSYNC ? 1 : 0); 128 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CTRL, HIBMC_DP_CFG_STREAM_HSYNC_POLARITY, 129 + mode->flags & DRM_MODE_FLAG_PHSYNC ? 1 : 0); 130 + 131 + /* MSA mic 0 and 1 */ 132 + writel(HIBMC_DP_MSA1, dp->base + HIBMC_DP_VIDEO_MSA1); 133 + writel(HIBMC_DP_MSA2, dp->base + HIBMC_DP_VIDEO_MSA2); 134 + 135 + hibmc_dp_set_tu(dp, mode); 136 + 137 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CTRL, HIBMC_DP_CFG_STREAM_RGB_ENABLE, 0x1); 138 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CTRL, HIBMC_DP_CFG_STREAM_VIDEO_MAPPING, 0); 139 + 140 + /* divide 2: up even */ 141 + if (timing_delay % 2) 142 + timing_delay++; 143 + 144 + hibmc_dp_reg_write_field(dp, HIBMC_DP_TIMING_MODEL_CTRL, 145 + HIBMC_DP_CFG_PIXEL_NUM_TIMING_MODE_SEL1, timing_delay); 146 + 147 + hibmc_dp_set_sst(dp, mode); 148 + } 149 + 150 + int hibmc_dp_hw_init(struct hibmc_dp *dp) 151 + { 152 + struct drm_device *drm_dev = dp->drm_dev; 153 + struct hibmc_dp_dev *dp_dev; 154 + 155 + dp_dev = devm_kzalloc(drm_dev->dev, sizeof(struct hibmc_dp_dev), GFP_KERNEL); 156 + if (!dp_dev) 157 + return -ENOMEM; 158 + 159 + mutex_init(&dp_dev->lock); 160 + 161 + dp->dp_dev = dp_dev; 162 + 163 + dp_dev->dev = drm_dev; 164 + dp_dev->base = dp->mmio + HIBMC_DP_OFFSET; 165 + 166 + hibmc_dp_aux_init(dp_dev); 167 + 168 + dp_dev->link.cap.lanes = 0x2; 169 + dp_dev->link.cap.link_rate = DP_LINK_BW_2_7; 170 + 171 + /* hdcp data */ 172 + writel(HIBMC_DP_HDCP, dp_dev->base + HIBMC_DP_HDCP_CFG); 173 + /* int init */ 174 + writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE); 175 + writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS); 176 + /* rst */ 177 + writel(HIBMC_DP_DPTX_RST, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL); 178 + /* clock enable */ 179 + writel(HIBMC_DP_CLK_EN, dp_dev->base + HIBMC_DP_DPTX_CLK_CTRL); 180 + 181 + return 0; 182 + } 183 + 184 + void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable) 185 + { 186 + struct hibmc_dp_dev *dp_dev = dp->dp_dev; 187 + 188 + if (enable) { 189 + hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_VIDEO_CTRL, BIT(0), 0x1); 190 + writel(HIBMC_DP_SYNC_EN_MASK, dp_dev->base + HIBMC_DP_TIMING_SYNC_CTRL); 191 + hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_DPTX_GCTL0, BIT(10), 0x1); 192 + writel(HIBMC_DP_SYNC_EN_MASK, dp_dev->base + HIBMC_DP_TIMING_SYNC_CTRL); 193 + } else { 194 + hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_DPTX_GCTL0, BIT(10), 0); 195 + writel(HIBMC_DP_SYNC_EN_MASK, dp_dev->base + HIBMC_DP_TIMING_SYNC_CTRL); 196 + hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_VIDEO_CTRL, BIT(0), 0); 197 + writel(HIBMC_DP_SYNC_EN_MASK, dp_dev->base + HIBMC_DP_TIMING_SYNC_CTRL); 198 + } 199 + 200 + msleep(50); 201 + } 202 + 203 + int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode) 204 + { 205 + struct hibmc_dp_dev *dp_dev = dp->dp_dev; 206 + int ret; 207 + 208 + if (!dp_dev->link.status.channel_equalized) { 209 + ret = hibmc_dp_link_training(dp_dev); 210 + if (ret) { 211 + drm_err(dp->drm_dev, "dp link training failed, ret: %d\n", ret); 212 + return ret; 213 + } 214 + } 215 + 216 + hibmc_dp_display_en(dp, false); 217 + hibmc_dp_link_cfg(dp_dev, mode); 218 + 219 + return 0; 220 + }
+28
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef DP_KAPI_H 5 + #define DP_KAPI_H 6 + 7 + #include <linux/types.h> 8 + #include <linux/delay.h> 9 + #include <drm/drm_device.h> 10 + #include <drm/drm_encoder.h> 11 + #include <drm/drm_connector.h> 12 + #include <drm/drm_print.h> 13 + 14 + struct hibmc_dp_dev; 15 + 16 + struct hibmc_dp { 17 + struct hibmc_dp_dev *dp_dev; 18 + struct drm_device *drm_dev; 19 + struct drm_encoder encoder; 20 + struct drm_connector connector; 21 + void __iomem *mmio; 22 + }; 23 + 24 + int hibmc_dp_hw_init(struct hibmc_dp *dp); 25 + int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode); 26 + void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable); 27 + 28 + #endif
+332
drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/delay.h> 5 + #include <drm/drm_device.h> 6 + #include <drm/drm_print.h> 7 + #include "dp_comm.h" 8 + #include "dp_reg.h" 9 + 10 + #define HIBMC_EQ_MAX_RETRY 5 11 + 12 + static int hibmc_dp_link_training_configure(struct hibmc_dp_dev *dp) 13 + { 14 + u8 buf[2]; 15 + int ret; 16 + 17 + /* DP 2 lane */ 18 + hibmc_dp_reg_write_field(dp, HIBMC_DP_PHYIF_CTRL0, HIBMC_DP_CFG_LANE_DATA_EN, 19 + dp->link.cap.lanes == 0x2 ? 0x3 : 0x1); 20 + hibmc_dp_reg_write_field(dp, HIBMC_DP_DPTX_GCTL0, HIBMC_DP_CFG_PHY_LANE_NUM, 21 + dp->link.cap.lanes == 0x2 ? 0x1 : 0); 22 + 23 + /* enhanced frame */ 24 + hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CTRL, HIBMC_DP_CFG_STREAM_FRAME_MODE, 0x1); 25 + 26 + /* set rate and lane count */ 27 + buf[0] = dp->link.cap.link_rate; 28 + buf[1] = DP_LANE_COUNT_ENHANCED_FRAME_EN | dp->link.cap.lanes; 29 + ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, sizeof(buf)); 30 + if (ret != sizeof(buf)) { 31 + drm_dbg_dp(dp->dev, "dp aux write link rate and lanes failed, ret: %d\n", ret); 32 + return ret >= 0 ? -EIO : ret; 33 + } 34 + 35 + /* set 8b/10b and downspread */ 36 + buf[0] = DP_SPREAD_AMP_0_5; 37 + buf[1] = DP_SET_ANSI_8B10B; 38 + ret = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, sizeof(buf)); 39 + if (ret != sizeof(buf)) { 40 + drm_dbg_dp(dp->dev, "dp aux write 8b/10b and downspread failed, ret: %d\n", ret); 41 + return ret >= 0 ? -EIO : ret; 42 + } 43 + 44 + ret = drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd); 45 + if (ret) 46 + drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret); 47 + 48 + return ret; 49 + } 50 + 51 + static int hibmc_dp_link_set_pattern(struct hibmc_dp_dev *dp, int pattern) 52 + { 53 + int ret; 54 + u8 val; 55 + u8 buf; 56 + 57 + buf = (u8)pattern; 58 + if (pattern != DP_TRAINING_PATTERN_DISABLE && pattern != DP_TRAINING_PATTERN_4) { 59 + buf |= DP_LINK_SCRAMBLING_DISABLE; 60 + hibmc_dp_reg_write_field(dp, HIBMC_DP_PHYIF_CTRL0, HIBMC_DP_CFG_SCRAMBLE_EN, 0x1); 61 + } else { 62 + hibmc_dp_reg_write_field(dp, HIBMC_DP_PHYIF_CTRL0, HIBMC_DP_CFG_SCRAMBLE_EN, 0); 63 + } 64 + 65 + switch (pattern) { 66 + case DP_TRAINING_PATTERN_DISABLE: 67 + val = 0; 68 + break; 69 + case DP_TRAINING_PATTERN_1: 70 + val = 1; 71 + break; 72 + case DP_TRAINING_PATTERN_2: 73 + val = 2; 74 + break; 75 + case DP_TRAINING_PATTERN_3: 76 + val = 3; 77 + break; 78 + case DP_TRAINING_PATTERN_4: 79 + val = 4; 80 + break; 81 + default: 82 + return -EINVAL; 83 + } 84 + 85 + hibmc_dp_reg_write_field(dp, HIBMC_DP_PHYIF_CTRL0, HIBMC_DP_CFG_PAT_SEL, val); 86 + 87 + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_PATTERN_SET, &buf, sizeof(buf)); 88 + if (ret != sizeof(buf)) { 89 + drm_dbg_dp(dp->dev, "dp aux write training pattern set failed\n"); 90 + return ret >= 0 ? -EIO : ret; 91 + } 92 + 93 + return 0; 94 + } 95 + 96 + static int hibmc_dp_link_training_cr_pre(struct hibmc_dp_dev *dp) 97 + { 98 + u8 *train_set = dp->link.train_set; 99 + int ret; 100 + u8 i; 101 + 102 + ret = hibmc_dp_link_training_configure(dp); 103 + if (ret) 104 + return ret; 105 + 106 + ret = hibmc_dp_link_set_pattern(dp, DP_TRAINING_PATTERN_1); 107 + if (ret) 108 + return ret; 109 + 110 + for (i = 0; i < dp->link.cap.lanes; i++) 111 + train_set[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2; 112 + 113 + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, train_set, dp->link.cap.lanes); 114 + if (ret != dp->link.cap.lanes) { 115 + drm_dbg_dp(dp->dev, "dp aux write training lane set failed\n"); 116 + return ret >= 0 ? -EIO : ret; 117 + } 118 + 119 + return 0; 120 + } 121 + 122 + static bool hibmc_dp_link_get_adjust_train(struct hibmc_dp_dev *dp, 123 + u8 lane_status[DP_LINK_STATUS_SIZE]) 124 + { 125 + u8 train_set[HIBMC_DP_LANE_NUM_MAX] = {0}; 126 + u8 lane; 127 + 128 + for (lane = 0; lane < dp->link.cap.lanes; lane++) 129 + train_set[lane] = drm_dp_get_adjust_request_voltage(lane_status, lane) | 130 + drm_dp_get_adjust_request_pre_emphasis(lane_status, lane); 131 + 132 + if (memcmp(dp->link.train_set, train_set, HIBMC_DP_LANE_NUM_MAX)) { 133 + memcpy(dp->link.train_set, train_set, HIBMC_DP_LANE_NUM_MAX); 134 + return true; 135 + } 136 + 137 + return false; 138 + } 139 + 140 + static inline int hibmc_dp_link_reduce_rate(struct hibmc_dp_dev *dp) 141 + { 142 + switch (dp->link.cap.link_rate) { 143 + case DP_LINK_BW_2_7: 144 + dp->link.cap.link_rate = DP_LINK_BW_1_62; 145 + return 0; 146 + case DP_LINK_BW_5_4: 147 + dp->link.cap.link_rate = DP_LINK_BW_2_7; 148 + return 0; 149 + case DP_LINK_BW_8_1: 150 + dp->link.cap.link_rate = DP_LINK_BW_5_4; 151 + return 0; 152 + default: 153 + return -EINVAL; 154 + } 155 + } 156 + 157 + static inline int hibmc_dp_link_reduce_lane(struct hibmc_dp_dev *dp) 158 + { 159 + switch (dp->link.cap.lanes) { 160 + case 0x2: 161 + dp->link.cap.lanes--; 162 + break; 163 + case 0x1: 164 + drm_err(dp->dev, "dp link training reduce lane failed, already reach minimum\n"); 165 + return -EIO; 166 + default: 167 + return -EINVAL; 168 + } 169 + 170 + return 0; 171 + } 172 + 173 + static int hibmc_dp_link_training_cr(struct hibmc_dp_dev *dp) 174 + { 175 + u8 lane_status[DP_LINK_STATUS_SIZE] = {0}; 176 + bool level_changed; 177 + u32 voltage_tries; 178 + u32 cr_tries; 179 + int ret; 180 + 181 + /* 182 + * DP 1.4 spec define 10 for maxtries value, for pre DP 1.4 version set a limit of 80 183 + * (4 voltage levels x 4 preemphasis levels x 5 identical voltage retries) 184 + */ 185 + 186 + voltage_tries = 1; 187 + for (cr_tries = 0; cr_tries < 80; cr_tries++) { 188 + drm_dp_link_train_clock_recovery_delay(&dp->aux, dp->dpcd); 189 + 190 + ret = drm_dp_dpcd_read_link_status(&dp->aux, lane_status); 191 + if (ret != DP_LINK_STATUS_SIZE) { 192 + drm_err(dp->dev, "Get lane status failed\n"); 193 + return ret; 194 + } 195 + 196 + if (drm_dp_clock_recovery_ok(lane_status, dp->link.cap.lanes)) { 197 + drm_dbg_dp(dp->dev, "dp link training cr done\n"); 198 + dp->link.status.clock_recovered = true; 199 + return 0; 200 + } 201 + 202 + if (voltage_tries == 5) { 203 + drm_dbg_dp(dp->dev, "same voltage tries 5 times\n"); 204 + dp->link.status.clock_recovered = false; 205 + return 0; 206 + } 207 + 208 + level_changed = hibmc_dp_link_get_adjust_train(dp, lane_status); 209 + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, dp->link.train_set, 210 + dp->link.cap.lanes); 211 + if (ret != dp->link.cap.lanes) { 212 + drm_dbg_dp(dp->dev, "Update link training failed\n"); 213 + return ret >= 0 ? -EIO : ret; 214 + } 215 + 216 + voltage_tries = level_changed ? 1 : voltage_tries + 1; 217 + } 218 + 219 + drm_err(dp->dev, "dp link training clock recovery 80 times failed\n"); 220 + dp->link.status.clock_recovered = false; 221 + 222 + return 0; 223 + } 224 + 225 + static int hibmc_dp_link_training_channel_eq(struct hibmc_dp_dev *dp) 226 + { 227 + u8 lane_status[DP_LINK_STATUS_SIZE] = {0}; 228 + u8 eq_tries; 229 + int ret; 230 + 231 + ret = hibmc_dp_link_set_pattern(dp, DP_TRAINING_PATTERN_2); 232 + if (ret) 233 + return ret; 234 + 235 + for (eq_tries = 0; eq_tries < HIBMC_EQ_MAX_RETRY; eq_tries++) { 236 + drm_dp_link_train_channel_eq_delay(&dp->aux, dp->dpcd); 237 + 238 + ret = drm_dp_dpcd_read_link_status(&dp->aux, lane_status); 239 + if (ret != DP_LINK_STATUS_SIZE) { 240 + drm_err(dp->dev, "get lane status failed\n"); 241 + break; 242 + } 243 + 244 + if (!drm_dp_clock_recovery_ok(lane_status, dp->link.cap.lanes)) { 245 + drm_dbg_dp(dp->dev, "clock recovery check failed\n"); 246 + drm_dbg_dp(dp->dev, "cannot continue channel equalization\n"); 247 + dp->link.status.clock_recovered = false; 248 + break; 249 + } 250 + 251 + if (drm_dp_channel_eq_ok(lane_status, dp->link.cap.lanes)) { 252 + dp->link.status.channel_equalized = true; 253 + drm_dbg_dp(dp->dev, "dp link training eq done\n"); 254 + break; 255 + } 256 + 257 + hibmc_dp_link_get_adjust_train(dp, lane_status); 258 + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, 259 + dp->link.train_set, dp->link.cap.lanes); 260 + if (ret != dp->link.cap.lanes) { 261 + drm_dbg_dp(dp->dev, "Update link training failed\n"); 262 + ret = (ret >= 0) ? -EIO : ret; 263 + break; 264 + } 265 + } 266 + 267 + if (eq_tries == HIBMC_EQ_MAX_RETRY) 268 + drm_err(dp->dev, "channel equalization failed %u times\n", eq_tries); 269 + 270 + hibmc_dp_link_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE); 271 + 272 + return ret < 0 ? ret : 0; 273 + } 274 + 275 + static int hibmc_dp_link_downgrade_training_cr(struct hibmc_dp_dev *dp) 276 + { 277 + if (hibmc_dp_link_reduce_rate(dp)) 278 + return hibmc_dp_link_reduce_lane(dp); 279 + 280 + return 0; 281 + } 282 + 283 + static int hibmc_dp_link_downgrade_training_eq(struct hibmc_dp_dev *dp) 284 + { 285 + if ((dp->link.status.clock_recovered && !dp->link.status.channel_equalized)) { 286 + if (!hibmc_dp_link_reduce_lane(dp)) 287 + return 0; 288 + } 289 + 290 + return hibmc_dp_link_reduce_rate(dp); 291 + } 292 + 293 + int hibmc_dp_link_training(struct hibmc_dp_dev *dp) 294 + { 295 + struct hibmc_dp_link *link = &dp->link; 296 + int ret; 297 + 298 + while (true) { 299 + ret = hibmc_dp_link_training_cr_pre(dp); 300 + if (ret) 301 + goto err; 302 + 303 + ret = hibmc_dp_link_training_cr(dp); 304 + if (ret) 305 + goto err; 306 + 307 + if (!link->status.clock_recovered) { 308 + ret = hibmc_dp_link_downgrade_training_cr(dp); 309 + if (ret) 310 + goto err; 311 + continue; 312 + } 313 + 314 + ret = hibmc_dp_link_training_channel_eq(dp); 315 + if (ret) 316 + goto err; 317 + 318 + if (!link->status.channel_equalized) { 319 + ret = hibmc_dp_link_downgrade_training_eq(dp); 320 + if (ret) 321 + goto err; 322 + continue; 323 + } 324 + 325 + return 0; 326 + } 327 + 328 + err: 329 + hibmc_dp_link_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE); 330 + 331 + return ret; 332 + }
+76
drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef DP_REG_H 5 + #define DP_REG_H 6 + 7 + #define HIBMC_DP_AUX_CMD_ADDR 0x50 8 + #define HIBMC_DP_AUX_WR_DATA0 0x54 9 + #define HIBMC_DP_AUX_WR_DATA1 0x58 10 + #define HIBMC_DP_AUX_WR_DATA2 0x5c 11 + #define HIBMC_DP_AUX_WR_DATA3 0x60 12 + #define HIBMC_DP_AUX_RD_DATA0 0x64 13 + #define HIBMC_DP_AUX_REQ 0x74 14 + #define HIBMC_DP_AUX_STATUS 0x78 15 + #define HIBMC_DP_PHYIF_CTRL0 0xa0 16 + #define HIBMC_DP_VIDEO_CTRL 0x100 17 + #define HIBMC_DP_VIDEO_CONFIG0 0x104 18 + #define HIBMC_DP_VIDEO_CONFIG1 0x108 19 + #define HIBMC_DP_VIDEO_CONFIG2 0x10c 20 + #define HIBMC_DP_VIDEO_CONFIG3 0x110 21 + #define HIBMC_DP_VIDEO_PACKET 0x114 22 + #define HIBMC_DP_VIDEO_MSA0 0x118 23 + #define HIBMC_DP_VIDEO_MSA1 0x11c 24 + #define HIBMC_DP_VIDEO_MSA2 0x120 25 + #define HIBMC_DP_VIDEO_HORIZONTAL_SIZE 0X124 26 + #define HIBMC_DP_TIMING_GEN_CONFIG0 0x26c 27 + #define HIBMC_DP_TIMING_GEN_CONFIG2 0x274 28 + #define HIBMC_DP_TIMING_GEN_CONFIG3 0x278 29 + #define HIBMC_DP_HDCP_CFG 0x600 30 + #define HIBMC_DP_DPTX_RST_CTRL 0x700 31 + #define HIBMC_DP_DPTX_CLK_CTRL 0x704 32 + #define HIBMC_DP_DPTX_GCTL0 0x708 33 + #define HIBMC_DP_INTR_ENABLE 0x720 34 + #define HIBMC_DP_INTR_ORIGINAL_STATUS 0x728 35 + #define HIBMC_DP_TIMING_MODEL_CTRL 0x884 36 + #define HIBMC_DP_TIMING_SYNC_CTRL 0xFF0 37 + 38 + #define HIBMC_DP_CFG_AUX_SYNC_LEN_SEL BIT(1) 39 + #define HIBMC_DP_CFG_AUX_TIMER_TIMEOUT BIT(2) 40 + #define HIBMC_DP_CFG_STREAM_FRAME_MODE BIT(6) 41 + #define HIBMC_DP_CFG_AUX_MIN_PULSE_NUM GENMASK(13, 9) 42 + #define HIBMC_DP_CFG_LANE_DATA_EN GENMASK(11, 8) 43 + #define HIBMC_DP_CFG_PHY_LANE_NUM GENMASK(2, 1) 44 + #define HIBMC_DP_CFG_AUX_REQ BIT(0) 45 + #define HIBMC_DP_CFG_AUX_RST_N BIT(4) 46 + #define HIBMC_DP_CFG_AUX_TIMEOUT BIT(0) 47 + #define HIBMC_DP_CFG_AUX_READY_DATA_BYTE GENMASK(16, 12) 48 + #define HIBMC_DP_CFG_AUX GENMASK(24, 17) 49 + #define HIBMC_DP_CFG_AUX_STATUS GENMASK(11, 4) 50 + #define HIBMC_DP_CFG_SCRAMBLE_EN BIT(0) 51 + #define HIBMC_DP_CFG_PAT_SEL GENMASK(7, 4) 52 + #define HIBMC_DP_CFG_TIMING_GEN0_HACTIVE GENMASK(31, 16) 53 + #define HIBMC_DP_CFG_TIMING_GEN0_HBLANK GENMASK(15, 0) 54 + #define HIBMC_DP_CFG_TIMING_GEN0_VACTIVE GENMASK(31, 16) 55 + #define HIBMC_DP_CFG_TIMING_GEN0_VBLANK GENMASK(15, 0) 56 + #define HIBMC_DP_CFG_TIMING_GEN0_VFRONT_PORCH GENMASK(31, 16) 57 + #define HIBMC_DP_CFG_STREAM_HACTIVE GENMASK(31, 16) 58 + #define HIBMC_DP_CFG_STREAM_HBLANK GENMASK(15, 0) 59 + #define HIBMC_DP_CFG_STREAM_HSYNC_WIDTH GENMASK(15, 0) 60 + #define HIBMC_DP_CFG_STREAM_VACTIVE GENMASK(31, 16) 61 + #define HIBMC_DP_CFG_STREAM_VBLANK GENMASK(15, 0) 62 + #define HIBMC_DP_CFG_STREAM_VFRONT_PORCH GENMASK(31, 16) 63 + #define HIBMC_DP_CFG_STREAM_VSYNC_WIDTH GENMASK(15, 0) 64 + #define HIBMC_DP_CFG_STREAM_VSTART GENMASK(31, 16) 65 + #define HIBMC_DP_CFG_STREAM_HSTART GENMASK(15, 0) 66 + #define HIBMC_DP_CFG_STREAM_VSYNC_POLARITY BIT(8) 67 + #define HIBMC_DP_CFG_STREAM_HSYNC_POLARITY BIT(7) 68 + #define HIBMC_DP_CFG_STREAM_RGB_ENABLE BIT(1) 69 + #define HIBMC_DP_CFG_STREAM_VIDEO_MAPPING GENMASK(5, 2) 70 + #define HIBMC_DP_CFG_PIXEL_NUM_TIMING_MODE_SEL1 GENMASK(31, 16) 71 + #define HIBMC_DP_CFG_STREAM_TU_SYMBOL_SIZE GENMASK(5, 0) 72 + #define HIBMC_DP_CFG_STREAM_TU_SYMBOL_FRAC_SIZE GENMASK(9, 6) 73 + #define HIBMC_DP_CFG_STREAM_HTOTAL_SIZE GENMASK(31, 16) 74 + #define HIBMC_DP_CFG_STREAM_HBLANK_SIZE GENMASK(15, 0) 75 + 76 + #endif
+118
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/io.h> 5 + 6 + #include <drm/drm_probe_helper.h> 7 + #include <drm/drm_simple_kms_helper.h> 8 + #include <drm/drm_atomic_helper.h> 9 + #include <drm/drm_modes.h> 10 + #include <drm/drm_drv.h> 11 + #include <drm/drm_edid.h> 12 + 13 + #include "hibmc_drm_drv.h" 14 + #include "dp/dp_hw.h" 15 + 16 + static int hibmc_dp_connector_get_modes(struct drm_connector *connector) 17 + { 18 + int count; 19 + 20 + count = drm_add_modes_noedid(connector, connector->dev->mode_config.max_width, 21 + connector->dev->mode_config.max_height); 22 + drm_set_preferred_mode(connector, 1024, 768); // temporary implementation 23 + 24 + return count; 25 + } 26 + 27 + static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = { 28 + .get_modes = hibmc_dp_connector_get_modes, 29 + }; 30 + 31 + static const struct drm_connector_funcs hibmc_dp_conn_funcs = { 32 + .reset = drm_atomic_helper_connector_reset, 33 + .fill_modes = drm_helper_probe_single_connector_modes, 34 + .destroy = drm_connector_cleanup, 35 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 36 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 37 + }; 38 + 39 + static inline int hibmc_dp_prepare(struct hibmc_dp *dp, struct drm_display_mode *mode) 40 + { 41 + int ret; 42 + 43 + hibmc_dp_display_en(dp, false); 44 + 45 + ret = hibmc_dp_mode_set(dp, mode); 46 + if (ret) 47 + drm_err(dp->drm_dev, "hibmc dp mode set failed: %d\n", ret); 48 + 49 + return ret; 50 + } 51 + 52 + static void hibmc_dp_encoder_enable(struct drm_encoder *drm_encoder, 53 + struct drm_atomic_state *state) 54 + { 55 + struct hibmc_dp *dp = container_of(drm_encoder, struct hibmc_dp, encoder); 56 + struct drm_display_mode *mode = &drm_encoder->crtc->state->mode; 57 + 58 + if (hibmc_dp_prepare(dp, mode)) 59 + return; 60 + 61 + hibmc_dp_display_en(dp, true); 62 + } 63 + 64 + static void hibmc_dp_encoder_disable(struct drm_encoder *drm_encoder, 65 + struct drm_atomic_state *state) 66 + { 67 + struct hibmc_dp *dp = container_of(drm_encoder, struct hibmc_dp, encoder); 68 + 69 + hibmc_dp_display_en(dp, false); 70 + } 71 + 72 + static const struct drm_encoder_helper_funcs hibmc_dp_encoder_helper_funcs = { 73 + .atomic_enable = hibmc_dp_encoder_enable, 74 + .atomic_disable = hibmc_dp_encoder_disable, 75 + }; 76 + 77 + int hibmc_dp_init(struct hibmc_drm_private *priv) 78 + { 79 + struct drm_device *dev = &priv->dev; 80 + struct drm_crtc *crtc = &priv->crtc; 81 + struct hibmc_dp *dp = &priv->dp; 82 + struct drm_connector *connector = &dp->connector; 83 + struct drm_encoder *encoder = &dp->encoder; 84 + int ret; 85 + 86 + dp->mmio = priv->mmio; 87 + dp->drm_dev = dev; 88 + 89 + ret = hibmc_dp_hw_init(&priv->dp); 90 + if (ret) { 91 + drm_err(dev, "hibmc dp hw init failed: %d\n", ret); 92 + return ret; 93 + } 94 + 95 + hibmc_dp_display_en(&priv->dp, false); 96 + 97 + encoder->possible_crtcs = drm_crtc_mask(crtc); 98 + ret = drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL); 99 + if (ret) { 100 + drm_err(dev, "init dp encoder failed: %d\n", ret); 101 + return ret; 102 + } 103 + 104 + drm_encoder_helper_add(encoder, &hibmc_dp_encoder_helper_funcs); 105 + 106 + ret = drm_connector_init(dev, connector, &hibmc_dp_conn_funcs, 107 + DRM_MODE_CONNECTOR_DisplayPort); 108 + if (ret) { 109 + drm_err(dev, "init dp connector failed: %d\n", ret); 110 + return ret; 111 + } 112 + 113 + drm_connector_helper_add(connector, &hibmc_dp_conn_helper_funcs); 114 + 115 + drm_connector_attach_encoder(connector, encoder); 116 + 117 + return 0; 118 + }
+14
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
··· 28 28 #include "hibmc_drm_drv.h" 29 29 #include "hibmc_drm_regs.h" 30 30 31 + #define HIBMC_DP_HOST_SERDES_CTRL 0x1f001c 32 + #define HIBMC_DP_HOST_SERDES_CTRL_VAL 0x8a00 33 + #define HIBMC_DP_HOST_SERDES_CTRL_MASK 0x7ffff 34 + 31 35 DEFINE_DRM_GEM_FOPS(hibmc_fops); 32 36 33 37 static irqreturn_t hibmc_interrupt(int irq, void *arg) ··· 119 115 if (ret) { 120 116 drm_err(dev, "failed to init de: %d\n", ret); 121 117 return ret; 118 + } 119 + 120 + /* if DP existed, init DP */ 121 + if ((readl(priv->mmio + HIBMC_DP_HOST_SERDES_CTRL) & 122 + HIBMC_DP_HOST_SERDES_CTRL_MASK) == HIBMC_DP_HOST_SERDES_CTRL_VAL) { 123 + ret = hibmc_dp_init(priv); 124 + if (ret) 125 + drm_err(dev, "failed to init dp: %d\n", ret); 122 126 } 123 127 124 128 ret = hibmc_vdac_init(priv); ··· 338 326 drm_err(dev, "failed to enable pci device: %d\n", ret); 339 327 goto err_return; 340 328 } 329 + 330 + pci_set_master(pdev); 341 331 342 332 ret = hibmc_load(dev); 343 333 if (ret) {
+12 -7
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
··· 20 20 21 21 #include <drm/drm_framebuffer.h> 22 22 23 - struct hibmc_connector { 24 - struct drm_connector base; 23 + #include "dp/dp_hw.h" 25 24 25 + struct hibmc_vdac { 26 + struct drm_device *dev; 27 + struct drm_encoder encoder; 28 + struct drm_connector connector; 26 29 struct i2c_adapter adapter; 27 30 struct i2c_algo_bit_data bit_data; 28 31 }; ··· 38 35 struct drm_device dev; 39 36 struct drm_plane primary_plane; 40 37 struct drm_crtc crtc; 41 - struct drm_encoder encoder; 42 - struct hibmc_connector connector; 38 + struct hibmc_vdac vdac; 39 + struct hibmc_dp dp; 43 40 }; 44 41 45 - static inline struct hibmc_connector *to_hibmc_connector(struct drm_connector *connector) 42 + static inline struct hibmc_vdac *to_hibmc_vdac(struct drm_connector *connector) 46 43 { 47 - return container_of(connector, struct hibmc_connector, base); 44 + return container_of(connector, struct hibmc_vdac, connector); 48 45 } 49 46 50 47 static inline struct hibmc_drm_private *to_hibmc_drm_private(struct drm_device *dev) ··· 60 57 int hibmc_de_init(struct hibmc_drm_private *priv); 61 58 int hibmc_vdac_init(struct hibmc_drm_private *priv); 62 59 63 - int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector); 60 + int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *connector); 61 + 62 + int hibmc_dp_init(struct hibmc_drm_private *priv); 64 63 65 64 #endif
+18 -19
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
··· 25 25 26 26 static void hibmc_set_i2c_signal(void *data, u32 mask, int value) 27 27 { 28 - struct hibmc_connector *hibmc_connector = data; 29 - struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector->base.dev); 28 + struct hibmc_vdac *vdac = data; 29 + struct hibmc_drm_private *priv = to_hibmc_drm_private(vdac->connector.dev); 30 30 u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION); 31 31 32 32 if (value) { ··· 45 45 46 46 static int hibmc_get_i2c_signal(void *data, u32 mask) 47 47 { 48 - struct hibmc_connector *hibmc_connector = data; 49 - struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector->base.dev); 48 + struct hibmc_vdac *vdac = data; 49 + struct hibmc_drm_private *priv = to_hibmc_drm_private(vdac->connector.dev); 50 50 u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION); 51 51 52 52 if ((tmp_dir & mask) != mask) { ··· 77 77 return hibmc_get_i2c_signal(data, I2C_SCL_MASK); 78 78 } 79 79 80 - int hibmc_ddc_create(struct drm_device *drm_dev, 81 - struct hibmc_connector *connector) 80 + int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *vdac) 82 81 { 83 - connector->adapter.owner = THIS_MODULE; 84 - snprintf(connector->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus"); 85 - connector->adapter.dev.parent = drm_dev->dev; 86 - i2c_set_adapdata(&connector->adapter, connector); 87 - connector->adapter.algo_data = &connector->bit_data; 82 + vdac->adapter.owner = THIS_MODULE; 83 + snprintf(vdac->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus"); 84 + vdac->adapter.dev.parent = drm_dev->dev; 85 + i2c_set_adapdata(&vdac->adapter, vdac); 86 + vdac->adapter.algo_data = &vdac->bit_data; 88 87 89 - connector->bit_data.udelay = 20; 90 - connector->bit_data.timeout = usecs_to_jiffies(2000); 91 - connector->bit_data.data = connector; 92 - connector->bit_data.setsda = hibmc_ddc_setsda; 93 - connector->bit_data.setscl = hibmc_ddc_setscl; 94 - connector->bit_data.getsda = hibmc_ddc_getsda; 95 - connector->bit_data.getscl = hibmc_ddc_getscl; 88 + vdac->bit_data.udelay = 20; 89 + vdac->bit_data.timeout = usecs_to_jiffies(2000); 90 + vdac->bit_data.data = vdac; 91 + vdac->bit_data.setsda = hibmc_ddc_setsda; 92 + vdac->bit_data.setscl = hibmc_ddc_setscl; 93 + vdac->bit_data.getsda = hibmc_ddc_getsda; 94 + vdac->bit_data.getscl = hibmc_ddc_getscl; 96 95 97 - return i2c_bit_add_bus(&connector->adapter); 96 + return i2c_bit_add_bus(&vdac->adapter); 98 97 }
+10 -10
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
··· 24 24 25 25 static int hibmc_connector_get_modes(struct drm_connector *connector) 26 26 { 27 - struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector); 27 + struct hibmc_vdac *vdac = to_hibmc_vdac(connector); 28 28 const struct drm_edid *drm_edid; 29 29 int count; 30 30 31 - drm_edid = drm_edid_read_ddc(connector, &hibmc_connector->adapter); 31 + drm_edid = drm_edid_read_ddc(connector, &vdac->adapter); 32 32 33 33 drm_edid_connector_update(connector, drm_edid); 34 34 ··· 51 51 52 52 static void hibmc_connector_destroy(struct drm_connector *connector) 53 53 { 54 - struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector); 54 + struct hibmc_vdac *vdac = to_hibmc_vdac(connector); 55 55 56 - i2c_del_adapter(&hibmc_connector->adapter); 56 + i2c_del_adapter(&vdac->adapter); 57 57 drm_connector_cleanup(connector); 58 58 } 59 59 ··· 93 93 int hibmc_vdac_init(struct hibmc_drm_private *priv) 94 94 { 95 95 struct drm_device *dev = &priv->dev; 96 - struct hibmc_connector *hibmc_connector = &priv->connector; 97 - struct drm_encoder *encoder = &priv->encoder; 96 + struct hibmc_vdac *vdac = &priv->vdac; 97 + struct drm_encoder *encoder = &vdac->encoder; 98 98 struct drm_crtc *crtc = &priv->crtc; 99 - struct drm_connector *connector = &hibmc_connector->base; 99 + struct drm_connector *connector = &vdac->connector; 100 100 int ret; 101 101 102 - ret = hibmc_ddc_create(dev, hibmc_connector); 102 + ret = hibmc_ddc_create(dev, vdac); 103 103 if (ret) { 104 104 drm_err(dev, "failed to create ddc: %d\n", ret); 105 105 return ret; 106 106 } 107 107 108 108 encoder->possible_crtcs = drm_crtc_mask(crtc); 109 - ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); 109 + ret = drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_DAC, NULL); 110 110 if (ret) { 111 111 drm_err(dev, "failed to init encoder: %d\n", ret); 112 112 return ret; ··· 117 117 ret = drm_connector_init_with_ddc(dev, connector, 118 118 &hibmc_connector_funcs, 119 119 DRM_MODE_CONNECTOR_VGA, 120 - &hibmc_connector->adapter); 120 + &vdac->adapter); 121 121 if (ret) { 122 122 drm_err(dev, "failed to init connector: %d\n", ret); 123 123 return ret;
+1 -1
drivers/gpu/drm/i2c/tda998x_drv.c
··· 1165 1165 .audio_shutdown = tda998x_audio_shutdown, 1166 1166 .mute_stream = tda998x_audio_mute_stream, 1167 1167 .get_eld = tda998x_audio_get_eld, 1168 - .no_capture_mute = 1, 1169 1168 }; 1170 1169 1171 1170 static int tda998x_audio_codec_init(struct tda998x_priv *priv, ··· 1175 1176 .max_i2s_channels = 2, 1176 1177 .no_i2s_capture = 1, 1177 1178 .no_spdif_capture = 1, 1179 + .no_capture_mute = 1, 1178 1180 }; 1179 1181 1180 1182 if (priv->audio_port_enable[AUDIO_ROUTE_I2S])
+1
drivers/gpu/drm/i915/i915_drm_client.c
··· 102 102 for_each_memory_region(mr, i915, id) 103 103 drm_print_memory_stats(p, 104 104 &stats[id], 105 + DRM_GEM_OBJECT_ACTIVE | 105 106 DRM_GEM_OBJECT_RESIDENT | 106 107 DRM_GEM_OBJECT_PURGEABLE, 107 108 mr->uabi_name);
+1 -1
drivers/gpu/drm/mediatek/mtk_dp.c
··· 2638 2638 .audio_shutdown = mtk_dp_audio_shutdown, 2639 2639 .get_eld = mtk_dp_audio_get_eld, 2640 2640 .hook_plugged_cb = mtk_dp_audio_hook_plugged_cb, 2641 - .no_capture_mute = 1, 2642 2641 }; 2643 2642 2644 2643 static int mtk_dp_register_audio_driver(struct device *dev) ··· 2648 2649 .max_i2s_channels = 8, 2649 2650 .i2s = 1, 2650 2651 .data = mtk_dp, 2652 + .no_capture_mute = 1, 2651 2653 }; 2652 2654 2653 2655 mtk_dp->audio_pdev = platform_device_register_data(dev,
+1 -1
drivers/gpu/drm/mediatek/mtk_hdmi.c
··· 1660 1660 .mute_stream = mtk_hdmi_audio_mute, 1661 1661 .get_eld = mtk_hdmi_audio_get_eld, 1662 1662 .hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb, 1663 - .no_capture_mute = 1, 1664 1663 }; 1665 1664 1666 1665 static int mtk_hdmi_register_audio_driver(struct device *dev) ··· 1670 1671 .max_i2s_channels = 2, 1671 1672 .i2s = 1, 1672 1673 .data = hdmi, 1674 + .no_capture_mute = 1, 1673 1675 }; 1674 1676 struct platform_device *pdev; 1675 1677
+1 -1
drivers/gpu/drm/msm/dsi/dsi_host.c
··· 1831 1831 msm_dsi->te_source = devm_kstrdup(dev, te_source, GFP_KERNEL); 1832 1832 ret = 0; 1833 1833 1834 - if (of_property_read_bool(np, "syscon-sfpb")) { 1834 + if (of_property_present(np, "syscon-sfpb")) { 1835 1835 msm_host->sfpb = syscon_regmap_lookup_by_phandle(np, 1836 1836 "syscon-sfpb"); 1837 1837 if (IS_ERR(msm_host->sfpb)) {
+34
drivers/gpu/drm/panel/panel-simple.c
··· 4454 4454 .bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 4455 4455 }; 4456 4456 4457 + static const struct display_timing topland_tian_g07017_01_timing = { 4458 + .pixelclock = { 44900000, 51200000, 63000000 }, 4459 + .hactive = { 1024, 1024, 1024 }, 4460 + .hfront_porch = { 16, 160, 216 }, 4461 + .hback_porch = { 160, 160, 160 }, 4462 + .hsync_len = { 1, 1, 140 }, 4463 + .vactive = { 600, 600, 600 }, 4464 + .vfront_porch = { 1, 12, 127 }, 4465 + .vback_porch = { 23, 23, 23 }, 4466 + .vsync_len = { 1, 1, 20 }, 4467 + }; 4468 + 4469 + static const struct panel_desc topland_tian_g07017_01 = { 4470 + .timings = &topland_tian_g07017_01_timing, 4471 + .num_timings = 1, 4472 + .bpc = 8, 4473 + .size = { 4474 + .width = 154, 4475 + .height = 86, 4476 + }, 4477 + .delay = { 4478 + .prepare = 1, /* 6.5 - 150µs PLL wake-up time */ 4479 + .enable = 100, /* 6.4 - Power on: 6 VSyncs */ 4480 + .disable = 84, /* 6.4 - Power off: 5 Vsyncs */ 4481 + .unprepare = 50, /* 6.4 - Power off: 3 Vsyncs */ 4482 + }, 4483 + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 4484 + .connector_type = DRM_MODE_CONNECTOR_LVDS, 4485 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 4486 + }; 4487 + 4457 4488 static const struct drm_display_mode toshiba_lt089ac29000_mode = { 4458 4489 .clock = 79500, 4459 4490 .hdisplay = 1280, ··· 5170 5139 }, { 5171 5140 .compatible = "toshiba,lt089ac29000", 5172 5141 .data = &toshiba_lt089ac29000, 5142 + }, { 5143 + .compatible = "topland,tian-g07017-01", 5144 + .data = &topland_tian_g07017_01, 5173 5145 }, { 5174 5146 .compatible = "tpk,f07a-0102", 5175 5147 .data = &tpk_f07a_0102,
+1 -1
drivers/gpu/drm/rockchip/cdn-dp-core.c
··· 885 885 .mute_stream = cdn_dp_audio_mute_stream, 886 886 .get_eld = cdn_dp_audio_get_eld, 887 887 .hook_plugged_cb = cdn_dp_audio_hook_plugged_cb, 888 - .no_capture_mute = 1, 889 888 }; 890 889 891 890 static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp, ··· 895 896 .spdif = 1, 896 897 .ops = &audio_codec_ops, 897 898 .max_i2s_channels = 8, 899 + .no_capture_mute = 1, 898 900 }; 899 901 900 902 dp->audio_pdev = platform_device_register_data(
+13 -4
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
··· 1454 1454 vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en); 1455 1455 1456 1456 if (afbc_en) { 1457 - u32 stride; 1457 + u32 stride, block_w; 1458 1458 1459 - /* the afbc superblock is 16 x 16 */ 1459 + /* the afbc superblock is 16 x 16 or 32 x 8 */ 1460 + block_w = fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16; 1461 + 1460 1462 afbc_format = vop2_convert_afbc_format(fb->format->format); 1461 1463 1462 1464 /* Enable color transform for YTR */ 1463 1465 if (fb->modifier & AFBC_FORMAT_MOD_YTR) 1464 1466 afbc_format |= (1 << 4); 1465 1467 1466 - afbc_tile_num = ALIGN(actual_w, 16) >> 4; 1468 + afbc_tile_num = ALIGN(actual_w, block_w) / block_w; 1467 1469 1468 1470 /* 1469 1471 * AFBC pic_vir_width is count by pixel, this is different ··· 1475 1473 if ((stride & 0x3f) && (xmirror || rotate_90 || rotate_270)) 1476 1474 drm_dbg_kms(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n", 1477 1475 vp->id, win->data->name, stride); 1476 + 1477 + /* It's for head stride, each head size is 16 byte */ 1478 + stride = ALIGN(stride, block_w) / block_w * 16; 1478 1479 1479 1480 uv_swap = vop2_afbc_uv_swap(fb->format->format); 1480 1481 /* ··· 1509 1504 else 1510 1505 vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1); 1511 1506 1512 - vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); 1507 + if (fb->modifier & AFBC_FORMAT_MOD_SPLIT) 1508 + vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 1); 1509 + else 1510 + vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); 1511 + 1513 1512 transform_offset = vop2_afbc_transform_offset(pstate, half_block_en); 1514 1513 vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst); 1515 1514 vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
+2 -1
drivers/gpu/drm/scheduler/sched_main.c
··· 1355 1355 * drm_sched_backend_ops.run_job(). Consequently, drm_sched_backend_ops.free_job() 1356 1356 * will not be called for all jobs still in drm_gpu_scheduler.pending_list. 1357 1357 * There is no solution for this currently. Thus, it is up to the driver to make 1358 - * sure that 1358 + * sure that: 1359 + * 1359 1360 * a) drm_sched_fini() is only called after for all submitted jobs 1360 1361 * drm_sched_backend_ops.free_job() has been called or that 1361 1362 * b) the jobs for which drm_sched_backend_ops.free_job() has not been called
+1 -1
drivers/gpu/drm/sti/sti_hdmi.c
··· 1237 1237 .audio_shutdown = hdmi_audio_shutdown, 1238 1238 .mute_stream = hdmi_audio_mute, 1239 1239 .get_eld = hdmi_audio_get_eld, 1240 - .no_capture_mute = 1, 1241 1240 }; 1242 1241 1243 1242 static int sti_hdmi_register_audio_driver(struct device *dev, ··· 1246 1247 .ops = &audio_codec_ops, 1247 1248 .max_i2s_channels = 8, 1248 1249 .i2s = 1, 1250 + .no_capture_mute = 1, 1249 1251 }; 1250 1252 1251 1253 DRM_DEBUG_DRIVER("\n");
+1
drivers/gpu/drm/vc4/Kconfig
··· 10 10 depends on COMMON_CLK 11 11 depends on PM 12 12 select DRM_CLIENT_SELECTION 13 + select DRM_DISPLAY_HDMI_AUDIO_HELPER 13 14 select DRM_DISPLAY_HDMI_HELPER 14 15 select DRM_DISPLAY_HDMI_STATE_HELPER 15 16 select DRM_DISPLAY_HELPER
+22 -82
drivers/gpu/drm/vc4/vc4_hdmi.c
··· 31 31 * encoder block has CEC support. 32 32 */ 33 33 34 + #include <drm/display/drm_hdmi_audio_helper.h> 34 35 #include <drm/display/drm_hdmi_helper.h> 35 36 #include <drm/display/drm_hdmi_state_helper.h> 36 37 #include <drm/display/drm_scdc_helper.h> ··· 384 383 enum drm_connector_status status) 385 384 { 386 385 struct drm_connector *connector = &vc4_hdmi->connector; 387 - const struct drm_edid *drm_edid; 388 386 int ret; 389 387 390 388 /* ··· 405 405 return; 406 406 } 407 407 408 - drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc); 408 + drm_atomic_helper_connector_hdmi_hotplug(connector, status); 409 409 410 - drm_edid_connector_update(connector, drm_edid); 411 410 cec_s_phys_addr(vc4_hdmi->cec_adap, 412 411 connector->display_info.source_physical_address, false); 413 412 414 - if (!drm_edid) 413 + if (status != connector_status_connected) 415 414 return; 416 - 417 - drm_edid_free(drm_edid); 418 415 419 416 for (;;) { 420 417 ret = vc4_hdmi_reset_link(connector, ctx); ··· 467 470 468 471 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) 469 472 { 470 - struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); 471 473 struct vc4_dev *vc4 = to_vc4_dev(connector->dev); 472 - const struct drm_edid *drm_edid; 473 474 int ret = 0; 474 475 475 - /* 476 - * NOTE: This function should really take vc4_hdmi->mutex, but doing so 477 - * results in reentrancy issues since cec_s_phys_addr() might call 478 - * .adap_enable, which leads to that funtion being called with our mutex 479 - * held. 480 - * 481 - * Concurrency isn't an issue at the moment since we don't share 482 - * any state with any of the other frameworks so we can ignore 483 - * the lock for now. 484 - */ 485 - 486 - drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc); 487 - drm_edid_connector_update(connector, drm_edid); 488 - cec_s_phys_addr(vc4_hdmi->cec_adap, 489 - connector->display_info.source_physical_address, false); 490 - if (!drm_edid) 491 - return 0; 492 - 493 476 ret = drm_edid_connector_add_modes(connector); 494 - drm_edid_free(drm_edid); 495 477 496 478 if (!vc4->hvs->vc5_hdmi_enable_hdmi_20) { 497 479 struct drm_device *drm = connector->dev; ··· 546 570 } 547 571 548 572 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { 573 + .force = drm_atomic_helper_connector_hdmi_force, 549 574 .fill_modes = drm_helper_probe_single_connector_modes, 550 575 .reset = vc4_hdmi_connector_reset, 551 576 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, ··· 561 584 }; 562 585 563 586 static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs; 587 + static const struct drm_connector_hdmi_audio_funcs vc4_hdmi_audio_funcs; 564 588 565 589 static int vc4_hdmi_connector_init(struct drm_device *dev, 566 590 struct vc4_hdmi *vc4_hdmi) ··· 584 606 BIT(HDMI_COLORSPACE_YUV422) | 585 607 BIT(HDMI_COLORSPACE_YUV444), 586 608 max_bpc); 609 + if (ret) 610 + return ret; 611 + 612 + ret = drm_connector_hdmi_audio_init(connector, dev->dev, 613 + &vc4_hdmi_audio_funcs, 614 + 8, false, -1); 587 615 if (ret) 588 616 return ret; 589 617 ··· 1905 1921 return true; 1906 1922 } 1907 1923 1908 - static int vc4_hdmi_audio_startup(struct device *dev, void *data) 1924 + static int vc4_hdmi_audio_startup(struct drm_connector *connector) 1909 1925 { 1910 - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); 1926 + struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); 1911 1927 struct drm_device *drm = vc4_hdmi->connector.dev; 1912 1928 unsigned long flags; 1913 1929 int ret = 0; ··· 1969 1985 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 1970 1986 } 1971 1987 1972 - static void vc4_hdmi_audio_shutdown(struct device *dev, void *data) 1988 + static void vc4_hdmi_audio_shutdown(struct drm_connector *connector) 1973 1989 { 1974 - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); 1990 + struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); 1975 1991 struct drm_device *drm = vc4_hdmi->connector.dev; 1976 1992 unsigned long flags; 1977 1993 int idx; ··· 2041 2057 } 2042 2058 2043 2059 /* HDMI audio codec callbacks */ 2044 - static int vc4_hdmi_audio_prepare(struct device *dev, void *data, 2060 + static int vc4_hdmi_audio_prepare(struct drm_connector *connector, 2045 2061 struct hdmi_codec_daifmt *daifmt, 2046 2062 struct hdmi_codec_params *params) 2047 2063 { 2048 - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); 2064 + struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); 2049 2065 struct drm_device *drm = vc4_hdmi->connector.dev; 2050 - struct drm_connector *connector = &vc4_hdmi->connector; 2051 2066 struct vc4_dev *vc4 = to_vc4_dev(drm); 2052 2067 unsigned int sample_rate = params->sample_rate; 2053 2068 unsigned int channels = params->channels; ··· 2058 2075 int ret = 0; 2059 2076 int idx; 2060 2077 2061 - dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__, 2078 + dev_dbg(&vc4_hdmi->pdev->dev, "%s: %u Hz, %d bit, %d channels\n", __func__, 2062 2079 sample_rate, params->sample_width, channels); 2063 2080 2064 2081 mutex_lock(&vc4_hdmi->mutex); ··· 2197 2214 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, 2198 2215 }; 2199 2216 2200 - static int vc4_hdmi_audio_get_eld(struct device *dev, void *data, 2201 - uint8_t *buf, size_t len) 2202 - { 2203 - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); 2204 - struct drm_connector *connector = &vc4_hdmi->connector; 2205 - 2206 - mutex_lock(&connector->eld_mutex); 2207 - memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); 2208 - mutex_unlock(&connector->eld_mutex); 2209 - 2210 - return 0; 2211 - } 2212 - 2213 - static const struct hdmi_codec_ops vc4_hdmi_codec_ops = { 2214 - .get_eld = vc4_hdmi_audio_get_eld, 2217 + static const struct drm_connector_hdmi_audio_funcs vc4_hdmi_audio_funcs = { 2218 + .startup = vc4_hdmi_audio_startup, 2215 2219 .prepare = vc4_hdmi_audio_prepare, 2216 - .audio_shutdown = vc4_hdmi_audio_shutdown, 2217 - .audio_startup = vc4_hdmi_audio_startup, 2220 + .shutdown = vc4_hdmi_audio_shutdown, 2218 2221 }; 2219 - 2220 - static struct hdmi_codec_pdata vc4_hdmi_codec_pdata = { 2221 - .ops = &vc4_hdmi_codec_ops, 2222 - .max_i2s_channels = 8, 2223 - .i2s = 1, 2224 - }; 2225 - 2226 - static void vc4_hdmi_audio_codec_release(void *ptr) 2227 - { 2228 - struct vc4_hdmi *vc4_hdmi = ptr; 2229 - 2230 - platform_device_unregister(vc4_hdmi->audio.codec_pdev); 2231 - vc4_hdmi->audio.codec_pdev = NULL; 2232 - } 2233 2222 2234 2223 static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) 2235 2224 { ··· 2210 2255 struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link; 2211 2256 struct snd_soc_card *card = &vc4_hdmi->audio.card; 2212 2257 struct device *dev = &vc4_hdmi->pdev->dev; 2213 - struct platform_device *codec_pdev; 2214 2258 const __be32 *addr; 2215 2259 int index, len; 2216 2260 int ret; ··· 2302 2348 return ret; 2303 2349 } 2304 2350 2305 - codec_pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME, 2306 - PLATFORM_DEVID_AUTO, 2307 - &vc4_hdmi_codec_pdata, 2308 - sizeof(vc4_hdmi_codec_pdata)); 2309 - if (IS_ERR(codec_pdev)) { 2310 - dev_err(dev, "Couldn't register the HDMI codec: %ld\n", PTR_ERR(codec_pdev)); 2311 - return PTR_ERR(codec_pdev); 2312 - } 2313 - vc4_hdmi->audio.codec_pdev = codec_pdev; 2314 - 2315 - ret = devm_add_action_or_reset(dev, vc4_hdmi_audio_codec_release, vc4_hdmi); 2316 - if (ret) 2317 - return ret; 2318 - 2319 2351 dai_link->cpus = &vc4_hdmi->audio.cpu; 2320 2352 dai_link->codecs = &vc4_hdmi->audio.codec; 2321 2353 dai_link->platforms = &vc4_hdmi->audio.platform; ··· 2314 2374 dai_link->stream_name = "MAI PCM"; 2315 2375 dai_link->codecs->dai_name = "i2s-hifi"; 2316 2376 dai_link->cpus->dai_name = dev_name(dev); 2317 - dai_link->codecs->name = dev_name(&codec_pdev->dev); 2377 + dai_link->codecs->name = dev_name(&vc4_hdmi->connector.hdmi_audio.codec_pdev->dev); 2318 2378 dai_link->platforms->name = dev_name(dev); 2319 2379 2320 2380 card->dai_link = dai_link;
-2
drivers/gpu/drm/vc4/vc4_hdmi.h
··· 104 104 struct snd_soc_dai_link_component codec; 105 105 struct snd_soc_dai_link_component platform; 106 106 struct snd_dmaengine_dai_dma_data dma_data; 107 - struct hdmi_audio_infoframe infoframe; 108 - struct platform_device *codec_pdev; 109 107 bool streaming; 110 108 }; 111 109
+1
drivers/gpu/drm/xe/xe_drm_client.c
··· 261 261 if (man) { 262 262 drm_print_memory_stats(p, 263 263 &stats[mem_type], 264 + DRM_GEM_OBJECT_ACTIVE | 264 265 DRM_GEM_OBJECT_RESIDENT | 265 266 (mem_type != XE_PL_SYSTEM ? 0 : 266 267 DRM_GEM_OBJECT_PURGEABLE),
+22
include/drm/display/drm_hdmi_audio_helper.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + 3 + #ifndef DRM_DISPLAY_HDMI_AUDIO_HELPER_H_ 4 + #define DRM_DISPLAY_HDMI_AUDIO_HELPER_H_ 5 + 6 + #include <linux/types.h> 7 + 8 + struct drm_connector; 9 + struct drm_connector_hdmi_audio_funcs; 10 + 11 + struct device; 12 + 13 + int drm_connector_hdmi_audio_init(struct drm_connector *connector, 14 + struct device *hdmi_codec_dev, 15 + const struct drm_connector_hdmi_audio_funcs *funcs, 16 + unsigned int max_i2s_playback_channels, 17 + bool spdif_playback, 18 + int sound_dai_port); 19 + void drm_connector_hdmi_audio_plugged_notify(struct drm_connector *connector, 20 + bool plugged); 21 + 22 + #endif
+5
include/drm/display/drm_hdmi_state_helper.h
··· 8 8 struct drm_connector_state; 9 9 struct hdmi_audio_infoframe; 10 10 11 + enum drm_connector_status; 12 + 11 13 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, 12 14 struct drm_connector_state *new_conn_state); 13 15 ··· 21 19 int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector); 22 20 int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, 23 21 struct drm_atomic_state *state); 22 + void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector, 23 + enum drm_connector_status status); 24 + void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector); 24 25 25 26 enum drm_mode_status 26 27 drm_hdmi_connector_mode_valid(struct drm_connector *connector,
+74
include/drm/drm_bridge.h
··· 41 41 struct drm_minor; 42 42 struct drm_panel; 43 43 struct edid; 44 + struct hdmi_codec_daifmt; 45 + struct hdmi_codec_params; 44 46 struct i2c_adapter; 45 47 46 48 /** ··· 679 677 const u8 *buffer, size_t len); 680 678 681 679 /** 680 + * @hdmi_audio_startup: 681 + * 682 + * Called when ASoC starts an audio stream setup. The 683 + * @hdmi_audio_startup() is optional. 684 + * 685 + * Returns: 686 + * 0 on success, a negative error code otherwise 687 + */ 688 + int (*hdmi_audio_startup)(struct drm_connector *connector, 689 + struct drm_bridge *bridge); 690 + 691 + /** 692 + * @prepare: 693 + * Configures HDMI-encoder for audio stream. Can be called multiple 694 + * times for each setup. Mandatory if HDMI audio is enabled in the 695 + * bridge's configuration. 696 + * 697 + * Returns: 698 + * 0 on success, a negative error code otherwise 699 + */ 700 + int (*hdmi_audio_prepare)(struct drm_connector *connector, 701 + struct drm_bridge *bridge, 702 + struct hdmi_codec_daifmt *fmt, 703 + struct hdmi_codec_params *hparms); 704 + 705 + /** 706 + * @hdmi_audio_shutdown: 707 + * 708 + * Shut down the audio stream. Mandatory if HDMI audio is enabled in 709 + * the bridge's configuration. 710 + * 711 + * Returns: 712 + * 0 on success, a negative error code otherwise 713 + */ 714 + void (*hdmi_audio_shutdown)(struct drm_connector *connector, 715 + struct drm_bridge *bridge); 716 + 717 + /** 718 + * @hdmi_audio_mute_stream: 719 + * 720 + * Mute/unmute HDMI audio stream. The @hdmi_audio_mute_stream callback 721 + * is optional. 722 + * 723 + * Returns: 724 + * 0 on success, a negative error code otherwise 725 + */ 726 + int (*hdmi_audio_mute_stream)(struct drm_connector *connector, 727 + struct drm_bridge *bridge, 728 + bool enable, int direction); 729 + 730 + /** 682 731 * @debugfs_init: 683 732 * 684 733 * Allows bridges to create bridge-specific debugfs files. ··· 912 859 * @DRM_BRIDGE_OP_HDMI is set. 913 860 */ 914 861 unsigned int max_bpc; 862 + 863 + /** 864 + * @hdmi_audio_dev: device to be used as a parent for the HDMI Codec 865 + */ 866 + struct device *hdmi_audio_dev; 867 + 868 + /** 869 + * @hdmi_audio_max_i2s_playback_channels: maximum number of playback 870 + * I2S channels for the HDMI codec 871 + */ 872 + int hdmi_audio_max_i2s_playback_channels; 873 + 874 + /** 875 + * @hdmi_audio_spdif_playback: set if HDMI codec has S/PDIF playback port 876 + */ 877 + unsigned int hdmi_audio_spdif_playback : 1; 878 + 879 + /** 880 + * @hdmi_audio_dai_port: sound DAI port, -1 if it is not enabled 881 + */ 882 + int hdmi_audio_dai_port; 915 883 }; 916 884 917 885 static inline struct drm_bridge *
+132
include/drm/drm_connector.h
··· 45 45 struct drm_property_blob; 46 46 struct drm_printer; 47 47 struct drm_privacy_screen; 48 + struct drm_edid; 48 49 struct edid; 50 + struct hdmi_codec_daifmt; 51 + struct hdmi_codec_params; 49 52 struct i2c_adapter; 50 53 51 54 enum drm_connector_force { ··· 1144 1141 struct drm_connector_hdmi_state hdmi; 1145 1142 }; 1146 1143 1144 + struct drm_connector_hdmi_audio_funcs { 1145 + /** 1146 + * @startup: 1147 + * 1148 + * Called when ASoC starts an audio stream setup. The 1149 + * @startup() is optional. 1150 + * 1151 + * Returns: 1152 + * 0 on success, a negative error code otherwise 1153 + */ 1154 + int (*startup)(struct drm_connector *connector); 1155 + 1156 + /** 1157 + * @prepare: 1158 + * Configures HDMI-encoder for audio stream. Can be called 1159 + * multiple times for each setup. Mandatory. 1160 + * 1161 + * Returns: 1162 + * 0 on success, a negative error code otherwise 1163 + */ 1164 + int (*prepare)(struct drm_connector *connector, 1165 + struct hdmi_codec_daifmt *fmt, 1166 + struct hdmi_codec_params *hparms); 1167 + 1168 + /** 1169 + * @shutdown: 1170 + * 1171 + * Shut down the audio stream. Mandatory. 1172 + * 1173 + * Returns: 1174 + * 0 on success, a negative error code otherwise 1175 + */ 1176 + void (*shutdown)(struct drm_connector *connector); 1177 + 1178 + /** 1179 + * @mute_stream: 1180 + * 1181 + * Mute/unmute HDMI audio stream. The @mute_stream callback is 1182 + * optional. 1183 + * 1184 + * Returns: 1185 + * 0 on success, a negative error code otherwise 1186 + */ 1187 + int (*mute_stream)(struct drm_connector *connector, 1188 + bool enable, int direction); 1189 + }; 1190 + 1147 1191 /** 1148 1192 * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions 1149 1193 */ ··· 1248 1198 int (*write_infoframe)(struct drm_connector *connector, 1249 1199 enum hdmi_infoframe_type type, 1250 1200 const u8 *buffer, size_t len); 1201 + 1202 + /** 1203 + * @read_edid: 1204 + * 1205 + * This callback is used by the framework as a replacement for reading 1206 + * the EDID from connector->ddc. It is still recommended to provide 1207 + * connector->ddc instead of implementing this callback. Returned EDID 1208 + * should be freed via the drm_edid_free(). 1209 + * 1210 + * The @read_edid callback is optional. 1211 + * 1212 + * Returns: 1213 + * Valid EDID on success, NULL in case of failure. 1214 + */ 1215 + const struct drm_edid *(*read_edid)(struct drm_connector *connector); 1251 1216 }; 1252 1217 1253 1218 /** ··· 1723 1658 * Did the mode have a preferred TV mode? 1724 1659 */ 1725 1660 bool tv_mode_specified; 1661 + }; 1662 + 1663 + /** 1664 + * struct drm_connector_hdmi_audio - DRM gemeric HDMI Codec-related structure 1665 + * 1666 + * HDMI drivers usually incorporate a HDMI Codec. This structure expresses the 1667 + * generic HDMI Codec as used by the DRM HDMI Codec framework. 1668 + */ 1669 + struct drm_connector_hdmi_audio { 1670 + /** 1671 + * @funcs: 1672 + * 1673 + * Implementation of the HDMI codec functionality to be used by the DRM 1674 + * HDMI Codec framework. 1675 + */ 1676 + const struct drm_connector_hdmi_audio_funcs *funcs; 1677 + 1678 + /** 1679 + * @codec_pdev: 1680 + * 1681 + * Platform device created to hold the HDMI Codec. It will be 1682 + * automatically unregistered during drm_connector_cleanup(). 1683 + */ 1684 + struct platform_device *codec_pdev; 1685 + 1686 + /** 1687 + * @lock: 1688 + * 1689 + * Mutex to protect @last_state, @plugged_cb and @plugged_cb_dev. 1690 + */ 1691 + struct mutex lock; 1692 + 1693 + /** 1694 + * @plugged_cb: 1695 + * 1696 + * Callback to be called when the HDMI sink get plugged to or unplugged 1697 + * from this connector. This is assigned by the framework when 1698 + * requested by the ASoC code. 1699 + */ 1700 + void (*plugged_cb)(struct device *dev, bool plugged); 1701 + 1702 + /** 1703 + * @plugged_cb_dev: 1704 + * 1705 + * The data for @plugged_cb(). It is being provided by the ASoC. 1706 + */ 1707 + struct device *plugged_cb_dev; 1708 + 1709 + /** 1710 + * @last_state: 1711 + * 1712 + * Last plugged state recored by the framework. It is used to correctly 1713 + * report the state to @plugged_cb(). 1714 + */ 1715 + bool last_state; 1716 + 1717 + /** 1718 + * @dai_port: 1719 + * 1720 + * The port in DT that is used for the Codec DAI. 1721 + */ 1722 + int dai_port; 1726 1723 }; 1727 1724 1728 1725 /* ··· 2248 2121 * @hdmi: HDMI-related variable and properties. 2249 2122 */ 2250 2123 struct drm_connector_hdmi hdmi; 2124 + 2125 + /** 2126 + * @hdmi_audio: HDMI codec properties and non-DRM state. 2127 + */ 2128 + struct drm_connector_hdmi_audio hdmi_audio; 2251 2129 }; 2252 2130 2253 2131 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
+1
include/drm/drm_file.h
··· 494 494 495 495 enum drm_gem_object_status; 496 496 497 + int drm_memory_stats_is_zero(const struct drm_memory_stats *stats); 497 498 void drm_print_memory_stats(struct drm_printer *p, 498 499 const struct drm_memory_stats *stats, 499 500 enum drm_gem_object_status supported_status,
+8 -6
include/drm/drm_gem.h
··· 48 48 * enum drm_gem_object_status - bitmask of object state for fdinfo reporting 49 49 * @DRM_GEM_OBJECT_RESIDENT: object is resident in memory (ie. not unpinned) 50 50 * @DRM_GEM_OBJECT_PURGEABLE: object marked as purgeable by userspace 51 + * @DRM_GEM_OBJECT_ACTIVE: object is currently used by an active submission 51 52 * 52 53 * Bitmask of status used for fdinfo memory stats, see &drm_gem_object_funcs.status 53 - * and drm_show_fdinfo(). Note that an object can DRM_GEM_OBJECT_PURGEABLE if 54 - * it still active or not resident, in which case drm_show_fdinfo() will not 54 + * and drm_show_fdinfo(). Note that an object can report DRM_GEM_OBJECT_PURGEABLE 55 + * and be active or not resident, in which case drm_show_fdinfo() will not 55 56 * account for it as purgeable. So drivers do not need to check if the buffer 56 - * is idle and resident to return this bit. (Ie. userspace can mark a buffer 57 - * as purgeable even while it is still busy on the GPU.. it does not _actually_ 58 - * become puregeable until it becomes idle. The status gem object func does 59 - * not need to consider this.) 57 + * is idle and resident to return this bit, i.e. userspace can mark a buffer as 58 + * purgeable even while it is still busy on the GPU. It will not get reported in 59 + * the puregeable stats until it becomes idle. The status gem object func does 60 + * not need to consider this. 60 61 */ 61 62 enum drm_gem_object_status { 62 63 DRM_GEM_OBJECT_RESIDENT = BIT(0), 63 64 DRM_GEM_OBJECT_PURGEABLE = BIT(1), 65 + DRM_GEM_OBJECT_ACTIVE = BIT(2), 64 66 }; 65 67 66 68 /**
+3 -4
include/sound/hdmi-codec.h
··· 105 105 * Optional 106 106 */ 107 107 int (*get_dai_id)(struct snd_soc_component *comment, 108 - struct device_node *endpoint); 108 + struct device_node *endpoint, 109 + void *data); 109 110 110 111 /* 111 112 * Hook callback function to handle connector plug event. ··· 115 114 int (*hook_plugged_cb)(struct device *dev, void *data, 116 115 hdmi_codec_plugged_cb fn, 117 116 struct device *codec_dev); 118 - 119 - /* bit field */ 120 - unsigned int no_capture_mute:1; 121 117 }; 122 118 123 119 /* HDMI codec initalization data */ ··· 126 128 uint spdif:1; 127 129 uint no_spdif_playback:1; 128 130 uint no_spdif_capture:1; 131 + uint no_capture_mute:1; 129 132 int max_i2s_channels; 130 133 void *data; 131 134 };
+2 -2
sound/soc/codecs/hdmi-codec.c
··· 714 714 */ 715 715 if (hcp->hcd.ops->mute_stream && 716 716 (direction == SNDRV_PCM_STREAM_PLAYBACK || 717 - !hcp->hcd.ops->no_capture_mute)) 717 + !hcp->hcd.no_capture_mute)) 718 718 return hcp->hcd.ops->mute_stream(dai->dev->parent, 719 719 hcp->hcd.data, 720 720 mute, direction); ··· 995 995 int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */ 996 996 997 997 if (hcp->hcd.ops->get_dai_id) 998 - ret = hcp->hcd.ops->get_dai_id(component, endpoint); 998 + ret = hcp->hcd.ops->get_dai_id(component, endpoint, hcp->hcd.data); 999 999 1000 1000 return ret; 1001 1001 }