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

Configure Feed

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

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

drm-misc-next for 6.20:

Core Changes:

- atomic: Introduce Gamma/Degamma LUT size check
- gem: Fix a leak in drm_gem_get_unmapped_area
- gpuvm: API sanitation for Rust bindings
- panic: Few corner-cases fixes

Driver Changes:

- Replace system workqueue with percpu equivalent

- amdxdna: Update message buffer allocation requirements, Update
firmware version check
- imagination: Add AM62P support
- ivpu: Implement warm boot flow
- rockchip: Get rid of atomic_check fixups, Add Rockchip RK3506 Support
- rocket: Cleanups

- bridge:
- dw-hdmi-qp: Add support for HPD-less setups
- panel:
- mantix: Various power management related improvements
- new panels: Innolux G150XGE-L05,

- dma-buf:
- cma: Call clear_page instead of memset

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

From: Maxime Ripard <mripard@redhat.com>
Link: https://patch.msgid.link/20260115-lilac-dragon-of-opposition-ac0a30@houat

+882 -382
+5 -1
Documentation/devicetree/bindings/display/panel/panel-simple.yaml
··· 178 178 - innolux,g121x1-l03 179 179 # Innolux Corporation 12.1" G121XCE-L01 XGA (1024x768) TFT LCD panel 180 180 - innolux,g121xce-l01 181 + # InnoLux 15.0" G150XGE-L05 XGA (1024x768) TFT LCD panel 182 + - innolux,g150xge-l05 181 183 # InnoLux 15.6" FHD (1920x1080) TFT LCD panel 182 184 - innolux,g156hce-l01 183 185 # InnoLux 13.3" FHD (1920x1080) TFT LCD panel ··· 351 349 properties: 352 350 compatible: 353 351 contains: 354 - const: innolux,g101ice-l01 352 + enum: 353 + - innolux,g101ice-l01 354 + - yes-optoelectronics,ytc700tlag-05-201c 355 355 then: 356 356 properties: 357 357 data-mapping: false
+2
Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml
··· 19 19 - rockchip,rk3288-mipi-dsi 20 20 - rockchip,rk3368-mipi-dsi 21 21 - rockchip,rk3399-mipi-dsi 22 + - rockchip,rk3506-mipi-dsi 22 23 - rockchip,rk3568-mipi-dsi 23 24 - rockchip,rv1126-mipi-dsi 24 25 - const: snps,dw-mipi-dsi ··· 76 75 - rockchip,px30-mipi-dsi 77 76 - rockchip,rk3128-mipi-dsi 78 77 - rockchip,rk3368-mipi-dsi 78 + - rockchip,rk3506-mipi-dsi 79 79 - rockchip,rk3568-mipi-dsi 80 80 - rockchip,rv1126-mipi-dsi 81 81
+6
Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
··· 69 69 - const: main 70 70 - const: hpd 71 71 72 + no-hpd: 73 + type: boolean 74 + description: 75 + The HPD pin is not present or used for another purpose, and the EDID 76 + must be polled instead to determine if a device is attached. 77 + 72 78 phys: 73 79 maxItems: 1 74 80 description: The HDMI/eDP PHY
+1
Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
··· 31 31 - rockchip,rk3368-vop 32 32 - rockchip,rk3399-vop-big 33 33 - rockchip,rk3399-vop-lit 34 + - rockchip,rk3506-vop 34 35 - rockchip,rv1126-vop 35 36 36 37 reg:
+14
Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml
··· 51 51 - stacks 52 52 - const: stacks 53 53 54 + nvmem-cells: 55 + items: 56 + - description: bitmask of functional shader cores 57 + 58 + nvmem-cell-names: 59 + items: 60 + - const: shader-present 61 + 54 62 mali-supply: true 55 63 56 64 operating-points-v2: true ··· 116 108 properties: 117 109 clocks: 118 110 minItems: 3 111 + nvmem-cells: false 112 + nvmem-cell-names: false 119 113 power-domains: 120 114 maxItems: 1 121 115 power-domain-names: false ··· 143 133 - const: core 144 134 - const: stacks 145 135 required: 136 + - nvmem-cells 137 + - nvmem-cell-names 146 138 - power-domains 147 139 148 140 examples: ··· 191 179 <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH 0>, 192 180 <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH 0>; 193 181 interrupt-names = "job", "mmu", "gpu"; 182 + nvmem-cells = <&shader_present>; 183 + nvmem-cell-names = "shader-present"; 194 184 power-domains = <&gpufreq>; 195 185 }; 196 186
+2
Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml
··· 40 40 - const: img,img-rogue 41 41 - items: 42 42 - enum: 43 + - ti,am62p-gpu 43 44 - ti,j721s2-gpu 44 45 - const: img,img-bxs-4-64 45 46 - const: img,img-rogue ··· 101 100 contains: 102 101 enum: 103 102 - ti,am62-gpu 103 + - ti,am62p-gpu 104 104 - ti,j721s2-gpu 105 105 then: 106 106 properties:
+11
MAINTAINERS
··· 8780 8780 F: drivers/gpu/drm/ttm/ 8781 8781 F: include/drm/ttm/ 8782 8782 8783 + DRM BUDDY ALLOCATOR 8784 + M: Matthew Auld <matthew.auld@intel.com> 8785 + M: Arun Pravin <arunpravin.paneerselvam@amd.com> 8786 + R: Christian Koenig <christian.koenig@amd.com> 8787 + L: dri-devel@lists.freedesktop.org 8788 + S: Maintained 8789 + T: git https://gitlab.freedesktop.org/drm/misc/kernel.git 8790 + F: drivers/gpu/drm/drm_buddy.c 8791 + F: drivers/gpu/drm/tests/drm_buddy_test.c 8792 + F: include/drm/drm_buddy.h 8793 + 8783 8794 DRM AUTOMATED TESTING 8784 8795 M: Helen Koike <helen.fornazier@gmail.com> 8785 8796 M: Vignesh Raman <vignesh.raman@collabora.com>
+4 -6
drivers/accel/amdxdna/aie2_error.c
··· 338 338 destroy_workqueue(events->wq); 339 339 mutex_lock(&xdna->dev_lock); 340 340 341 - dma_free_noncoherent(xdna->ddev.dev, events->size, events->buf, 342 - events->addr, DMA_FROM_DEVICE); 341 + aie2_free_msg_buffer(ndev, events->size, events->buf, events->addr); 343 342 kfree(events); 344 343 } 345 344 ··· 354 355 if (!events) 355 356 return -ENOMEM; 356 357 357 - events->buf = dma_alloc_noncoherent(xdna->ddev.dev, total_size, &events->addr, 358 - DMA_FROM_DEVICE, GFP_KERNEL); 358 + events->buf = aie2_alloc_msg_buffer(ndev, &total_size, &events->addr); 359 + 359 360 if (!events->buf) { 360 361 ret = -ENOMEM; 361 362 goto free_events; ··· 395 396 free_wq: 396 397 destroy_workqueue(events->wq); 397 398 free_buf: 398 - dma_free_noncoherent(xdna->ddev.dev, events->size, events->buf, 399 - events->addr, DMA_FROM_DEVICE); 399 + aie2_free_msg_buffer(ndev, events->size, events->buf, events->addr); 400 400 free_events: 401 401 kfree(events); 402 402 return ret;
+24 -9
drivers/accel/amdxdna/aie2_message.c
··· 55 55 return ret; 56 56 } 57 57 58 + void *aie2_alloc_msg_buffer(struct amdxdna_dev_hdl *ndev, u32 *size, 59 + dma_addr_t *dma_addr) 60 + { 61 + struct amdxdna_dev *xdna = ndev->xdna; 62 + int order; 63 + 64 + *size = max(*size, SZ_8K); 65 + order = get_order(*size); 66 + if (order > MAX_PAGE_ORDER) 67 + return NULL; 68 + *size = PAGE_SIZE << order; 69 + 70 + return dma_alloc_noncoherent(xdna->ddev.dev, *size, dma_addr, 71 + DMA_FROM_DEVICE, GFP_KERNEL); 72 + } 73 + 58 74 int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev) 59 75 { 60 76 DECLARE_AIE2_MSG(suspend, MSG_OP_SUSPEND); ··· 362 346 { 363 347 DECLARE_AIE2_MSG(aie_column_info, MSG_OP_QUERY_COL_STATUS); 364 348 struct amdxdna_dev *xdna = ndev->xdna; 349 + u32 buf_sz = size, aie_bitmap = 0; 365 350 struct amdxdna_client *client; 366 351 dma_addr_t dma_addr; 367 - u32 aie_bitmap = 0; 368 352 u8 *buff_addr; 369 353 int ret; 370 354 371 - buff_addr = dma_alloc_noncoherent(xdna->ddev.dev, size, &dma_addr, 372 - DMA_FROM_DEVICE, GFP_KERNEL); 355 + buff_addr = aie2_alloc_msg_buffer(ndev, &buf_sz, &dma_addr); 373 356 if (!buff_addr) 374 357 return -ENOMEM; 375 358 ··· 378 363 379 364 *cols_filled = 0; 380 365 req.dump_buff_addr = dma_addr; 381 - req.dump_buff_size = size; 366 + req.dump_buff_size = buf_sz; 382 367 req.num_cols = hweight32(aie_bitmap); 383 368 req.aie_bitmap = aie_bitmap; 384 369 ··· 406 391 *cols_filled = aie_bitmap; 407 392 408 393 fail: 409 - dma_free_noncoherent(xdna->ddev.dev, size, buff_addr, dma_addr, DMA_FROM_DEVICE); 394 + aie2_free_msg_buffer(ndev, buf_sz, buff_addr, dma_addr); 410 395 return ret; 411 396 } 412 397 ··· 417 402 DECLARE_AIE2_MSG(get_telemetry, MSG_OP_GET_TELEMETRY); 418 403 struct amdxdna_dev *xdna = ndev->xdna; 419 404 dma_addr_t dma_addr; 405 + u32 buf_sz = size; 420 406 u8 *addr; 421 407 int ret; 422 408 423 409 if (header->type >= MAX_TELEMETRY_TYPE) 424 410 return -EINVAL; 425 411 426 - addr = dma_alloc_noncoherent(xdna->ddev.dev, size, &dma_addr, 427 - DMA_FROM_DEVICE, GFP_KERNEL); 412 + addr = aie2_alloc_msg_buffer(ndev, &buf_sz, &dma_addr); 428 413 if (!addr) 429 414 return -ENOMEM; 430 415 431 416 req.buf_addr = dma_addr; 432 - req.buf_size = size; 417 + req.buf_size = buf_sz; 433 418 req.type = header->type; 434 419 435 420 drm_clflush_virt_range(addr, size); /* device can access */ ··· 455 440 header->minor = resp.minor; 456 441 457 442 free_buf: 458 - dma_free_noncoherent(xdna->ddev.dev, size, addr, dma_addr, DMA_FROM_DEVICE); 443 + aie2_free_msg_buffer(ndev, buf_sz, addr, dma_addr); 459 444 return ret; 460 445 } 461 446
+9 -27
drivers/accel/amdxdna/aie2_pci.c
··· 57 57 static int aie2_check_protocol(struct amdxdna_dev_hdl *ndev, u32 fw_major, u32 fw_minor) 58 58 { 59 59 const struct aie2_fw_feature_tbl *feature; 60 - struct amdxdna_dev *xdna = ndev->xdna; 60 + bool found = false; 61 61 62 - /* 63 - * The driver supported mailbox behavior is defined by 64 - * ndev->priv->protocol_major and protocol_minor. 65 - * 66 - * When protocol_major and fw_major are different, it means driver 67 - * and firmware are incompatible. 68 - */ 69 - if (ndev->priv->protocol_major != fw_major) { 70 - XDNA_ERR(xdna, "Incompatible firmware protocol major %d minor %d", 71 - fw_major, fw_minor); 72 - return -EINVAL; 73 - } 74 - 75 - /* 76 - * When protocol_minor is greater then fw_minor, that means driver 77 - * relies on operation the installed firmware does not support. 78 - */ 79 - if (ndev->priv->protocol_minor > fw_minor) { 80 - XDNA_ERR(xdna, "Firmware minor version smaller than supported"); 81 - return -EINVAL; 82 - } 83 - 84 - for (feature = ndev->priv->fw_feature_tbl; feature && feature->min_minor; 85 - feature++) { 62 + for (feature = ndev->priv->fw_feature_tbl; feature->major; feature++) { 63 + if (feature->major != fw_major) 64 + continue; 86 65 if (fw_minor < feature->min_minor) 87 66 continue; 88 67 if (feature->max_minor > 0 && fw_minor > feature->max_minor) 89 68 continue; 90 69 91 - set_bit(feature->feature, &ndev->feature_mask); 70 + ndev->feature_mask |= feature->features; 71 + 72 + /* firmware version matches one of the driver support entry */ 73 + found = true; 92 74 } 93 75 94 - return 0; 76 + return found ? 0 : -EOPNOTSUPP; 95 77 } 96 78 97 79 static void aie2_dump_chann_info_debug(struct amdxdna_dev_hdl *ndev)
+7 -3
drivers/accel/amdxdna/aie2_pci.h
··· 237 237 }; 238 238 239 239 struct aie2_fw_feature_tbl { 240 - enum aie2_fw_feature feature; 240 + u64 features; 241 + u32 major; 241 242 u32 max_minor; 242 243 u32 min_minor; 243 244 }; ··· 247 246 248 247 struct amdxdna_dev_priv { 249 248 const char *fw_path; 250 - u64 protocol_major; 251 - u64 protocol_minor; 252 249 const struct rt_config *rt_config; 253 250 const struct dpm_clk_freq *dpm_clk_tbl; 254 251 const struct aie2_fw_feature_tbl *fw_feature_tbl; ··· 335 336 int (*notify_cb)(void *, void __iomem *, size_t)); 336 337 int aie2_config_debug_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, 337 338 int (*notify_cb)(void *, void __iomem *, size_t)); 339 + void *aie2_alloc_msg_buffer(struct amdxdna_dev_hdl *ndev, u32 *size, 340 + dma_addr_t *dma_addr); 341 + #define aie2_free_msg_buffer(ndev, size, buff_addr, dma_addr) \ 342 + dma_free_noncoherent((ndev)->xdna->ddev.dev, size, buff_addr, \ 343 + dma_addr, DMA_FROM_DEVICE) 338 344 339 345 /* aie2_hwctx.c */ 340 346 int aie2_hwctx_init(struct amdxdna_hwctx *hwctx);
+1 -1
drivers/accel/amdxdna/amdxdna_pci_drv.c
··· 275 275 fs_reclaim_release(GFP_KERNEL); 276 276 } 277 277 278 - xdna->notifier_wq = alloc_ordered_workqueue("notifier_wq", 0); 278 + xdna->notifier_wq = alloc_ordered_workqueue("notifier_wq", WQ_MEM_RECLAIM); 279 279 if (!xdna->notifier_wq) 280 280 return -ENOMEM; 281 281
+3 -3
drivers/accel/amdxdna/npu1_regs.c
··· 6 6 #include <drm/amdxdna_accel.h> 7 7 #include <drm/drm_device.h> 8 8 #include <drm/gpu_scheduler.h> 9 + #include <linux/bits.h> 9 10 #include <linux/sizes.h> 10 11 11 12 #include "aie2_pci.h" ··· 66 65 }; 67 66 68 67 static const struct aie2_fw_feature_tbl npu1_fw_feature_table[] = { 69 - { .feature = AIE2_NPU_COMMAND, .min_minor = 8 }, 68 + { .major = 5, .min_minor = 7 }, 69 + { .features = BIT_U64(AIE2_NPU_COMMAND), .min_minor = 8 }, 70 70 { 0 } 71 71 }; 72 72 73 73 static const struct amdxdna_dev_priv npu1_dev_priv = { 74 74 .fw_path = "amdnpu/1502_00/npu.sbin", 75 - .protocol_major = 0x5, 76 - .protocol_minor = 0x7, 77 75 .rt_config = npu1_default_rt_cfg, 78 76 .dpm_clk_tbl = npu1_dpm_clk_table, 79 77 .fw_feature_tbl = npu1_fw_feature_table,
+6 -5
drivers/accel/amdxdna/npu4_regs.c
··· 6 6 #include <drm/amdxdna_accel.h> 7 7 #include <drm/drm_device.h> 8 8 #include <drm/gpu_scheduler.h> 9 + #include <linux/bits.h> 9 10 #include <linux/sizes.h> 10 11 11 12 #include "aie2_pci.h" ··· 89 88 }; 90 89 91 90 const struct aie2_fw_feature_tbl npu4_fw_feature_table[] = { 92 - { .feature = AIE2_NPU_COMMAND, .min_minor = 15 }, 93 - { .feature = AIE2_PREEMPT, .min_minor = 12 }, 94 - { .feature = AIE2_TEMPORAL_ONLY, .min_minor = 12 }, 91 + { .major = 6, .min_minor = 12 }, 92 + { .features = BIT_U64(AIE2_NPU_COMMAND), .major = 6, .min_minor = 15 }, 93 + { .features = BIT_U64(AIE2_PREEMPT), .major = 6, .min_minor = 12 }, 94 + { .features = BIT_U64(AIE2_TEMPORAL_ONLY), .major = 6, .min_minor = 12 }, 95 + { .features = GENMASK_ULL(AIE2_TEMPORAL_ONLY, AIE2_NPU_COMMAND), .major = 7 }, 95 96 { 0 } 96 97 }; 97 98 98 99 static const struct amdxdna_dev_priv npu4_dev_priv = { 99 100 .fw_path = "amdnpu/17f0_10/npu.sbin", 100 - .protocol_major = 0x6, 101 - .protocol_minor = 12, 102 101 .rt_config = npu4_default_rt_cfg, 103 102 .dpm_clk_tbl = npu4_dpm_clk_table, 104 103 .fw_feature_tbl = npu4_fw_feature_table,
-2
drivers/accel/amdxdna/npu5_regs.c
··· 64 64 65 65 static const struct amdxdna_dev_priv npu5_dev_priv = { 66 66 .fw_path = "amdnpu/17f0_11/npu.sbin", 67 - .protocol_major = 0x6, 68 - .protocol_minor = 12, 69 67 .rt_config = npu4_default_rt_cfg, 70 68 .dpm_clk_tbl = npu4_dpm_clk_table, 71 69 .fw_feature_tbl = npu4_fw_feature_table,
-2
drivers/accel/amdxdna/npu6_regs.c
··· 64 64 65 65 static const struct amdxdna_dev_priv npu6_dev_priv = { 66 66 .fw_path = "amdnpu/17f0_10/npu.sbin", 67 - .protocol_major = 0x6, 68 - .protocol_minor = 12, 69 67 .rt_config = npu4_default_rt_cfg, 70 68 .dpm_clk_tbl = npu4_dpm_clk_table, 71 69 .fw_feature_tbl = npu4_fw_feature_table,
+3 -1
drivers/accel/ivpu/ivpu_debugfs.c
··· 20 20 #include "ivpu_hw.h" 21 21 #include "ivpu_jsm_msg.h" 22 22 #include "ivpu_pm.h" 23 + #include "vpu_boot_api.h" 23 24 24 25 static inline struct ivpu_device *seq_to_ivpu(struct seq_file *s) 25 26 { ··· 97 96 { 98 97 struct ivpu_device *vdev = seq_to_ivpu(s); 99 98 100 - seq_printf(s, "%s\n", (vdev->pm->is_warmboot) ? "warmboot" : "coldboot"); 99 + seq_printf(s, "%s\n", (vdev->fw->last_boot_mode == VPU_BOOT_TYPE_WARMBOOT) ? 100 + "warm boot" : "cold boot"); 101 101 102 102 return 0; 103 103 }
+2 -2
drivers/accel/ivpu/ivpu_drv.c
··· 384 384 drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa)); 385 385 386 386 ivpu_fw_boot_params_setup(vdev, ivpu_bo_vaddr(vdev->fw->mem_bp)); 387 + vdev->fw->last_boot_mode = vdev->fw->next_boot_mode; 387 388 388 389 ret = ivpu_hw_boot_fw(vdev); 389 390 if (ret) { ··· 397 396 ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); 398 397 goto err_diagnose_failure; 399 398 } 400 - 401 399 ivpu_hw_irq_clear(vdev); 402 400 enable_irq(vdev->irq); 403 401 ivpu_hw_irq_enable(vdev); 404 402 ivpu_ipc_enable(vdev); 405 403 406 - if (ivpu_fw_is_cold_boot(vdev)) { 404 + if (!ivpu_fw_is_warm_boot(vdev)) { 407 405 ret = ivpu_pm_dct_init(vdev); 408 406 if (ret) 409 407 goto err_disable_ipc;
+6 -7
drivers/accel/ivpu/ivpu_fw.c
··· 300 300 fw->image_load_offset = image_load_addr - runtime_addr; 301 301 fw->image_size = image_size; 302 302 fw->shave_nn_size = PAGE_ALIGN(fw_hdr->shave_nn_fw_size); 303 - 304 303 fw->cold_boot_entry_point = fw_hdr->entry_point; 305 - fw->entry_point = fw->cold_boot_entry_point; 306 304 307 305 fw->trace_level = min_t(u32, ivpu_fw_log_level, IVPU_FW_LOG_FATAL); 308 306 fw->trace_destination_mask = VPU_TRACE_DESTINATION_VERBOSE_TRACING; ··· 336 338 fw->image_load_offset, fw->image_size); 337 339 ivpu_dbg(vdev, FW_BOOT, "Read-only section: address 0x%llx, size %u\n", 338 340 fw->read_only_addr, fw->read_only_size); 339 - ivpu_dbg(vdev, FW_BOOT, "FW entry point: 0x%llx\n", fw->entry_point); 341 + ivpu_dbg(vdev, FW_BOOT, "FW cold boot entry point: 0x%llx\n", fw->cold_boot_entry_point); 340 342 ivpu_dbg(vdev, FW_BOOT, "SHAVE NN size: %u\n", fw->shave_nn_size); 341 343 342 344 return 0; ··· 614 616 boot_params->power_profile); 615 617 ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_uses_ecc_mca_signal = 0x%x\n", 616 618 boot_params->vpu_uses_ecc_mca_signal); 619 + ivpu_dbg(vdev, FW_BOOT, "boot_params.boot_type = 0x%x\n", boot_params->boot_type); 617 620 } 618 621 619 622 void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *boot_params) ··· 622 623 struct ivpu_bo *ipc_mem_rx = vdev->ipc->mem_rx; 623 624 624 625 /* In case of warm boot only update variable params */ 625 - if (!ivpu_fw_is_cold_boot(vdev)) { 626 + if (ivpu_fw_is_warm_boot(vdev)) { 626 627 boot_params->d0i3_residency_time_us = 627 628 ktime_us_delta(ktime_get_boottime(), vdev->hw->d0i3_entry_host_ts); 628 629 boot_params->d0i3_entry_vpu_ts = vdev->hw->d0i3_entry_vpu_ts; ··· 634 635 boot_params->d0i3_entry_vpu_ts); 635 636 ivpu_dbg(vdev, FW_BOOT, "boot_params.system_time_us = %llu\n", 636 637 boot_params->system_time_us); 638 + ivpu_dbg(vdev, FW_BOOT, "boot_params.boot_type = 0x%x\n", boot_params->boot_type); 637 639 638 640 boot_params->save_restore_ret_address = 0; 639 - vdev->pm->is_warmboot = true; 641 + boot_params->boot_type = VPU_BOOT_TYPE_WARMBOOT; 640 642 wmb(); /* Flush WC buffers after writing save_restore_ret_address */ 641 643 return; 642 644 } 643 645 644 646 memset(boot_params, 0, sizeof(*boot_params)); 645 - vdev->pm->is_warmboot = false; 646 - 647 + boot_params->boot_type = VPU_BOOT_TYPE_COLDBOOT; 647 648 boot_params->magic = VPU_BOOT_PARAMS_MAGIC; 648 649 boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number; 649 650
+6 -3
drivers/accel/ivpu/ivpu_fw.h
··· 6 6 #ifndef __IVPU_FW_H__ 7 7 #define __IVPU_FW_H__ 8 8 9 + #include "vpu_boot_api.h" 9 10 #include "vpu_jsm_api.h" 10 11 11 12 #define FW_VERSION_HEADER_SIZE SZ_4K ··· 35 34 u64 image_load_offset; 36 35 u32 image_size; 37 36 u32 shave_nn_size; 38 - u64 entry_point; /* Cold or warm boot entry point for next boot */ 37 + u64 warm_boot_entry_point; 39 38 u64 cold_boot_entry_point; 39 + u8 last_boot_mode; 40 + u8 next_boot_mode; 40 41 u32 trace_level; 41 42 u32 trace_destination_mask; 42 43 u64 trace_hw_component_mask; ··· 57 54 void ivpu_fw_load(struct ivpu_device *vdev); 58 55 void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *boot_params); 59 56 60 - static inline bool ivpu_fw_is_cold_boot(struct ivpu_device *vdev) 57 + static inline bool ivpu_fw_is_warm_boot(struct ivpu_device *vdev) 61 58 { 62 - return vdev->fw->entry_point == vdev->fw->cold_boot_entry_point; 59 + return vdev->fw->next_boot_mode == VPU_BOOT_TYPE_WARMBOOT; 63 60 } 64 61 65 62 static inline u32 ivpu_fw_preempt_buf_size(struct ivpu_device *vdev)
+6
drivers/accel/ivpu/ivpu_hw_40xx_reg.h
··· 121 121 #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY 0x0003006cu 122 122 #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY_STATUS_DLY_MASK GENMASK(7, 0) 123 123 124 + #define VPU_40XX_HOST_SS_AON_RETENTION0 0x0003000cu 125 + #define VPU_40XX_HOST_SS_AON_RETENTION1 0x00030010u 126 + #define VPU_40XX_HOST_SS_AON_RETENTION2 0x00030014u 127 + #define VPU_40XX_HOST_SS_AON_RETENTION3 0x00030018u 128 + #define VPU_40XX_HOST_SS_AON_RETENTION4 0x0003001cu 129 + 124 130 #define VPU_40XX_HOST_SS_AON_IDLE_GEN 0x00030200u 125 131 #define VPU_40XX_HOST_SS_AON_IDLE_GEN_EN_MASK BIT_MASK(0) 126 132 #define VPU_40XX_HOST_SS_AON_IDLE_GEN_HW_PG_EN_MASK BIT_MASK(1)
+56 -28
drivers/accel/ivpu/ivpu_hw_ip.c
··· 5 5 6 6 #include "ivpu_drv.h" 7 7 #include "ivpu_fw.h" 8 + #include "ivpu_gem.h" 8 9 #include "ivpu_hw.h" 9 10 #include "ivpu_hw_37xx_reg.h" 10 11 #include "ivpu_hw_40xx_reg.h" ··· 817 816 return ivpu_hw_ip_tbu_mmu_enable_40xx(vdev); 818 817 } 819 818 819 + static inline u64 get_entry_point_addr(struct ivpu_device *vdev) 820 + { 821 + if (ivpu_fw_is_warm_boot(vdev)) 822 + return vdev->fw->warm_boot_entry_point; 823 + else 824 + return vdev->fw->cold_boot_entry_point; 825 + } 826 + 820 827 static int soc_cpu_boot_37xx(struct ivpu_device *vdev) 821 828 { 822 829 u32 val; ··· 841 832 val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val); 842 833 REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val); 843 834 844 - val = vdev->fw->entry_point >> 9; 835 + val = get_entry_point_addr(vdev) >> 9; 845 836 REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val); 846 837 847 838 val = REG_SET_FLD(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, DONE, val); 848 839 REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val); 849 - 850 - ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n", 851 - vdev->fw->entry_point == vdev->fw->cold_boot_entry_point ? "cold boot" : "resume"); 852 840 853 841 return 0; 854 842 } ··· 900 894 return ret; 901 895 } 902 896 903 - static int soc_cpu_enable(struct ivpu_device *vdev) 897 + static void soc_cpu_set_entry_point_40xx(struct ivpu_device *vdev, u64 entry_point) 904 898 { 905 - if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_60XX) 906 - return 0; 907 - 908 - return soc_cpu_drive_40xx(vdev, true); 909 - } 910 - 911 - static int soc_cpu_boot_40xx(struct ivpu_device *vdev) 912 - { 913 - int ret; 914 - u32 val; 915 899 u64 val64; 900 + u32 val; 916 901 917 - ret = soc_cpu_enable(vdev); 918 - if (ret) { 919 - ivpu_err(vdev, "Failed to enable SOC CPU: %d\n", ret); 920 - return ret; 921 - } 922 - 923 - val64 = vdev->fw->entry_point; 902 + val64 = entry_point; 924 903 val64 <<= ffs(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO_IMAGE_LOCATION_MASK) - 1; 925 904 REGV_WR64(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val64); 926 905 927 906 val = REGV_RD32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO); 928 907 val = REG_SET_FLD(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, DONE, val); 929 908 REGV_WR32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val); 909 + } 930 910 931 - ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n", 932 - ivpu_fw_is_cold_boot(vdev) ? "cold boot" : "resume"); 911 + static int soc_cpu_boot_40xx(struct ivpu_device *vdev) 912 + { 913 + int ret; 914 + 915 + ret = soc_cpu_drive_40xx(vdev, true); 916 + if (ret) { 917 + ivpu_err(vdev, "Failed to enable SOC CPU: %d\n", ret); 918 + return ret; 919 + } 920 + 921 + soc_cpu_set_entry_point_40xx(vdev, get_entry_point_addr(vdev)); 922 + 923 + return 0; 924 + } 925 + 926 + static int soc_cpu_boot_60xx(struct ivpu_device *vdev) 927 + { 928 + REGV_WR64(VPU_40XX_HOST_SS_AON_RETENTION1, vdev->fw->mem_bp->vpu_addr); 929 + soc_cpu_set_entry_point_40xx(vdev, vdev->fw->cold_boot_entry_point); 933 930 934 931 return 0; 935 932 } 936 933 937 934 int ivpu_hw_ip_soc_cpu_boot(struct ivpu_device *vdev) 938 935 { 939 - if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) 940 - return soc_cpu_boot_37xx(vdev); 941 - else 942 - return soc_cpu_boot_40xx(vdev); 936 + int ret; 937 + 938 + switch (ivpu_hw_ip_gen(vdev)) { 939 + case IVPU_HW_IP_37XX: 940 + ret = soc_cpu_boot_37xx(vdev); 941 + break; 942 + 943 + case IVPU_HW_IP_40XX: 944 + case IVPU_HW_IP_50XX: 945 + ret = soc_cpu_boot_40xx(vdev); 946 + break; 947 + 948 + default: 949 + ret = soc_cpu_boot_60xx(vdev); 950 + } 951 + 952 + if (ret) 953 + return ret; 954 + 955 + ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n", 956 + ivpu_fw_is_warm_boot(vdev) ? "warm boot" : "cold boot"); 957 + 958 + return 0; 943 959 } 944 960 945 961 static void wdt_disable_37xx(struct ivpu_device *vdev)
-1
drivers/accel/ivpu/ivpu_hw_ip.h
··· 29 29 void ivpu_hw_ip_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr); 30 30 void ivpu_hw_ip_irq_enable(struct ivpu_device *vdev); 31 31 void ivpu_hw_ip_irq_disable(struct ivpu_device *vdev); 32 - void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev); 33 32 void ivpu_hw_ip_fabric_req_override_enable_50xx(struct ivpu_device *vdev); 34 33 void ivpu_hw_ip_fabric_req_override_disable_50xx(struct ivpu_device *vdev); 35 34
+8 -5
drivers/accel/ivpu/ivpu_pm.c
··· 47 47 ivpu_ipc_reset(vdev); 48 48 ivpu_fw_log_reset(vdev); 49 49 ivpu_fw_load(vdev); 50 - fw->entry_point = fw->cold_boot_entry_point; 51 50 fw->last_heartbeat = 0; 51 + 52 + ivpu_dbg(vdev, FW_BOOT, "Cold boot entry point 0x%llx", vdev->fw->cold_boot_entry_point); 53 + fw->next_boot_mode = VPU_BOOT_TYPE_COLDBOOT; 52 54 } 53 55 54 56 static void ivpu_pm_prepare_warm_boot(struct ivpu_device *vdev) ··· 58 56 struct ivpu_fw_info *fw = vdev->fw; 59 57 struct vpu_boot_params *bp = ivpu_bo_vaddr(fw->mem_bp); 60 58 61 - if (!bp->save_restore_ret_address) { 59 + fw->warm_boot_entry_point = bp->save_restore_ret_address; 60 + if (!fw->warm_boot_entry_point) { 62 61 ivpu_pm_prepare_cold_boot(vdev); 63 62 return; 64 63 } 65 64 66 - ivpu_dbg(vdev, FW_BOOT, "Save/restore entry point %llx", bp->save_restore_ret_address); 67 - fw->entry_point = bp->save_restore_ret_address; 65 + ivpu_dbg(vdev, FW_BOOT, "Warm boot entry point 0x%llx", fw->warm_boot_entry_point); 66 + fw->next_boot_mode = VPU_BOOT_TYPE_WARMBOOT; 68 67 } 69 68 70 69 static int ivpu_suspend(struct ivpu_device *vdev) ··· 113 110 ivpu_hw_power_down(vdev); 114 111 pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot); 115 112 116 - if (!ivpu_fw_is_cold_boot(vdev)) { 113 + if (ivpu_fw_is_warm_boot(vdev)) { 117 114 ivpu_pm_prepare_cold_boot(vdev); 118 115 goto retry; 119 116 } else {
-1
drivers/accel/ivpu/ivpu_pm.h
··· 18 18 struct rw_semaphore reset_lock; 19 19 atomic_t reset_counter; 20 20 atomic_t reset_pending; 21 - bool is_warmboot; 22 21 u8 dct_active_percent; 23 22 }; 24 23
+5 -2
drivers/accel/rocket/rocket_core.c
··· 59 59 core->iommu_group = iommu_group_get(dev); 60 60 61 61 err = rocket_job_init(core); 62 - if (err) 62 + if (err) { 63 + iommu_group_put(core->iommu_group); 64 + core->iommu_group = NULL; 63 65 return err; 66 + } 64 67 65 68 pm_runtime_use_autosuspend(dev); 66 69 ··· 79 76 80 77 err = pm_runtime_resume_and_get(dev); 81 78 if (err) { 82 - rocket_job_fini(core); 79 + rocket_core_fini(core); 83 80 return err; 84 81 } 85 82
+22 -8
drivers/accel/rocket/rocket_drv.c
··· 13 13 #include <linux/platform_device.h> 14 14 #include <linux/pm_runtime.h> 15 15 16 + #include "rocket_device.h" 16 17 #include "rocket_drv.h" 17 18 #include "rocket_gem.h" 18 19 #include "rocket_job.h" ··· 159 158 160 159 static int rocket_probe(struct platform_device *pdev) 161 160 { 161 + int ret; 162 + 162 163 if (rdev == NULL) { 163 164 /* First core probing, initialize DRM device. */ 164 165 rdev = rocket_device_init(drm_dev, &rocket_drm_driver); ··· 180 177 181 178 rdev->num_cores++; 182 179 183 - return rocket_core_init(&rdev->cores[core]); 180 + ret = rocket_core_init(&rdev->cores[core]); 181 + if (ret) { 182 + rdev->num_cores--; 183 + 184 + if (rdev->num_cores == 0) { 185 + rocket_device_fini(rdev); 186 + rdev = NULL; 187 + } 188 + } 189 + 190 + return ret; 184 191 } 192 + 193 + static int find_core_for_dev(struct device *dev); 185 194 186 195 static void rocket_remove(struct platform_device *pdev) 187 196 { 188 197 struct device *dev = &pdev->dev; 198 + int core = find_core_for_dev(dev); 189 199 190 - for (unsigned int core = 0; core < rdev->num_cores; core++) { 191 - if (rdev->cores[core].dev == dev) { 192 - rocket_core_fini(&rdev->cores[core]); 193 - rdev->num_cores--; 194 - break; 195 - } 196 - } 200 + if (core < 0) 201 + return; 202 + 203 + rocket_core_fini(&rdev->cores[core]); 204 + rdev->num_cores--; 197 205 198 206 if (rdev->num_cores == 0) { 199 207 /* Last core removed, deinitialize DRM device. */
+1 -3
drivers/crypto/tegra/tegra-se-main.c
··· 401 401 return host1x_device_init(dev); 402 402 } 403 403 404 - static int tegra_se_host1x_remove(struct host1x_device *dev) 404 + static void tegra_se_host1x_remove(struct host1x_device *dev) 405 405 { 406 406 host1x_device_exit(dev); 407 - 408 - return 0; 409 407 } 410 408 411 409 static struct host1x_driver tegra_se_host1x_driver = {
+1 -1
drivers/dma-buf/heaps/cma_heap.c
··· 331 331 while (nr_clear_pages > 0) { 332 332 void *vaddr = kmap_local_page(page); 333 333 334 - memset(vaddr, 0, PAGE_SIZE); 334 + clear_page(vaddr); 335 335 kunmap_local(vaddr); 336 336 /* 337 337 * Avoid wasting time zeroing memory if the process
+9 -9
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
··· 1676 1676 if (property == adev->mode_info.plane_degamma_lut_property) { 1677 1677 ret = drm_property_replace_blob_from_id(plane->dev, 1678 1678 &dm_plane_state->degamma_lut, 1679 - val, -1, 1680 - sizeof(struct drm_color_lut), 1679 + val, 1680 + -1, -1, sizeof(struct drm_color_lut), 1681 1681 &replaced); 1682 1682 dm_plane_state->base.color_mgmt_changed |= replaced; 1683 1683 return ret; ··· 1695 1695 ret = drm_property_replace_blob_from_id(plane->dev, 1696 1696 &dm_plane_state->ctm, 1697 1697 val, 1698 - sizeof(struct drm_color_ctm_3x4), -1, 1698 + -1, sizeof(struct drm_color_ctm_3x4), -1, 1699 1699 &replaced); 1700 1700 dm_plane_state->base.color_mgmt_changed |= replaced; 1701 1701 return ret; 1702 1702 } else if (property == adev->mode_info.plane_shaper_lut_property) { 1703 1703 ret = drm_property_replace_blob_from_id(plane->dev, 1704 1704 &dm_plane_state->shaper_lut, 1705 - val, -1, 1706 - sizeof(struct drm_color_lut), 1705 + val, 1706 + -1, -1, sizeof(struct drm_color_lut), 1707 1707 &replaced); 1708 1708 dm_plane_state->base.color_mgmt_changed |= replaced; 1709 1709 return ret; ··· 1715 1715 } else if (property == adev->mode_info.plane_lut3d_property) { 1716 1716 ret = drm_property_replace_blob_from_id(plane->dev, 1717 1717 &dm_plane_state->lut3d, 1718 - val, -1, 1719 - sizeof(struct drm_color_lut), 1718 + val, 1719 + -1, -1, sizeof(struct drm_color_lut), 1720 1720 &replaced); 1721 1721 dm_plane_state->base.color_mgmt_changed |= replaced; 1722 1722 return ret; 1723 1723 } else if (property == adev->mode_info.plane_blend_lut_property) { 1724 1724 ret = drm_property_replace_blob_from_id(plane->dev, 1725 1725 &dm_plane_state->blend_lut, 1726 - val, -1, 1727 - sizeof(struct drm_color_lut), 1726 + val, 1727 + -1, -1, sizeof(struct drm_color_lut), 1728 1728 &replaced); 1729 1729 dm_plane_state->base.color_mgmt_changed |= replaced; 1730 1730 return ret;
+30 -4
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
··· 165 165 struct regmap *regm; 166 166 167 167 unsigned long tmds_char_rate; 168 + bool no_hpd; 168 169 }; 169 170 170 171 static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val, ··· 556 555 557 556 stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); 558 557 if (!stat) { 559 - dev_err(hdmi->dev, "i2c read timed out\n"); 558 + if (hdmi->no_hpd) 559 + dev_dbg_ratelimited(hdmi->dev, 560 + "i2c read timed out\n"); 561 + else 562 + dev_err(hdmi->dev, "i2c read timed out\n"); 560 563 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); 561 564 return -EAGAIN; 562 565 } 563 566 564 567 /* Check for error condition on the bus */ 565 568 if (i2c->stat & I2CM_NACK_RCVD_IRQ) { 566 - dev_err(hdmi->dev, "i2c read error\n"); 569 + if (hdmi->no_hpd) 570 + dev_dbg_ratelimited(hdmi->dev, 571 + "i2c read error\n"); 572 + else 573 + dev_err(hdmi->dev, "i2c read error\n"); 567 574 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); 568 575 return -EIO; 569 576 } ··· 909 900 dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector) 910 901 { 911 902 struct dw_hdmi_qp *hdmi = bridge->driver_private; 903 + const struct drm_edid *drm_edid; 904 + 905 + if (hdmi->no_hpd) { 906 + drm_edid = drm_edid_read_ddc(connector, bridge->ddc); 907 + if (drm_edid) 908 + return connector_status_connected; 909 + else 910 + return connector_status_disconnected; 911 + } 912 912 913 913 return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); 914 914 } ··· 943 925 { 944 926 struct dw_hdmi_qp *hdmi = bridge->driver_private; 945 927 928 + /* 929 + * TODO: when hdmi->no_hpd is 1 we must not support modes that 930 + * require scrambling, including every mode with a clock above 931 + * HDMI14_MAX_TMDSCLK. 932 + */ 946 933 if (rate > HDMI14_MAX_TMDSCLK) { 947 934 dev_dbg(hdmi->dev, "Unsupported TMDS char rate: %lld\n", rate); 948 935 return MODE_CLOCK_HIGH; ··· 1300 1277 if (ret) 1301 1278 return ERR_PTR(ret); 1302 1279 1280 + hdmi->no_hpd = device_property_read_bool(dev, "no-hpd"); 1281 + 1303 1282 hdmi->bridge.driver_private = hdmi; 1304 1283 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | 1305 1284 DRM_BRIDGE_OP_EDID | 1306 1285 DRM_BRIDGE_OP_HDMI | 1307 - DRM_BRIDGE_OP_HDMI_AUDIO | 1308 - DRM_BRIDGE_OP_HPD; 1286 + DRM_BRIDGE_OP_HDMI_AUDIO; 1287 + if (!hdmi->no_hpd) 1288 + hdmi->bridge.ops |= DRM_BRIDGE_OP_HPD; 1309 1289 hdmi->bridge.of_node = pdev->dev.of_node; 1310 1290 hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 1311 1291 hdmi->bridge.vendor = "Synopsys";
+24 -8
drivers/gpu/drm/drm_atomic_uapi.c
··· 413 413 } else if (property == config->prop_vrr_enabled) { 414 414 state->vrr_enabled = val; 415 415 } else if (property == config->degamma_lut_property) { 416 + const size_t elem_size = sizeof(struct drm_color_lut); 417 + u64 lut_size; 418 + 419 + ret = drm_object_immutable_property_get_value(&crtc->base, 420 + config->degamma_lut_size_property, 421 + &lut_size); 422 + if (ret) 423 + return ret; 424 + 416 425 ret = drm_property_replace_blob_from_id(dev, 417 426 &state->degamma_lut, 418 427 val, 419 - -1, sizeof(struct drm_color_lut), 428 + elem_size * lut_size, -1, elem_size, 420 429 &replaced); 421 430 state->color_mgmt_changed |= replaced; 422 431 return ret; ··· 433 424 ret = drm_property_replace_blob_from_id(dev, 434 425 &state->ctm, 435 426 val, 436 - sizeof(struct drm_color_ctm), -1, 427 + -1, sizeof(struct drm_color_ctm), -1, 437 428 &replaced); 438 429 state->color_mgmt_changed |= replaced; 439 430 return ret; 440 431 } else if (property == config->gamma_lut_property) { 432 + const size_t elem_size = sizeof(struct drm_color_lut); 433 + u64 lut_size; 434 + 435 + ret = drm_object_immutable_property_get_value(&crtc->base, 436 + config->gamma_lut_size_property, 437 + &lut_size); 438 + if (ret) 439 + return ret; 440 + 441 441 ret = drm_property_replace_blob_from_id(dev, 442 442 &state->gamma_lut, 443 443 val, 444 - -1, sizeof(struct drm_color_lut), 444 + elem_size * lut_size, -1, elem_size, 445 445 &replaced); 446 446 state->color_mgmt_changed |= replaced; 447 447 return ret; ··· 605 587 ret = drm_property_replace_blob_from_id(dev, 606 588 &state->fb_damage_clips, 607 589 val, 608 - -1, 609 - sizeof(struct drm_mode_rect), 590 + -1, -1, sizeof(struct drm_mode_rect), 610 591 &replaced); 611 592 return ret; 612 593 } else if (property == plane->scaling_filter_property) { ··· 734 717 return drm_property_replace_blob_from_id(colorop->dev, 735 718 &state->data, 736 719 val, 737 - size, 738 - elem_size, 720 + -1, size, elem_size, 739 721 &replaced); 740 722 } 741 723 ··· 892 876 ret = drm_property_replace_blob_from_id(dev, 893 877 &state->hdr_output_metadata, 894 878 val, 895 - sizeof(struct hdr_output_metadata), -1, 879 + -1, sizeof(struct hdr_output_metadata), -1, 896 880 &replaced); 897 881 return ret; 898 882 } else if (property == config->aspect_ratio_property) {
+6 -5
drivers/gpu/drm/drm_gem.c
··· 1302 1302 unsigned long ret; 1303 1303 1304 1304 obj = drm_gem_object_lookup_at_offset(filp, pgoff, len >> PAGE_SHIFT); 1305 - if (IS_ERR(obj) || !obj->filp || !obj->filp->f_op->get_unmapped_area) 1306 - return mm_get_unmapped_area(filp, uaddr, len, 0, 1307 - flags); 1305 + if (IS_ERR(obj)) 1306 + obj = NULL; 1308 1307 1309 - ret = obj->filp->f_op->get_unmapped_area(obj->filp, uaddr, len, 0, 1310 - flags); 1308 + if (!obj || !obj->filp || !obj->filp->f_op->get_unmapped_area) 1309 + ret = mm_get_unmapped_area(filp, uaddr, len, 0, flags); 1310 + else 1311 + ret = obj->filp->f_op->get_unmapped_area(obj->filp, uaddr, len, 0, flags); 1311 1312 1312 1313 drm_gem_object_put(obj); 1313 1314
+18 -8
drivers/gpu/drm/drm_gpuvm.c
··· 1815 1815 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_find); 1816 1816 1817 1817 /** 1818 - * drm_gpuvm_bo_obtain() - obtains an instance of the &drm_gpuvm_bo for the 1819 - * given &drm_gpuvm and &drm_gem_object 1818 + * drm_gpuvm_bo_obtain_locked() - obtains an instance of the &drm_gpuvm_bo for 1819 + * the given &drm_gpuvm and &drm_gem_object 1820 1820 * @gpuvm: The &drm_gpuvm the @obj is mapped in. 1821 1821 * @obj: The &drm_gem_object being mapped in the @gpuvm. 1822 1822 * ··· 1825 1825 * count of the &drm_gpuvm_bo accordingly. If not found, allocates a new 1826 1826 * &drm_gpuvm_bo. 1827 1827 * 1828 + * Requires the lock for the GEMs gpuva list. 1829 + * 1828 1830 * A new &drm_gpuvm_bo is added to the GEMs gpuva list. 1829 1831 * 1830 1832 * Returns: a pointer to the &drm_gpuvm_bo on success, an ERR_PTR on failure 1831 1833 */ 1832 1834 struct drm_gpuvm_bo * 1833 - drm_gpuvm_bo_obtain(struct drm_gpuvm *gpuvm, 1834 - struct drm_gem_object *obj) 1835 + drm_gpuvm_bo_obtain_locked(struct drm_gpuvm *gpuvm, 1836 + struct drm_gem_object *obj) 1835 1837 { 1836 1838 struct drm_gpuvm_bo *vm_bo; 1839 + 1840 + /* 1841 + * In immediate mode this would require the caller to hold the GEMs 1842 + * gpuva mutex, but it's not okay to allocate while holding that lock, 1843 + * and this method allocates. Immediate mode drivers should use 1844 + * drm_gpuvm_bo_obtain_prealloc() instead. 1845 + */ 1846 + drm_WARN_ON(gpuvm->drm, drm_gpuvm_immediate_mode(gpuvm)); 1837 1847 1838 1848 vm_bo = drm_gpuvm_bo_find(gpuvm, obj); 1839 1849 if (vm_bo) ··· 1858 1848 1859 1849 return vm_bo; 1860 1850 } 1861 - EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain); 1851 + EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain_locked); 1862 1852 1863 1853 /** 1864 1854 * drm_gpuvm_bo_obtain_prealloc() - obtains an instance of the &drm_gpuvm_bo ··· 2268 2258 void 2269 2259 drm_gpuva_map(struct drm_gpuvm *gpuvm, 2270 2260 struct drm_gpuva *va, 2271 - struct drm_gpuva_op_map *op) 2261 + const struct drm_gpuva_op_map *op) 2272 2262 { 2273 2263 drm_gpuva_init_from_op(va, op); 2274 2264 drm_gpuva_insert(gpuvm, va); ··· 2288 2278 void 2289 2279 drm_gpuva_remap(struct drm_gpuva *prev, 2290 2280 struct drm_gpuva *next, 2291 - struct drm_gpuva_op_remap *op) 2281 + const struct drm_gpuva_op_remap *op) 2292 2282 { 2293 2283 struct drm_gpuva *va = op->unmap->va; 2294 2284 struct drm_gpuvm *gpuvm = va->vm; ··· 2315 2305 * Removes the &drm_gpuva associated with the &drm_gpuva_op_unmap. 2316 2306 */ 2317 2307 void 2318 - drm_gpuva_unmap(struct drm_gpuva_op_unmap *op) 2308 + drm_gpuva_unmap(const struct drm_gpuva_op_unmap *op) 2319 2309 { 2320 2310 drm_gpuva_remove(op->va); 2321 2311 }
+25
drivers/gpu/drm/drm_mode_object.c
··· 385 385 } 386 386 EXPORT_SYMBOL(drm_object_property_get_default_value); 387 387 388 + /** 389 + * drm_object_immutable_property_get_value - retrieve the value of a property 390 + * @obj: drm mode object to get property value from 391 + * @property: property to retrieve 392 + * @val: storage for the property value 393 + * 394 + * This function retrieves the software state of the given immutable property 395 + * for the given mode object. 396 + * 397 + * This function can be called by both atomic and non-atomic drivers. 398 + * 399 + * Returns: 400 + * Zero on success, error code on failure. 401 + */ 402 + int drm_object_immutable_property_get_value(struct drm_mode_object *obj, 403 + struct drm_property *property, 404 + uint64_t *val) 405 + { 406 + if (drm_WARN_ON(property->dev, !(property->flags & DRM_MODE_PROP_IMMUTABLE))) 407 + return -EINVAL; 408 + 409 + return __drm_object_property_get_prop_value(obj, property, val); 410 + } 411 + EXPORT_SYMBOL(drm_object_immutable_property_get_value); 412 + 388 413 /* helper for getconnector and getproperties ioctls */ 389 414 int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, 390 415 bool plane_color_pipeline,
+7 -4
drivers/gpu/drm/drm_panic.c
··· 823 823 [DRM_PANIC_TYPE_KMSG] = "kmsg", 824 824 [DRM_PANIC_TYPE_USER] = "user", 825 825 #if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) 826 - [DRM_PANIC_TYPE_QR] = "qr", 826 + [DRM_PANIC_TYPE_QR] = "qr_code", 827 827 #endif 828 828 }; 829 829 ··· 855 855 module_param_cb(panic_screen, &drm_panic_ops, NULL, 0644); 856 856 MODULE_PARM_DESC(panic_screen, 857 857 #if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) 858 - "Choose what will be displayed by drm_panic, 'user', 'kmsg' or 'qr' [default=" 858 + "Choose what will be displayed by drm_panic, 'user', 'kmsg' or 'qr_code' [default=" 859 859 #else 860 860 "Choose what will be displayed by drm_panic, 'user' or 'kmsg' [default=" 861 861 #endif ··· 1072 1072 */ 1073 1073 void __init drm_panic_init(void) 1074 1074 { 1075 - if (drm_panic_type == -1) 1076 - drm_panic_type_set(CONFIG_DRM_PANIC_SCREEN, NULL); 1075 + if (drm_panic_type == -1 && drm_panic_type_set(CONFIG_DRM_PANIC_SCREEN, NULL)) { 1076 + pr_warn("Unsupported value for CONFIG_DRM_PANIC_SCREEN ('%s'), falling back to 'user'...\n", 1077 + CONFIG_DRM_PANIC_SCREEN); 1078 + drm_panic_type = DRM_PANIC_TYPE_USER; 1079 + } 1077 1080 drm_panic_qr_init(); 1078 1081 } 1079 1082
+11
drivers/gpu/drm/drm_property.c
··· 757 757 * @dev: DRM device 758 758 * @blob: a pointer to the member blob to be replaced 759 759 * @blob_id: the id of the new blob to replace with 760 + * @max_size: the maximum size of the blob property for variable-size blobs 760 761 * @expected_size: expected size of the blob property 761 762 * @expected_elem_size: expected size of an element in the blob property 762 763 * @replaced: if the blob was in fact replaced ··· 772 771 int drm_property_replace_blob_from_id(struct drm_device *dev, 773 772 struct drm_property_blob **blob, 774 773 uint64_t blob_id, 774 + ssize_t max_size, 775 775 ssize_t expected_size, 776 776 ssize_t expected_elem_size, 777 777 bool *replaced) ··· 784 782 if (new_blob == NULL) { 785 783 drm_dbg_atomic(dev, 786 784 "cannot find blob ID %llu\n", blob_id); 785 + return -EINVAL; 786 + } 787 + 788 + if (max_size > 0 && 789 + new_blob->length > max_size) { 790 + drm_dbg_atomic(dev, 791 + "[BLOB:%d] length %zu greater than max %zu\n", 792 + new_blob->base.id, new_blob->length, max_size); 793 + drm_property_blob_put(new_blob); 787 794 return -EINVAL; 788 795 } 789 796
+1 -1
drivers/gpu/drm/imagination/pvr_vm.c
··· 256 256 bind_op->type = PVR_VM_BIND_TYPE_MAP; 257 257 258 258 dma_resv_lock(obj->resv, NULL); 259 - bind_op->gpuvm_bo = drm_gpuvm_bo_obtain(&vm_ctx->gpuvm_mgr, obj); 259 + bind_op->gpuvm_bo = drm_gpuvm_bo_obtain_locked(&vm_ctx->gpuvm_mgr, obj); 260 260 dma_resv_unlock(obj->resv); 261 261 if (IS_ERR(bind_op->gpuvm_bo)) 262 262 return PTR_ERR(bind_op->gpuvm_bo);
+1 -1
drivers/gpu/drm/msm/msm_gem.h
··· 60 60 * embedded in any larger driver structure. The GEM object holds a list of 61 61 * drm_gpuvm_bo, which in turn holds a list of msm_gem_vma. A linked vma 62 62 * holds a reference to the vm_bo, and drops it when the vma is unlinked. 63 - * So we just need to call drm_gpuvm_bo_obtain() to return a ref to an 63 + * So we just need to call drm_gpuvm_bo_obtain_locked() to return a ref to an 64 64 * existing vm_bo, or create a new one. Once the vma is linked, the ref 65 65 * to the vm_bo can be dropped (since the vma is holding one). 66 66 */
+1 -1
drivers/gpu/drm/msm/msm_gem_vma.c
··· 413 413 if (!obj) 414 414 return &vma->base; 415 415 416 - vm_bo = drm_gpuvm_bo_obtain(&vm->base, obj); 416 + vm_bo = drm_gpuvm_bo_obtain_locked(&vm->base, obj); 417 417 if (IS_ERR(vm_bo)) { 418 418 ret = PTR_ERR(vm_bo); 419 419 goto err_va_remove;
+1 -1
drivers/gpu/drm/nouveau/nouveau_uvmm.c
··· 1275 1275 return -ENOENT; 1276 1276 1277 1277 dma_resv_lock(obj->resv, NULL); 1278 - op->vm_bo = drm_gpuvm_bo_obtain(&uvmm->base, obj); 1278 + op->vm_bo = drm_gpuvm_bo_obtain_locked(&uvmm->base, obj); 1279 1279 dma_resv_unlock(obj->resv); 1280 1280 if (IS_ERR(op->vm_bo)) 1281 1281 return PTR_ERR(op->vm_bo);
+6 -6
drivers/gpu/drm/panel/panel-himax-hx83102.c
··· 859 859 { 860 860 struct hx83102 *ctx = panel_to_hx83102(panel); 861 861 862 - gpiod_set_value(ctx->enable_gpio, 0); 862 + gpiod_set_value_cansleep(ctx->enable_gpio, 0); 863 863 usleep_range(1000, 2000); 864 864 regulator_disable(ctx->avee); 865 865 regulator_disable(ctx->avdd); ··· 875 875 struct mipi_dsi_device *dsi = ctx->dsi; 876 876 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 877 877 878 - gpiod_set_value(ctx->enable_gpio, 0); 878 + gpiod_set_value_cansleep(ctx->enable_gpio, 0); 879 879 usleep_range(1000, 1500); 880 880 881 881 dsi_ctx.accum_err = regulator_enable(ctx->pp1800); ··· 899 899 900 900 usleep_range(1000, 2000); 901 901 902 - gpiod_set_value(ctx->enable_gpio, 1); 902 + gpiod_set_value_cansleep(ctx->enable_gpio, 1); 903 903 usleep_range(1000, 2000); 904 - gpiod_set_value(ctx->enable_gpio, 0); 904 + gpiod_set_value_cansleep(ctx->enable_gpio, 0); 905 905 usleep_range(1000, 2000); 906 - gpiod_set_value(ctx->enable_gpio, 1); 906 + gpiod_set_value_cansleep(ctx->enable_gpio, 1); 907 907 usleep_range(6000, 10000); 908 908 909 909 dsi_ctx.accum_err = ctx->desc->init(ctx); ··· 917 917 return 0; 918 918 919 919 poweroff: 920 - gpiod_set_value(ctx->enable_gpio, 0); 920 + gpiod_set_value_cansleep(ctx->enable_gpio, 0); 921 921 regulator_disable(ctx->avee); 922 922 poweroffavdd: 923 923 regulator_disable(ctx->avdd);
+136 -11
drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
··· 8 8 #include <linux/of.h> 9 9 #include <linux/regulator/consumer.h> 10 10 11 + #include <drm/display/drm_dsc.h> 12 + #include <drm/display/drm_dsc_helper.h> 11 13 #include <drm/drm_connector.h> 12 14 #include <drm/drm_crtc.h> 13 15 #include <drm/drm_mipi_dsi.h> 14 16 #include <drm/drm_panel.h> 15 17 16 18 #include <video/mipi_display.h> 19 + 20 + #define DSC_BPG_OFFSET(x) ((u8)((x) & DSC_RANGE_BPG_OFFSET_MASK)) 17 21 18 22 struct ili9882t; 19 23 ··· 27 23 */ 28 24 struct panel_desc { 29 25 const struct drm_display_mode *modes; 26 + const struct drm_dsc_config *dsc; 30 27 unsigned int bpc; 31 28 32 29 /** ··· 57 52 struct regulator *avee; 58 53 struct regulator *avdd; 59 54 struct gpio_desc *enable_gpio; 55 + 56 + struct drm_dsc_config dsc; 60 57 }; 61 58 62 59 /* ILI9882-specific commands, add new commands as you decode them */ ··· 74 67 #define il79900a_switch_page(ctx, page) \ 75 68 mipi_dsi_dcs_write_seq_multi(ctx, IL79900A_DCS_SWITCH_PAGE, \ 76 69 0x5a, 0xa5, (page)) 70 + 71 + static const struct drm_dsc_config tianma_il79900a_dsc = { 72 + .dsc_version_major = 1, 73 + .dsc_version_minor = 2, 74 + .slice_height = 8, 75 + .slice_width = 800, 76 + .slice_count = 2, 77 + .bits_per_component = 8, 78 + .bits_per_pixel = 8 << 4, 79 + .block_pred_enable = true, 80 + .native_420 = false, 81 + .native_422 = false, 82 + .simple_422 = false, 83 + .vbr_enable = false, 84 + .rc_model_size = DSC_RC_MODEL_SIZE_CONST, 85 + .pic_width = 1600, 86 + .pic_height = 2560, 87 + .convert_rgb = 0, 88 + .vbr_enable = 0, 89 + .rc_buf_thresh = {14, 28, 42, 56, 70, 84, 98, 105, 112, 119, 121, 123, 125, 126}, 90 + .rc_model_size = DSC_RC_MODEL_SIZE_CONST, 91 + .rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST, 92 + .rc_tgt_offset_high = DSC_RC_TGT_OFFSET_HI_CONST, 93 + .rc_tgt_offset_low = DSC_RC_TGT_OFFSET_LO_CONST, 94 + .mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC, 95 + .line_buf_depth = 9, 96 + .first_line_bpg_offset = 12, 97 + .initial_xmit_delay = 512, 98 + .initial_offset = 6144, 99 + .rc_quant_incr_limit0 = 11, 100 + .rc_quant_incr_limit1 = 11, 101 + .nfl_bpg_offset = 1402, 102 + .rc_range_params = { 103 + { 0, 4, DSC_BPG_OFFSET(2)}, 104 + { 0, 4, DSC_BPG_OFFSET(0)}, 105 + { 1, 5, DSC_BPG_OFFSET(0)}, 106 + { 1, 6, DSC_BPG_OFFSET(-2)}, 107 + { 3, 7, DSC_BPG_OFFSET(-4)}, 108 + { 3, 7, DSC_BPG_OFFSET(-6)}, 109 + { 3, 7, DSC_BPG_OFFSET(-8)}, 110 + { 3, 8, DSC_BPG_OFFSET(-8)}, 111 + { 3, 9, DSC_BPG_OFFSET(-8)}, 112 + { 3, 10, DSC_BPG_OFFSET(-10)}, 113 + { 5, 10, DSC_BPG_OFFSET(-10)}, 114 + { 5, 11, DSC_BPG_OFFSET(-12)}, 115 + { 5, 11, DSC_BPG_OFFSET(-12)}, 116 + { 9, 12, DSC_BPG_OFFSET(-12)}, 117 + {12, 13, DSC_BPG_OFFSET(-12)}, 118 + }, 119 + .initial_scale_value = 32, 120 + .slice_chunk_size = 800, 121 + .initial_dec_delay = 657, 122 + .final_offset = 4320, 123 + .scale_increment_interval = 222, 124 + .scale_decrement_interval = 11, 125 + .initial_scale_value = 32, 126 + .nfl_bpg_offset = 3511, 127 + .slice_bpg_offset = 2179, 128 + .flatness_max_qp = 12, 129 + .flatness_min_qp = 3, 130 + }; 77 131 78 132 static int starry_ili9882t_init(struct ili9882t *ili) 79 133 { ··· 491 423 static int tianma_il79900a_init(struct ili9882t *ili) 492 424 { 493 425 struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi }; 426 + struct drm_dsc_picture_parameter_set pps; 494 427 495 428 mipi_dsi_usleep_range(&ctx, 5000, 5100); 496 429 497 430 il79900a_switch_page(&ctx, 0x06); 498 431 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x62); 499 432 433 + il79900a_switch_page(&ctx, 0x01); 434 + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00); 435 + 500 436 il79900a_switch_page(&ctx, 0x02); 501 - mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x20); 437 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x00); 502 438 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00); 503 439 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x40); 504 440 441 + il79900a_switch_page(&ctx, 0x05); 442 + mipi_dsi_dcs_write_seq_multi(&ctx, 0X9e, 0xe9); 443 + 505 444 il79900a_switch_page(&ctx, 0x07); 506 - mipi_dsi_dcs_write_seq_multi(&ctx, 0X29, 0x00); 445 + mipi_dsi_dcs_write_seq_multi(&ctx, 0X29, 0x01); 446 + 447 + il79900a_switch_page(&ctx, 0x17); 448 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 449 + 0x00, 0x89, 0x30, 0x80, 0x0a, 0x00, 0x06, 0x40, 0x00, 450 + 0x08, 0x03, 0x20, 0x03, 0x20, 0x02, 0x00, 0x02, 0x91, 451 + 0x00, 0x20, 0x00, 0xde, 0x00, 0x0b, 0x00, 0x0c, 0x0d, 452 + 0xb7, 0x08, 0x83, 0x18, 0x00, 0x10, 0xe0, 0x03, 0x0c, 453 + 0x20, 0x00, 0x06, 0x0b, 0x0b, 0x33, 0x0e, 0x1c, 0x2a, 454 + 0x38, 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b, 455 + 0x7d, 0x7e, 0x01, 0x02, 0x01, 0x00, 0x09, 0x40, 0x09, 456 + 0xbe, 0x19, 0xfc, 0x19, 0xfa, 0x19, 0xf8, 0x1a, 0x38, 457 + 0x1a, 0x78, 0x1a, 0xb6, 0x2a, 0xb6, 0x2a, 0xf4, 0x2a, 458 + 0xf4, 0x4b, 0x34, 0x63, 0x74); 507 459 508 460 il79900a_switch_page(&ctx, 0x06); 509 - mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22); 461 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x91, 0x45); 462 + 463 + il79900a_switch_page(&ctx, 0x16); 464 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x4b); 465 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x73); 466 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0xdf); 467 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x01); 468 + 469 + il79900a_switch_page(&ctx, 0x10); 470 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x8c); 471 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x3c); 472 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x3d); 473 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0xfc); 474 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x9d); 475 + 476 + il79900a_switch_page(&ctx, 0x0e); 477 + mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x18); 478 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x0e); 479 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0xcd); 480 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x53); 481 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x0e); 482 + 483 + il79900a_switch_page(&ctx, 0x1e); 484 + mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x5c); 485 + 486 + drm_dsc_pps_payload_pack(&pps, &tianma_il79900a_dsc); 487 + 488 + mipi_dsi_picture_parameter_set_multi(&ctx, &pps); 489 + 490 + mipi_dsi_compression_mode_ext_multi(&ctx, true, 491 + MIPI_DSI_COMPRESSION_DSC, 1); 510 492 511 493 il79900a_switch_page(&ctx, 0x00); 512 494 mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); ··· 565 447 566 448 mipi_dsi_dcs_set_display_on_multi(&ctx); 567 449 568 - mipi_dsi_msleep(&ctx, 80); 450 + mipi_dsi_msleep(&ctx, 20); 569 451 570 - return 0; 452 + return ctx.accum_err; 571 453 }; 572 454 573 455 static inline struct ili9882t *to_ili9882t(struct drm_panel *panel) ··· 687 569 }; 688 570 689 571 static const struct drm_display_mode tianma_il79900a_default_mode = { 690 - .clock = 264355, 572 + .clock = 543850, 691 573 .hdisplay = 1600, 692 574 .hsync_start = 1600 + 20, 693 - .hsync_end = 1600 + 20 + 4, 694 - .htotal = 1600 + 20 + 4 + 20, 575 + .hsync_end = 1600 + 20 + 2, 576 + .htotal = 1600 + 20 + 2 + 20, 695 577 .vdisplay = 2560, 696 - .vsync_start = 2560 + 82, 697 - .vsync_end = 2560 + 82 + 2, 698 - .vtotal = 2560 + 82 + 2 + 36, 578 + .vsync_start = 2560 + 62, 579 + .vsync_end = 2560 + 62 + 2, 580 + .vtotal = 2560 + 62 + 2 + 136, 699 581 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 700 582 }; 701 583 ··· 715 597 716 598 static const struct panel_desc tianma_tl121bvms07_desc = { 717 599 .modes = &tianma_il79900a_default_mode, 600 + .dsc = &tianma_il79900a_dsc, 718 601 .bpc = 8, 719 602 .size = { 720 603 .width_mm = 163, ··· 835 716 dsi->mode_flags = desc->mode_flags; 836 717 ili->desc = desc; 837 718 ili->dsi = dsi; 719 + 720 + if (desc->dsc) { 721 + ili->dsc = *desc->dsc; 722 + dsi->dsc = &ili->dsc; 723 + } 724 + 838 725 ret = ili9882t_add(ili); 839 726 if (ret < 0) 840 727 return ret;
+3 -1
drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c
··· 434 434 int err; 435 435 436 436 /* only detach from host for the DSI-LINK2 interface */ 437 - if (!jdi) 437 + if (!jdi) { 438 438 mipi_dsi_detach(dsi); 439 + return; 440 + } 439 441 440 442 err = jdi_panel_disable(&jdi->base); 441 443 if (err < 0)
+18 -17
drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c
··· 53 53 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a); 54 54 55 55 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_INT_CANCEL, 0x03); 56 - mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a, 0x03); 57 - mipi_dsi_generic_write_seq_multi(dsi_ctx, 0x80, 0xa9, 0x00); 58 56 59 - mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a, 0x09); 60 - mipi_dsi_generic_write_seq_multi(dsi_ctx, 0x80, 0x64, 0x00, 0x64, 0x00, 0x00); 61 - mipi_dsi_msleep(dsi_ctx, 20); 57 + mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a, 0x03); 58 + mipi_dsi_generic_write_seq_multi(dsi_ctx, 0x80, 0xa9, 0x00); /* VCOM */ 62 59 63 60 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_SPI_FINISH, 0xa5); 64 61 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x00, 0x2f); 65 - mipi_dsi_msleep(dsi_ctx, 20); 66 62 } 67 63 68 64 static int mantix_enable(struct drm_panel *panel) ··· 71 75 if (!dsi_ctx.accum_err) 72 76 dev_dbg(ctx->dev, "Panel init sequence done\n"); 73 77 78 + /* remainder to 120ms (7.3.1 Note 4) */ 79 + mipi_dsi_msleep(&dsi_ctx, 70); 80 + 74 81 mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); 75 - mipi_dsi_msleep(&dsi_ctx, 20); 82 + mipi_dsi_msleep(&dsi_ctx, 120); 76 83 77 84 mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); 78 85 mipi_dsi_usleep_range(&dsi_ctx, 10000, 12000); 79 - 80 - mipi_dsi_turn_on_peripheral_multi(&dsi_ctx); 81 86 82 87 return dsi_ctx.accum_err; 83 88 } ··· 92 95 mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); 93 96 mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); 94 97 98 + /* T10 */ 99 + mipi_dsi_msleep(&dsi_ctx, 150); 100 + 95 101 return dsi_ctx.accum_err; 96 102 } 97 103 ··· 102 102 { 103 103 struct mantix *ctx = panel_to_mantix(panel); 104 104 105 - gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 1); 106 - usleep_range(5000, 6000); 107 - gpiod_set_value_cansleep(ctx->reset_gpio, 1); 108 - 109 105 regulator_disable(ctx->avee); 110 106 regulator_disable(ctx->avdd); 111 107 /* T11 */ 112 108 usleep_range(5000, 6000); 113 109 regulator_disable(ctx->vddi); 110 + 111 + gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 1); 112 + usleep_range(5000, 6000); 113 + gpiod_set_value_cansleep(ctx->reset_gpio, 1); 114 + 114 115 /* T14 */ 115 116 msleep(50); 116 117 ··· 148 147 return ret; 149 148 } 150 149 151 - /* T3 + T4 + time for voltage to become stable: */ 152 - usleep_range(6000, 7000); 153 - gpiod_set_value_cansleep(ctx->reset_gpio, 0); 150 + usleep_range(100, 200); 154 151 gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 0); 152 + usleep_range(100, 200); 153 + gpiod_set_value_cansleep(ctx->reset_gpio, 0); 155 154 156 155 /* T6 */ 157 156 msleep(50); ··· 259 258 260 259 dsi->lanes = 4; 261 260 dsi->format = MIPI_DSI_FMT_RGB888; 262 - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | 261 + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM | 263 262 MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE; 264 263 265 264 ctx->avdd = devm_regulator_get(dev, "avdd");
+29
drivers/gpu/drm/panel/panel-simple.c
··· 2836 2836 .connector_type = DRM_MODE_CONNECTOR_LVDS, 2837 2837 }; 2838 2838 2839 + static const struct display_timing innolux_g150xge_l05_timing = { 2840 + .pixelclock = { 53350000, 65000000, 80000000 }, 2841 + .hactive = { 1024, 1024, 1024 }, 2842 + .hfront_porch = { 58, 160, 288 }, 2843 + .hback_porch = { 58, 160, 288 }, 2844 + .hsync_len = { 1, 1, 1 }, 2845 + .vactive = { 768, 768, 768 }, 2846 + .vfront_porch = { 6, 19, 216 }, 2847 + .vback_porch = { 6, 19, 216 }, 2848 + .vsync_len = { 1, 1, 1 }, 2849 + .flags = DISPLAY_FLAGS_DE_HIGH, 2850 + }; 2851 + 2852 + static const struct panel_desc innolux_g150xge_l05 = { 2853 + .timings = &innolux_g150xge_l05_timing, 2854 + .num_timings = 1, 2855 + .bpc = 8, 2856 + .size = { 2857 + .width = 304, 2858 + .height = 228, 2859 + }, 2860 + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 2861 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 2862 + .connector_type = DRM_MODE_CONNECTOR_LVDS, 2863 + }; 2864 + 2839 2865 static const struct display_timing innolux_g156hce_l01_timings = { 2840 2866 .pixelclock = { 120000000, 141860000, 150000000 }, 2841 2867 .hactive = { 1920, 1920, 1920 }, ··· 5340 5314 }, { 5341 5315 .compatible = "innolux,g121xce-l01", 5342 5316 .data = &innolux_g121xce_l01, 5317 + }, { 5318 + .compatible = "innolux,g150xge-l05", 5319 + .data = &innolux_g150xge_l05, 5343 5320 }, { 5344 5321 .compatible = "innolux,g156hce-l01", 5345 5322 .data = &innolux_g156hce_l01,
+25 -15
drivers/gpu/drm/panfrost/panfrost_mmu.c
··· 587 587 static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, 588 588 u64 addr) 589 589 { 590 - int ret, i; 590 + int ret; 591 591 struct panfrost_gem_mapping *bomapping; 592 592 struct panfrost_gem_object *bo; 593 593 struct address_space *mapping; 594 594 struct drm_gem_object *obj; 595 - pgoff_t page_offset; 595 + pgoff_t page_offset, nr_pages; 596 596 struct sg_table *sgt; 597 597 struct page **pages; 598 598 ··· 613 613 addr &= ~((u64)SZ_2M - 1); 614 614 page_offset = addr >> PAGE_SHIFT; 615 615 page_offset -= bomapping->mmnode.start; 616 + nr_pages = bo->base.base.size >> PAGE_SHIFT; 616 617 617 618 obj = &bo->base.base; 618 619 ··· 627 626 goto err_unlock; 628 627 } 629 628 630 - pages = kvmalloc_array(bo->base.base.size >> PAGE_SHIFT, 631 - sizeof(struct page *), GFP_KERNEL | __GFP_ZERO); 629 + pages = kvmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL | __GFP_ZERO); 632 630 if (!pages) { 633 631 kvfree(bo->sgts); 634 632 bo->sgts = NULL; ··· 649 649 mapping = bo->base.base.filp->f_mapping; 650 650 mapping_set_unevictable(mapping); 651 651 652 - for (i = page_offset; i < page_offset + NUM_FAULT_PAGES; i++) { 653 - /* Can happen if the last fault only partially filled this 654 - * section of the pages array before failing. In that case 655 - * we skip already filled pages. 656 - */ 657 - if (pages[i]) 658 - continue; 652 + for (pgoff_t pg = page_offset; pg < page_offset + NUM_FAULT_PAGES;) { 653 + bool already_owned = false; 654 + struct folio *folio; 659 655 660 - pages[i] = shmem_read_mapping_page(mapping, i); 661 - if (IS_ERR(pages[i])) { 662 - ret = PTR_ERR(pages[i]); 663 - pages[i] = NULL; 656 + folio = shmem_read_folio(mapping, pg); 657 + if (IS_ERR(folio)) { 658 + ret = PTR_ERR(folio); 664 659 goto err_unlock; 665 660 } 661 + 662 + pg &= ~(folio_nr_pages(folio) - 1); 663 + for (u32 i = 0; i < folio_nr_pages(folio) && pg < nr_pages; i++) { 664 + if (pages[pg]) 665 + already_owned = true; 666 + 667 + pages[pg++] = folio_page(folio, i); 668 + } 669 + 670 + /* We always fill the page array at a folio granularity so 671 + * there's no valid reason for a folio range to be partially 672 + * populated. 673 + */ 674 + if (drm_WARN_ON(&pfdev->base, already_owned)) 675 + folio_put(folio); 666 676 } 667 677 668 678 ret = sg_alloc_table_from_pages(sgt, pages + page_offset,
+30 -6
drivers/gpu/drm/panthor/panthor_hw.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 or MIT 2 2 /* Copyright 2025 ARM Limited. All rights reserved. */ 3 3 4 + #include <linux/nvmem-consumer.h> 4 5 #include <drm/drm_print.h> 5 6 6 7 #include "panthor_device.h" ··· 110 109 return "(Unknown Mali GPU)"; 111 110 } 112 111 113 - static void panthor_gpu_info_init(struct panthor_device *ptdev) 112 + static int overload_shader_present(struct panthor_device *ptdev) 113 + { 114 + u64 contents; 115 + int ret; 116 + 117 + ret = nvmem_cell_read_variable_le_u64(ptdev->base.dev, "shader-present", 118 + &contents); 119 + if (!ret) 120 + ptdev->gpu_info.shader_present = contents; 121 + else if (ret == -ENOENT) 122 + return 0; 123 + else 124 + return dev_err_probe(ptdev->base.dev, ret, 125 + "Failed to read shader-present nvmem cell\n"); 126 + 127 + return 0; 128 + } 129 + 130 + static int panthor_gpu_info_init(struct panthor_device *ptdev) 114 131 { 115 132 unsigned int i; 116 133 ··· 162 143 ptdev->gpu_info.tiler_present = gpu_read64(ptdev, GPU_TILER_PRESENT); 163 144 ptdev->gpu_info.l2_present = gpu_read64(ptdev, GPU_L2_PRESENT); 164 145 } 146 + 147 + return overload_shader_present(ptdev); 165 148 } 166 149 167 - static void panthor_hw_info_init(struct panthor_device *ptdev) 150 + static int panthor_hw_info_init(struct panthor_device *ptdev) 168 151 { 169 152 u32 major, minor, status; 153 + int ret; 170 154 171 - panthor_gpu_info_init(ptdev); 155 + ret = panthor_gpu_info_init(ptdev); 156 + if (ret) 157 + return ret; 172 158 173 159 major = GPU_VER_MAJOR(ptdev->gpu_info.gpu_id); 174 160 minor = GPU_VER_MINOR(ptdev->gpu_info.gpu_id); ··· 196 172 "shader_present=0x%0llx l2_present=0x%0llx tiler_present=0x%0llx", 197 173 ptdev->gpu_info.shader_present, ptdev->gpu_info.l2_present, 198 174 ptdev->gpu_info.tiler_present); 175 + 176 + return 0; 199 177 } 200 178 201 179 static int panthor_hw_bind_device(struct panthor_device *ptdev) ··· 244 218 if (ret) 245 219 return ret; 246 220 247 - panthor_hw_info_init(ptdev); 248 - 249 - return 0; 221 + return panthor_hw_info_init(ptdev); 250 222 }
+3 -1
drivers/gpu/drm/rockchip/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 config DRM_ROCKCHIP 3 3 tristate "DRM Support for Rockchip" 4 - depends on DRM && ROCKCHIP_IOMMU 4 + depends on DRM 5 + depends on ARCH_ROCKCHIP || COMPILE_TEST 6 + depends on ROCKCHIP_IOMMU || !ROCKCHIP_IOMMU 5 7 depends on OF 6 8 select DRM_CLIENT_SELECTION 7 9 select DRM_GEM_DMA_HELPER
+20
drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
··· 198 198 #define RK3568_DSI0_TURNDISABLE BIT(2) 199 199 #define RK3568_DSI0_FORCERXMODE BIT(0) 200 200 201 + #define RK3506_SYS_GRF_SOC_CON6 0x0018 202 + #define RK3506_DSI_FORCETXSTOPMODE (0xf << 4) 203 + #define RK3506_DSI_TURNDISABLE BIT(2) 204 + #define RK3506_DSI_FORCERXMODE BIT(0) 205 + 201 206 /* 202 207 * Note these registers do not appear in the datasheet, they are 203 208 * however present in the BSP driver which is where these values ··· 1666 1661 { /* sentinel */ } 1667 1662 }; 1668 1663 1664 + static const struct rockchip_dw_dsi_chip_data rk3506_chip_data[] = { 1665 + { 1666 + .reg = 0xff640000, 1667 + .lanecfg1_grf_reg = RK3506_SYS_GRF_SOC_CON6, 1668 + .lanecfg1 = (FIELD_PREP_WM16_CONST(RK3506_DSI_TURNDISABLE, 0) | 1669 + FIELD_PREP_WM16_CONST(RK3506_DSI_FORCERXMODE, 0) | 1670 + FIELD_PREP_WM16_CONST(RK3506_DSI_FORCETXSTOPMODE, 0)), 1671 + .max_data_lanes = 2, 1672 + }, 1673 + { /* sentinel */ } 1674 + }; 1675 + 1669 1676 static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = { 1670 1677 { 1671 1678 .reg = 0xfe060000, ··· 1728 1711 }, { 1729 1712 .compatible = "rockchip,rk3399-mipi-dsi", 1730 1713 .data = &rk3399_chip_data, 1714 + }, { 1715 + .compatible = "rockchip,rk3506-mipi-dsi", 1716 + .data = &rk3506_chip_data, 1731 1717 }, { 1732 1718 .compatible = "rockchip,rk3568-mipi-dsi", 1733 1719 .data = &rk3568_chip_data,
+2 -2
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
··· 289 289 290 290 val = FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_CLR, 1); 291 291 regmap_write(hdmi->regmap, RK3576_IOC_MISC_CON0, val); 292 - mod_delayed_work(system_wq, &hdmi->hpd_work, 292 + mod_delayed_work(system_percpu_wq, &hdmi->hpd_work, 293 293 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); 294 294 295 295 val = FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_MSK, 0); ··· 332 332 val = FIELD_PREP_WM16(RK3588_HDMI0_HPD_INT_CLR, 1); 333 333 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); 334 334 335 - mod_delayed_work(system_wq, &hdmi->hpd_work, 335 + mod_delayed_work(system_percpu_wq, &hdmi->hpd_work, 336 336 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); 337 337 338 338 if (hdmi->port_id)
+1 -1
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
··· 1771 1771 spin_unlock(&drm->event_lock); 1772 1772 1773 1773 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending)) 1774 - drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq); 1774 + drm_flip_work_commit(&vop->fb_unref_work, system_dfl_wq); 1775 1775 } 1776 1776 1777 1777 static irqreturn_t vop_isr(int irq, void *data)
+69 -82
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
··· 367 367 } 368 368 } 369 369 370 - static bool rockchip_afbc(struct drm_plane *plane, u64 modifier) 371 - { 372 - int i; 373 - 374 - if (modifier == DRM_FORMAT_MOD_LINEAR) 375 - return false; 376 - 377 - for (i = 0 ; i < plane->modifier_count; i++) 378 - if (plane->modifiers[i] == modifier) 379 - return true; 380 - 381 - return false; 382 - } 383 - 384 370 static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format, 385 371 u64 modifier) 386 372 { 387 373 struct vop2_win *win = to_vop2_win(plane); 388 374 struct vop2 *vop2 = win->vop2; 375 + int i; 389 376 377 + /* No support for implicit modifiers */ 390 378 if (modifier == DRM_FORMAT_MOD_INVALID) 391 379 return false; 392 380 393 - if (vop2->version == VOP_VERSION_RK3568) { 394 - if (vop2_cluster_window(win)) { 395 - if (modifier == DRM_FORMAT_MOD_LINEAR) { 396 - drm_dbg_kms(vop2->drm, 397 - "Cluster window only supports format with afbc\n"); 398 - return false; 399 - } 400 - } 401 - } 402 - 403 - if (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010) { 404 - if (vop2->version == VOP_VERSION_RK3588) { 405 - if (!rockchip_afbc(plane, modifier)) { 406 - drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n"); 407 - return false; 408 - } 409 - } 410 - } 411 - 412 - if (modifier == DRM_FORMAT_MOD_LINEAR) 413 - return true; 414 - 415 - if (!rockchip_afbc(plane, modifier)) { 416 - drm_dbg_kms(vop2->drm, "Unsupported format modifier 0x%llx\n", 417 - modifier); 418 - 381 + /* The cluster window on 3568 is AFBC-only */ 382 + if (vop2->version == VOP_VERSION_RK3568 && vop2_cluster_window(win) && 383 + !drm_is_afbc(modifier)) { 384 + drm_dbg_kms(vop2->drm, 385 + "Cluster window only supports format with afbc\n"); 419 386 return false; 420 387 } 421 388 422 - return vop2_convert_afbc_format(format) >= 0; 389 + /* 10bpc formats on 3588 are AFBC-only */ 390 + if (vop2->version == VOP_VERSION_RK3588 && !drm_is_afbc(modifier) && 391 + (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010)) { 392 + drm_dbg_kms(vop2->drm, "Only support 10bpc format with afbc\n"); 393 + return false; 394 + } 395 + 396 + /* Linear is otherwise supported everywhere */ 397 + if (modifier == DRM_FORMAT_MOD_LINEAR) 398 + return true; 399 + 400 + /* Not all format+modifier combinations are allowable */ 401 + if (vop2_convert_afbc_format(format) == VOP2_AFBC_FMT_INVALID) 402 + return false; 403 + 404 + /* Different windows have different format/modifier support */ 405 + for (i = 0; i < plane->modifier_count; i++) { 406 + if (plane->modifiers[i] == modifier) 407 + return true; 408 + } 409 + 410 + return false; 423 411 } 424 412 425 413 /* ··· 986 998 struct drm_crtc *crtc = pstate->crtc; 987 999 struct drm_crtc_state *cstate; 988 1000 struct vop2_video_port *vp; 1001 + struct vop2_win *win = to_vop2_win(plane); 989 1002 struct vop2 *vop2; 990 1003 const struct vop2_data *vop2_data; 991 1004 struct drm_rect *dest = &pstate->dst; ··· 1019 1030 return 0; 1020 1031 1021 1032 format = vop2_convert_format(fb->format->format); 1022 - if (format < 0) 1033 + /* We shouldn't be able to create a fb for an unsupported format */ 1034 + if (WARN_ON(format < 0)) 1023 1035 return format; 1024 1036 1025 1037 /* Co-ordinates have now been clipped */ ··· 1051 1061 */ 1052 1062 if (fb->format->is_yuv && src_x % 2) { 1053 1063 drm_dbg_kms(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n"); 1064 + return -EINVAL; 1065 + } 1066 + 1067 + /* 1068 + * This is workaround solution for IC design: 1069 + * esmart can't support scale down when src_w % 16 == 1. 1070 + */ 1071 + if (!vop2_cluster_window(win) && src_w > dest_w && (src_w & 1)) { 1072 + drm_dbg_kms(vop2->drm, 1073 + "Esmart windows cannot downscale odd-width source regions\n"); 1074 + return -EINVAL; 1075 + } 1076 + 1077 + if (vop2->version == VOP_VERSION_RK3568 && drm_is_afbc(fb->modifier) && src_w % 4) { 1078 + drm_dbg_kms(vop2->drm, 1079 + "AFBC source rectangles must be 4-pixel aligned; is %d\n", 1080 + src_w); 1081 + return -EINVAL; 1082 + } 1083 + 1084 + if (drm_is_afbc(fb->modifier) && 1085 + pstate->rotation & 1086 + (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270) && 1087 + (fb->pitches[0] << 3) / vop2_get_bpp(fb->format) % 64) { 1088 + drm_dbg_kms(vop2->drm, 1089 + "AFBC buffers must be 64-pixel aligned for horizontal rotation or mirroring\n"); 1054 1090 return -EINVAL; 1055 1091 } 1056 1092 ··· 1195 1179 return; 1196 1180 } 1197 1181 1198 - afbc_en = rockchip_afbc(plane, fb->modifier); 1182 + afbc_en = drm_is_afbc(fb->modifier); 1199 1183 1200 1184 offset = (src->x1 >> 16) * fb->format->cpp[0]; 1201 1185 ··· 1229 1213 src_w = drm_rect_width(src) >> 16; 1230 1214 src_h = drm_rect_height(src) >> 16; 1231 1215 dsp_w = drm_rect_width(dest); 1232 - 1233 - if (dest->x1 + dsp_w > adjusted_mode->hdisplay) { 1234 - drm_dbg_kms(vop2->drm, 1235 - "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n", 1236 - vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay); 1237 - dsp_w = adjusted_mode->hdisplay - dest->x1; 1238 - if (dsp_w < 4) 1239 - dsp_w = 4; 1240 - src_w = dsp_w * src_w / drm_rect_width(dest); 1241 - } 1242 - 1243 1216 dsp_h = drm_rect_height(dest); 1244 1217 1245 - if (dest->y1 + dsp_h > adjusted_mode->vdisplay) { 1246 - drm_dbg_kms(vop2->drm, 1247 - "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n", 1248 - vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay); 1249 - dsp_h = adjusted_mode->vdisplay - dest->y1; 1250 - if (dsp_h < 4) 1251 - dsp_h = 4; 1252 - src_h = dsp_h * src_h / drm_rect_height(dest); 1253 - } 1254 - 1255 - /* 1256 - * This is workaround solution for IC design: 1257 - * esmart can't support scale down when src_w % 16 == 1. 1218 + /* drm_atomic_helper_check_plane_state calls drm_rect_clip_scaled for 1219 + * us, which keeps our planes bounded within the CRTC active area 1258 1220 */ 1259 - if (!(win->data->feature & WIN_FEATURE_AFBDC)) { 1260 - if (src_w > dsp_w && (src_w & 0xf) == 1) { 1261 - drm_dbg_kms(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n", 1262 - vp->id, win->data->name, src_w); 1263 - src_w -= 1; 1264 - } 1265 - } 1221 + if (WARN_ON(dest->x1 + dsp_w > adjusted_mode->hdisplay) || 1222 + WARN_ON(dest->y1 + dsp_h > adjusted_mode->vdisplay) || 1223 + WARN_ON(dsp_w < 4) || WARN_ON(dsp_h < 4) || 1224 + WARN_ON(src_w < 4) || WARN_ON(src_h < 4)) 1225 + return; 1266 1226 1267 - if (afbc_en && src_w % 4) { 1268 - drm_dbg_kms(vop2->drm, "vp%d %s src_w[%d] not 4 pixel aligned\n", 1269 - vp->id, win->data->name, src_w); 1270 - src_w = ALIGN_DOWN(src_w, 4); 1271 - } 1227 + if (vop2->version == VOP_VERSION_RK3568 && drm_is_afbc(fb->modifier)) 1228 + if (WARN_ON(src_w % 4)) 1229 + return; 1272 1230 1273 1231 act_info = (src_h - 1) << 16 | ((src_w - 1) & 0xffff); 1274 1232 dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff); ··· 1287 1297 * with WIN_VIR_STRIDE. 1288 1298 */ 1289 1299 stride = (fb->pitches[0] << 3) / bpp; 1290 - if ((stride & 0x3f) && (xmirror || rotate_90 || rotate_270)) 1291 - drm_dbg_kms(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n", 1292 - vp->id, win->data->name, stride); 1293 1300 1294 1301 /* It's for head stride, each head size is 16 byte */ 1295 1302 stride = ALIGN(stride, block_w) / block_w * 16;
+57
drivers/gpu/drm/rockchip/rockchip_vop_reg.c
··· 1180 1180 .max_output = { 4096, 2160 }, 1181 1181 }; 1182 1182 1183 + static const struct vop_common rk3506_common = { 1184 + .standby = VOP_REG_SYNC(RK3506_SYS_CTRL2, 0x1, 1), 1185 + .out_mode = VOP_REG(RK3506_DSP_CTRL2, 0xf, 16), 1186 + .dsp_blank = VOP_REG(RK3506_DSP_CTRL2, 0x1, 14), 1187 + .dither_down_en = VOP_REG(RK3506_DSP_CTRL2, 0x1, 8), 1188 + .dither_down_sel = VOP_REG(RK3506_DSP_CTRL2, 0x1, 7), 1189 + .dither_down_mode = VOP_REG(RK3506_DSP_CTRL2, 0x1, 6), 1190 + .dsp_lut_en = VOP_REG(RK3506_DSP_CTRL2, 0x1, 5), 1191 + .dither_up = VOP_REG(RK3506_DSP_CTRL2, 0x1, 2), 1192 + .cfg_done = VOP_REG_SYNC(RK3506_REG_CFG_DONE, 0x1, 0), 1193 + }; 1194 + 1195 + static const struct vop_output rk3506_output = { 1196 + .rgb_en = VOP_REG(RK3506_DSP_CTRL0, 0x1, 0), 1197 + .rgb_pin_pol = VOP_REG(RK3506_DSP_CTRL0, 0x7, 2), 1198 + .mipi_en = VOP_REG(RK3506_DSP_CTRL0, 0x1, 24), 1199 + .mipi_dclk_pol = VOP_REG(RK3506_DSP_CTRL0, 0x1, 25), 1200 + .mipi_pin_pol = VOP_REG(RK3506_DSP_CTRL0, 0x7, 26), 1201 + }; 1202 + 1203 + static const struct vop_win_phy rk3506_win1_data = { 1204 + .data_formats = formats_win_lite, 1205 + .nformats = ARRAY_SIZE(formats_win_lite), 1206 + .format_modifiers = format_modifiers_win_lite, 1207 + .enable = VOP_REG(RK3506_WIN1_CTRL0, 0x1, 0), 1208 + .format = VOP_REG(RK3506_WIN1_CTRL0, 0x7, 4), 1209 + .rb_swap = VOP_REG(RK3506_WIN1_CTRL0, 0x1, 12), 1210 + .channel = VOP_REG(RK3506_WIN1_CTRL1, 0xf, 8), 1211 + .yrgb_vir = VOP_REG(RK3506_WIN1_VIR, 0x1fff, 0), 1212 + .yrgb_mst = VOP_REG(RK3506_WIN1_MST, 0xffffffff, 0), 1213 + .dsp_info = VOP_REG(RK3506_WIN1_DSP_INFO, 0xffffffff, 0), 1214 + .dsp_st = VOP_REG(RK3506_WIN1_DSP_ST, 0xffffffff, 0), 1215 + .alpha_en = VOP_REG(RK3506_WIN1_ALPHA_CTRL, 0x1, 0), 1216 + .alpha_mode = VOP_REG(RK3506_WIN1_ALPHA_CTRL, 0x1, 1), 1217 + .alpha_pre_mul = VOP_REG(RK3506_WIN1_ALPHA_CTRL, 0x1, 2), 1218 + }; 1219 + 1220 + static const struct vop_win_data rk3506_vop_win_data[] = { 1221 + { .base = 0x00, .phy = &rk3506_win1_data, 1222 + .type = DRM_PLANE_TYPE_PRIMARY }, 1223 + }; 1224 + 1225 + static const struct vop_data rk3506_vop = { 1226 + .version = VOP_VERSION(2, 0xe), 1227 + .feature = VOP_FEATURE_INTERNAL_RGB, 1228 + .intr = &px30_intr, 1229 + .common = &rk3506_common, 1230 + .modeset = &px30_modeset, 1231 + .output = &rk3506_output, 1232 + .win = rk3506_vop_win_data, 1233 + .win_size = ARRAY_SIZE(rk3506_vop_win_data), 1234 + .lut_size = 256, 1235 + .max_output = { 1280, 1280 }, 1236 + }; 1237 + 1183 1238 static const struct vop_common rv1126_common = { 1184 1239 .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1), 1185 1240 .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16), ··· 1315 1260 .data = &rk3228_vop }, 1316 1261 { .compatible = "rockchip,rk3328-vop", 1317 1262 .data = &rk3328_vop }, 1263 + { .compatible = "rockchip,rk3506-vop", 1264 + .data = &rk3506_vop }, 1318 1265 { .compatible = "rockchip,rv1126-vop", 1319 1266 .data = &rv1126_vop }, 1320 1267 {},
+14
drivers/gpu/drm/rockchip/rockchip_vop_reg.h
··· 1033 1033 #define RK3066_DSP_LUT_ADDR 0x800 1034 1034 /* rk3066 register definition end */ 1035 1035 1036 + /* rk3506 register definition */ 1037 + #define RK3506_REG_CFG_DONE 0x00 1038 + #define RK3506_SYS_CTRL2 0x18 1039 + #define RK3506_DSP_CTRL0 0x20 1040 + #define RK3506_DSP_CTRL2 0x28 1041 + #define RK3506_WIN1_CTRL0 0x90 1042 + #define RK3506_WIN1_CTRL1 0x94 1043 + #define RK3506_WIN1_VIR 0x98 1044 + #define RK3506_WIN1_MST 0xa0 1045 + #define RK3506_WIN1_DSP_INFO 0xa4 1046 + #define RK3506_WIN1_DSP_ST 0xa8 1047 + #define RK3506_WIN1_ALPHA_CTRL 0xbc 1048 + /* rk3506 register definition end */ 1049 + 1036 1050 #endif /* _ROCKCHIP_VOP_REG_H */
+1 -3
drivers/gpu/drm/tegra/drm.c
··· 1301 1301 return err; 1302 1302 } 1303 1303 1304 - static int host1x_drm_remove(struct host1x_device *dev) 1304 + static void host1x_drm_remove(struct host1x_device *dev) 1305 1305 { 1306 1306 struct drm_device *drm = dev_get_drvdata(&dev->dev); 1307 1307 struct tegra_drm *tegra = drm->dev_private; ··· 1330 1330 1331 1331 kfree(tegra); 1332 1332 drm_dev_put(drm); 1333 - 1334 - return 0; 1335 1333 } 1336 1334 1337 1335 static void host1x_drm_shutdown(struct host1x_device *dev)
+2 -4
drivers/gpu/drm/tegra/dsi.c
··· 1542 1542 return -EPROBE_DEFER; 1543 1543 1544 1544 dsi->slave = platform_get_drvdata(gangster); 1545 - 1546 - if (!dsi->slave) { 1547 - put_device(&gangster->dev); 1545 + put_device(&gangster->dev); 1546 + if (!dsi->slave) 1548 1547 return -EPROBE_DEFER; 1549 - } 1550 1548 1551 1549 dsi->slave->master = dsi; 1552 1550 }
+2 -2
drivers/gpu/drm/xe/xe_vm.c
··· 1044 1044 1045 1045 xe_bo_assert_held(bo); 1046 1046 1047 - vm_bo = drm_gpuvm_bo_obtain(vma->gpuva.vm, &bo->ttm.base); 1047 + vm_bo = drm_gpuvm_bo_obtain_locked(vma->gpuva.vm, &bo->ttm.base); 1048 1048 if (IS_ERR(vm_bo)) { 1049 1049 xe_vma_free(vma); 1050 1050 return ERR_CAST(vm_bo); ··· 2301 2301 if (err) 2302 2302 return ERR_PTR(err); 2303 2303 2304 - vm_bo = drm_gpuvm_bo_obtain(&vm->gpuvm, obj); 2304 + vm_bo = drm_gpuvm_bo_obtain_locked(&vm->gpuvm, obj); 2305 2305 if (IS_ERR(vm_bo)) { 2306 2306 xe_bo_unlock(bo); 2307 2307 return ERR_CAST(vm_bo);
+33 -34
drivers/gpu/host1x/bus.c
··· 346 346 return 0; 347 347 } 348 348 349 + static int host1x_device_probe(struct device *dev) 350 + { 351 + struct host1x_driver *driver = to_host1x_driver(dev->driver); 352 + struct host1x_device *device = to_host1x_device(dev); 353 + 354 + if (driver->probe) 355 + return driver->probe(device); 356 + 357 + return 0; 358 + } 359 + 360 + static void host1x_device_remove(struct device *dev) 361 + { 362 + struct host1x_driver *driver = to_host1x_driver(dev->driver); 363 + struct host1x_device *device = to_host1x_device(dev); 364 + 365 + if (driver->remove) 366 + driver->remove(device); 367 + } 368 + 369 + static void host1x_device_shutdown(struct device *dev) 370 + { 371 + struct host1x_driver *driver = to_host1x_driver(dev->driver); 372 + struct host1x_device *device = to_host1x_device(dev); 373 + 374 + if (dev->driver && driver->shutdown) 375 + driver->shutdown(device); 376 + } 377 + 378 + 349 379 static const struct dev_pm_ops host1x_device_pm_ops = { 350 380 .suspend = pm_generic_suspend, 351 381 .resume = pm_generic_resume, ··· 389 359 .name = "host1x", 390 360 .match = host1x_device_match, 391 361 .uevent = host1x_device_uevent, 362 + .probe = host1x_device_probe, 363 + .remove = host1x_device_remove, 364 + .shutdown = host1x_device_shutdown, 392 365 .pm = &host1x_device_pm_ops, 393 366 }; 394 367 ··· 656 623 return 0; 657 624 } 658 625 659 - static int host1x_device_probe(struct device *dev) 660 - { 661 - struct host1x_driver *driver = to_host1x_driver(dev->driver); 662 - struct host1x_device *device = to_host1x_device(dev); 663 - 664 - if (driver->probe) 665 - return driver->probe(device); 666 - 667 - return 0; 668 - } 669 - 670 - static int host1x_device_remove(struct device *dev) 671 - { 672 - struct host1x_driver *driver = to_host1x_driver(dev->driver); 673 - struct host1x_device *device = to_host1x_device(dev); 674 - 675 - if (driver->remove) 676 - return driver->remove(device); 677 - 678 - return 0; 679 - } 680 - 681 - static void host1x_device_shutdown(struct device *dev) 682 - { 683 - struct host1x_driver *driver = to_host1x_driver(dev->driver); 684 - struct host1x_device *device = to_host1x_device(dev); 685 - 686 - if (driver->shutdown) 687 - driver->shutdown(device); 688 - } 689 - 690 626 /** 691 627 * host1x_driver_register_full() - register a host1x driver 692 628 * @driver: host1x driver ··· 686 684 687 685 driver->driver.bus = &host1x_bus_type; 688 686 driver->driver.owner = owner; 689 - driver->driver.probe = host1x_device_probe; 690 - driver->driver.remove = host1x_device_remove; 691 - driver->driver.shutdown = host1x_device_shutdown; 692 687 693 688 return driver_register(&driver->driver); 694 689 }
+1 -3
drivers/staging/media/tegra-video/video.c
··· 107 107 return ret; 108 108 } 109 109 110 - static int host1x_video_remove(struct host1x_device *dev) 110 + static void host1x_video_remove(struct host1x_device *dev) 111 111 { 112 112 struct tegra_video_device *vid = dev_get_drvdata(&dev->dev); 113 113 ··· 118 118 119 119 /* This calls v4l2_dev release callback on last reference */ 120 120 v4l2_device_put(&vid->v4l2_dev); 121 - 122 - return 0; 123 121 } 124 122 125 123 static const struct of_device_id host1x_video_subdevs[] = {
+6 -6
include/drm/drm_gpuvm.h
··· 736 736 struct drm_gem_object *obj); 737 737 738 738 struct drm_gpuvm_bo * 739 - drm_gpuvm_bo_obtain(struct drm_gpuvm *gpuvm, 740 - struct drm_gem_object *obj); 739 + drm_gpuvm_bo_obtain_locked(struct drm_gpuvm *gpuvm, 740 + struct drm_gem_object *obj); 741 741 struct drm_gpuvm_bo * 742 742 drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *vm_bo); 743 743 ··· 1121 1121 struct drm_gpuva_ops *ops); 1122 1122 1123 1123 static inline void drm_gpuva_init_from_op(struct drm_gpuva *va, 1124 - struct drm_gpuva_op_map *op) 1124 + const struct drm_gpuva_op_map *op) 1125 1125 { 1126 1126 va->va.addr = op->va.addr; 1127 1127 va->va.range = op->va.range; ··· 1265 1265 1266 1266 void drm_gpuva_map(struct drm_gpuvm *gpuvm, 1267 1267 struct drm_gpuva *va, 1268 - struct drm_gpuva_op_map *op); 1268 + const struct drm_gpuva_op_map *op); 1269 1269 1270 1270 void drm_gpuva_remap(struct drm_gpuva *prev, 1271 1271 struct drm_gpuva *next, 1272 - struct drm_gpuva_op_remap *op); 1272 + const struct drm_gpuva_op_remap *op); 1273 1273 1274 - void drm_gpuva_unmap(struct drm_gpuva_op_unmap *op); 1274 + void drm_gpuva_unmap(const struct drm_gpuva_op_unmap *op); 1275 1275 1276 1276 /** 1277 1277 * drm_gpuva_op_remap_to_unmap_range() - Helper to get the start and range of
+3
include/drm/drm_mode_object.h
··· 133 133 int drm_object_property_get_default_value(struct drm_mode_object *obj, 134 134 struct drm_property *property, 135 135 uint64_t *val); 136 + int drm_object_immutable_property_get_value(struct drm_mode_object *obj, 137 + struct drm_property *property, 138 + uint64_t *val); 136 139 137 140 void drm_object_attach_property(struct drm_mode_object *obj, 138 141 struct drm_property *property,
+1
include/drm/drm_property.h
··· 284 284 uint64_t blob_id, 285 285 ssize_t expected_size, 286 286 ssize_t expected_elem_size, 287 + ssize_t max_size, 287 288 bool *replaced); 288 289 int drm_property_replace_global_blob(struct drm_device *dev, 289 290 struct drm_property_blob **replace,
+1 -1
include/linux/host1x.h
··· 380 380 struct list_head list; 381 381 382 382 int (*probe)(struct host1x_device *device); 383 - int (*remove)(struct host1x_device *device); 383 + void (*remove)(struct host1x_device *device); 384 384 void (*shutdown)(struct host1x_device *device); 385 385 }; 386 386
+74 -24
include/uapi/drm/rocket_accel.h
··· 26 26 * 27 27 */ 28 28 struct drm_rocket_create_bo { 29 - /** Input: Size of the requested BO. */ 29 + /** 30 + * @size: Input: Size of the requested BO. 31 + */ 30 32 __u32 size; 31 33 32 - /** Output: GEM handle for the BO. */ 34 + /** 35 + * @handle: Output: GEM handle for the BO. 36 + */ 33 37 __u32 handle; 34 38 35 39 /** 36 - * Output: DMA address for the BO in the NPU address space. This address 37 - * is private to the DRM fd and is valid for the lifetime of the GEM 38 - * handle. 40 + * @dma_address: Output: DMA address for the BO in the NPU address 41 + * space. This address is private to the DRM fd and is valid for 42 + * the lifetime of the GEM handle. 39 43 */ 40 44 __u64 dma_address; 41 45 42 - /** Output: Offset into the drm node to use for subsequent mmap call. */ 46 + /** 47 + * @offset: Output: Offset into the drm node to use for subsequent 48 + * mmap call. 49 + */ 43 50 __u64 offset; 44 51 }; 45 52 ··· 57 50 * synchronization. 58 51 */ 59 52 struct drm_rocket_prep_bo { 60 - /** Input: GEM handle of the buffer object. */ 53 + /** 54 + * @handle: Input: GEM handle of the buffer object. 55 + */ 61 56 __u32 handle; 62 57 63 - /** Reserved, must be zero. */ 58 + /** 59 + * @reserved: Reserved, must be zero. 60 + */ 64 61 __u32 reserved; 65 62 66 - /** Input: Amount of time to wait for NPU jobs. */ 63 + /** 64 + * @timeout_ns: Input: Amount of time to wait for NPU jobs. 65 + */ 67 66 __s64 timeout_ns; 68 67 }; 69 68 ··· 79 66 * Synchronize caches for NPU access. 80 67 */ 81 68 struct drm_rocket_fini_bo { 82 - /** Input: GEM handle of the buffer object. */ 69 + /** 70 + * @handle: Input: GEM handle of the buffer object. 71 + */ 83 72 __u32 handle; 84 73 85 - /** Reserved, must be zero. */ 74 + /** 75 + * @reserved: Reserved, must be zero. 76 + */ 86 77 __u32 reserved; 87 78 }; 88 79 ··· 96 79 * A task is the smallest unit of work that can be run on the NPU. 97 80 */ 98 81 struct drm_rocket_task { 99 - /** Input: DMA address to NPU mapping of register command buffer */ 82 + /** 83 + * @regcmd: Input: DMA address to NPU mapping of register command buffer 84 + */ 100 85 __u32 regcmd; 101 86 102 - /** Input: Number of commands in the register command buffer */ 87 + /** 88 + * @regcmd_count: Input: Number of commands in the register command 89 + * buffer 90 + */ 103 91 __u32 regcmd_count; 104 92 }; 105 93 ··· 116 94 * sequentially on the same core, to benefit from memory residency in SRAM. 117 95 */ 118 96 struct drm_rocket_job { 119 - /** Input: Pointer to an array of struct drm_rocket_task. */ 97 + /** 98 + * @tasks: Input: Pointer to an array of struct drm_rocket_task. 99 + */ 120 100 __u64 tasks; 121 101 122 - /** Input: Pointer to a u32 array of the BOs that are read by the job. */ 102 + /** 103 + * @in_bo_handles: Input: Pointer to a u32 array of the BOs that 104 + * are read by the job. 105 + */ 123 106 __u64 in_bo_handles; 124 107 125 - /** Input: Pointer to a u32 array of the BOs that are written to by the job. */ 108 + /** 109 + * @out_bo_handles: Input: Pointer to a u32 array of the BOs that 110 + * are written to by the job. 111 + */ 126 112 __u64 out_bo_handles; 127 113 128 - /** Input: Number of tasks passed in. */ 114 + /** 115 + * @task_count: Input: Number of tasks passed in. 116 + */ 129 117 __u32 task_count; 130 118 131 - /** Input: Size in bytes of the structs in the @tasks field. */ 119 + /** 120 + * @task_struct_size: Input: Size in bytes of the structs in the 121 + * @tasks field. 122 + */ 132 123 __u32 task_struct_size; 133 124 134 - /** Input: Number of input BO handles passed in (size is that times 4). */ 125 + /** 126 + * @in_bo_handle_count: Input: Number of input BO handles passed in 127 + * (size is that times 4). 128 + */ 135 129 __u32 in_bo_handle_count; 136 130 137 - /** Input: Number of output BO handles passed in (size is that times 4). */ 131 + /** 132 + * @out_bo_handle_count: Input: Number of output BO handles passed in 133 + * (size is that times 4). 134 + */ 138 135 __u32 out_bo_handle_count; 139 136 }; 140 137 ··· 163 122 * The kernel will schedule the execution of these jobs in dependency order. 164 123 */ 165 124 struct drm_rocket_submit { 166 - /** Input: Pointer to an array of struct drm_rocket_job. */ 125 + /** 126 + * @jobs: Input: Pointer to an array of struct drm_rocket_job. 127 + */ 167 128 __u64 jobs; 168 129 169 - /** Input: Number of jobs passed in. */ 130 + /** 131 + * @job_count: Input: Number of jobs passed in. 132 + */ 170 133 __u32 job_count; 171 134 172 - /** Input: Size in bytes of the structs in the @jobs field. */ 135 + /** 136 + * @job_struct_size: Input: Size in bytes of the structs in the 137 + * @jobs field. 138 + */ 173 139 __u32 job_struct_size; 174 140 175 - /** Reserved, must be zero. */ 141 + /** 142 + * @reserved: Reserved, must be zero. 143 + */ 176 144 __u64 reserved; 177 145 }; 178 146