From 352683ea52e3f299a72899c9ee059190c9f769a8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 2 Feb 2023 11:23:32 +0100 Subject: [PATCH 1/8] drm/vc4: allow DRM_VC4_KUNIT_TEST to be a loadable module In configurations with CONFIG_KUNIT=m, builting the unit test into the kernel causes a link failure: arm-linux-gnueabi-ld: drivers/gpu/drm/vc4/tests/vc4_mock.o: in function `__build_mock': vc4_mock.c:(.text+0x6e): undefined reference to `kunit_do_failed_assertion' arm-linux-gnueabi-ld: vc4_mock.c:(.text+0x9c): undefined reference to `kunit_do_failed_assertion' arm-linux-gnueabi-ld: vc4_mock.c:(.text+0x100): undefined reference to `kunit_ptr_not_err_assert_format' ... Allow this to be a loadable module as well to have Kconfig sort out the dependencies correctly. Fixes: f759f5b53f1c ("drm/vc4: tests: Introduce a mocking infrastructure") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20230202102346.868771-1-arnd@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig index f423941c028d..91dcf8d174d6 100644 --- a/drivers/gpu/drm/vc4/Kconfig +++ b/drivers/gpu/drm/vc4/Kconfig @@ -36,7 +36,7 @@ config DRM_VC4_HDMI_CEC and want to use CEC. config DRM_VC4_KUNIT_TEST - bool "KUnit tests for VC4" if !KUNIT_ALL_TESTS + tristate "KUnit tests for VC4" if !KUNIT_ALL_TESTS depends on DRM_VC4 && KUNIT select DRM_KUNIT_TEST_HELPERS default KUNIT_ALL_TESTS From 98d4187113d494cebb15f52a715d3091b2de1b4a Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Thu, 2 Feb 2023 10:21:11 +0100 Subject: [PATCH 2/8] accel/ivpu: Fix FW API data alignment issues FW API structures have been updated to fix misaligned structure members. Also changed JSM message header format to account for future improvements. Added explicit check for minimum supported JSM API version. Fixes: 5d7422cfb498 ("accel/ivpu: Add IPC driver and JSM messages") Signed-off-by: Andrzej Kacprowski Signed-off-by: Stanislaw Gruszka Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20230202092114.2637452-2-stanislaw.gruszka@linux.intel.com (cherry picked from commit 4ea1e504db5b776892e2f5b0c5f05af6a046286b) Signed-off-by: Jacek Lawrynowicz --- drivers/accel/ivpu/ivpu_fw.c | 37 +++++++++++------- drivers/accel/ivpu/ivpu_job.c | 5 ++- drivers/accel/ivpu/vpu_jsm_api.h | 67 ++++++++++++++++++-------------- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index b463c24adb70..f58951a0d81b 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -32,10 +32,11 @@ #define ADDR_TO_L2_CACHE_CFG(addr) ((addr) >> 31) -#define IVPU_FW_CHECK_API(vdev, fw_hdr, name) ivpu_fw_check_api(vdev, fw_hdr, #name, \ - VPU_##name##_API_VER_INDEX, \ - VPU_##name##_API_VER_MAJOR, \ - VPU_##name##_API_VER_MINOR) +#define IVPU_FW_CHECK_API(vdev, fw_hdr, name, min_major) \ + ivpu_fw_check_api(vdev, fw_hdr, #name, \ + VPU_##name##_API_VER_INDEX, \ + VPU_##name##_API_VER_MAJOR, \ + VPU_##name##_API_VER_MINOR, min_major) static char *ivpu_firmware; module_param_named_unsafe(firmware, ivpu_firmware, charp, 0644); @@ -63,19 +64,27 @@ static int ivpu_fw_request(struct ivpu_device *vdev) return ret; } -static void +static int ivpu_fw_check_api(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr, - const char *str, int index, u16 expected_major, u16 expected_minor) + const char *str, int index, u16 expected_major, u16 expected_minor, + u16 min_major) { u16 major = (u16)(fw_hdr->api_version[index] >> 16); u16 minor = (u16)(fw_hdr->api_version[index]); + if (major < min_major) { + ivpu_err(vdev, "Incompatible FW %s API version: %d.%d, required %d.0 or later\n", + str, major, minor, min_major); + return -EINVAL; + } if (major != expected_major) { - ivpu_warn(vdev, "Incompatible FW %s API version: %d.%d (expected %d.%d)\n", + ivpu_warn(vdev, "Major FW %s API version different: %d.%d (expected %d.%d)\n", str, major, minor, expected_major, expected_minor); } ivpu_dbg(vdev, FW_BOOT, "FW %s API version: %d.%d (expected %d.%d)\n", str, major, minor, expected_major, expected_minor); + + return 0; } static int ivpu_fw_parse(struct ivpu_device *vdev) @@ -131,6 +140,14 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) ivpu_err(vdev, "Invalid entry point: 0x%llx\n", fw_hdr->entry_point); return -EINVAL; } + ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n", + fw_hdr->header_version, fw_hdr->image_format); + ivpu_dbg(vdev, FW_BOOT, "FW version: %s\n", (char *)fw_hdr + VPU_FW_HEADER_SIZE); + + if (IVPU_FW_CHECK_API(vdev, fw_hdr, BOOT, 3)) + return -EINVAL; + if (IVPU_FW_CHECK_API(vdev, fw_hdr, JSM, 3)) + return -EINVAL; fw->runtime_addr = runtime_addr; fw->runtime_size = runtime_size; @@ -141,16 +158,10 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->cold_boot_entry_point = fw_hdr->entry_point; fw->entry_point = fw->cold_boot_entry_point; - ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n", - fw_hdr->header_version, fw_hdr->image_format); ivpu_dbg(vdev, FW_BOOT, "Size: file %lu image %u runtime %u shavenn %u\n", fw->file->size, fw->image_size, fw->runtime_size, fw->shave_nn_size); ivpu_dbg(vdev, FW_BOOT, "Address: runtime 0x%llx, load 0x%llx, entry point 0x%llx\n", fw->runtime_addr, image_load_addr, fw->entry_point); - ivpu_dbg(vdev, FW_BOOT, "FW version: %s\n", (char *)fw_hdr + VPU_FW_HEADER_SIZE); - - IVPU_FW_CHECK_API(vdev, fw_hdr, BOOT); - IVPU_FW_CHECK_API(vdev, fw_hdr, JSM); return 0; } diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 3276bd9107b4..94068aedf97c 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -400,8 +400,9 @@ static int ivpu_direct_job_submission(struct ivpu_job *job) if (ret) goto err_xa_erase; - ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d next %d\n", - job->job_id, file_priv->ctx.id, job->engine_idx, cmdq->jobq->header.tail); + ivpu_dbg(vdev, JOB, "Job submitted: id %3u addr 0x%llx ctx %2d engine %d next %d\n", + job->job_id, job->cmd_buf_vpu_addr, file_priv->ctx.id, + job->engine_idx, cmdq->jobq->header.tail); if (ivpu_test_mode == IVPU_TEST_MODE_NULL_HW) { ivpu_job_done(vdev, job->job_id, VPU_JSM_STATUS_SUCCESS); diff --git a/drivers/accel/ivpu/vpu_jsm_api.h b/drivers/accel/ivpu/vpu_jsm_api.h index 1096cab0334e..2949ec8365bd 100644 --- a/drivers/accel/ivpu/vpu_jsm_api.h +++ b/drivers/accel/ivpu/vpu_jsm_api.h @@ -17,12 +17,12 @@ /* * Major version changes that break backward compatibility */ -#define VPU_JSM_API_VER_MAJOR 2 +#define VPU_JSM_API_VER_MAJOR 3 /* * Minor version changes when API backward compatibility is preserved. */ -#define VPU_JSM_API_VER_MINOR 10 +#define VPU_JSM_API_VER_MINOR 0 /* * API header changed (field names, documentation, formatting) but API itself has not been changed @@ -103,10 +103,10 @@ /* * Max length (including trailing NULL char) of a dyndbg command. * - * NOTE: 112 is used so that the size of 'struct vpu_ipc_msg' in the JSM API is + * NOTE: 96 is used so that the size of 'struct vpu_ipc_msg' in the JSM API is * 128 bytes (multiple of 64 bytes, the cache line size). */ -#define VPU_DYNDBG_CMD_MAX_LEN 112 +#define VPU_DYNDBG_CMD_MAX_LEN 96 /* * Job format. @@ -119,7 +119,7 @@ struct vpu_job_queue_entry { u64 root_page_table_update_counter; /**< Page tables update events counter */ u64 preemption_buffer_address; /**< Address of the preemption buffer to use for this job */ u64 preemption_buffer_size; /**< Size of the preemption buffer to use for this job */ - u8 reserved[VPU_JOB_RESERVED_BYTES]; + u8 reserved_0[VPU_JOB_RESERVED_BYTES]; }; /* @@ -129,7 +129,7 @@ struct vpu_job_queue_header { u32 engine_idx; u32 head; u32 tail; - u8 reserved[VPU_JOB_QUEUE_RESERVED_BYTES]; + u8 reserved_0[VPU_JOB_QUEUE_RESERVED_BYTES]; }; /* @@ -319,6 +319,8 @@ enum vpu_ipc_msg_status { VPU_JSM_MSG_FREE, VPU_JSM_MSG_ALLOCATED }; struct vpu_ipc_msg_payload_engine_reset { /* Engine to be reset. */ u32 engine_idx; + /* Reserved */ + u32 reserved_0; }; struct vpu_ipc_msg_payload_engine_preempt { @@ -336,6 +338,8 @@ struct vpu_ipc_msg_payload_engine_preempt { struct vpu_ipc_msg_payload_register_db { /* Index of the doorbell to register. */ u32 db_idx; + /* Reserved */ + u32 reserved_0; /* Virtual address in Global GTT pointing to the start of job queue. */ u64 jobq_base; /* Size of the job queue in bytes. */ @@ -352,11 +356,15 @@ struct vpu_ipc_msg_payload_register_db { struct vpu_ipc_msg_payload_unregister_db { /* Index of the doorbell to unregister. */ u32 db_idx; + /* Reserved */ + u32 reserved_0; }; struct vpu_ipc_msg_payload_query_engine_hb { /* Engine to return heartbeat value. */ u32 engine_idx; + /* Reserved */ + u32 reserved_0; }; struct vpu_ipc_msg_payload_power_level { @@ -371,11 +379,15 @@ struct vpu_ipc_msg_payload_power_level { * considered to be valid. */ u32 power_level; + /* Reserved */ + u32 reserved_0; }; struct vpu_ipc_msg_payload_ssid_release { /* Host sub-stream ID for the context to be released. */ u32 host_ssid; + /* Reserved */ + u32 reserved_0; }; /** @@ -425,9 +437,6 @@ struct vpu_jsm_metric_streamer_start { u64 next_buffer_size; }; -static_assert(sizeof(struct vpu_jsm_metric_streamer_start) % 8 == 0, - "vpu_jsm_metric_streamer_start is misaligned"); - /** * @brief Metric streamer stop command structure. * @see VPU_JSM_MSG_METRIC_STREAMER_STOP @@ -437,9 +446,6 @@ struct vpu_jsm_metric_streamer_stop { u64 metric_group_mask; }; -static_assert(sizeof(struct vpu_jsm_metric_streamer_stop) % 8 == 0, - "vpu_jsm_metric_streamer_stop is misaligned"); - /** * Provide VPU FW with buffers to write metric data. * @see VPU_JSM_MSG_METRIC_STREAMER_UPDATE @@ -471,9 +477,6 @@ struct vpu_jsm_metric_streamer_update { u64 next_buffer_size; }; -static_assert(sizeof(struct vpu_jsm_metric_streamer_update) % 8 == 0, - "vpu_jsm_metric_streamer_update is misaligned"); - struct vpu_ipc_msg_payload_blob_deinit { /* 64-bit unique ID for the blob to be de-initialized. */ u64 blob_id; @@ -491,7 +494,7 @@ struct vpu_ipc_msg_payload_job_done { /* Host SSID */ u32 host_ssid; /* Zero Padding */ - u32 reserved; + u32 reserved_0; /* Command queue id */ u64 cmdq_id; }; @@ -500,7 +503,7 @@ struct vpu_jsm_engine_reset_context { /* Host SSID */ u32 host_ssid; /* Zero Padding */ - u32 reserved; + u32 reserved_0; /* Command queue id */ u64 cmdq_id; /* Flags: 0: cause of hang; 1: collateral damage of reset */ @@ -533,6 +536,8 @@ struct vpu_ipc_msg_payload_engine_preempt_done { struct vpu_ipc_msg_payload_register_db_done { /* Index of the registered doorbell. */ u32 db_idx; + /* Reserved */ + u32 reserved_0; }; /** @@ -543,11 +548,15 @@ struct vpu_ipc_msg_payload_register_db_done { struct vpu_ipc_msg_payload_unregister_db_done { /* Index of the unregistered doorbell. */ u32 db_idx; + /* Reserved */ + u32 reserved_0; }; struct vpu_ipc_msg_payload_query_engine_hb_done { /* Engine returning heartbeat value. */ u32 engine_idx; + /* Reserved */ + u32 reserved_0; /* Heartbeat value. */ u64 heartbeat; }; @@ -559,6 +568,8 @@ struct vpu_ipc_msg_payload_get_power_level_count_done { * implementations. */ u32 power_level_count; + /* Reserved */ + u32 reserved_0; /** * Power consumption limit for each supported power level in * [0-100%] range relative to power level 0. @@ -577,7 +588,7 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { * Grace period in 100ns units when preempting another priority band for * this priority band */ - u64 grace_period[VPU_HWS_NUM_PRIORITY_BANDS]; + u32 grace_period[VPU_HWS_NUM_PRIORITY_BANDS]; /* * Default quantum in 100ns units for scheduling across processes * within a priority band @@ -593,6 +604,8 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { * in situations when it's starved by the focus band. */ u32 normal_band_percentage; + /* Reserved */ + u32 reserved_0; }; /* HWS create command queue request */ @@ -609,6 +622,8 @@ struct vpu_ipc_msg_payload_hws_create_cmdq { u64 cmdq_base; /* Command queue size */ u32 cmdq_size; + /* Reserved */ + u32 reserved_0; }; /* HWS create command queue response */ @@ -806,9 +821,6 @@ struct vpu_jsm_metric_streamer_done { u64 bytes_written; }; -static_assert(sizeof(struct vpu_jsm_metric_streamer_done) % 8 == 0, - "vpu_jsm_metric_streamer_done is misaligned"); - /** * Metric group description placed in the metric buffer after successful completion * of the VPU_JSM_MSG_METRIC_STREAMER_INFO command. This is followed by one or more @@ -848,16 +860,13 @@ struct vpu_jsm_metric_group_descriptor { u32 name_string_size; /** Counter description string size, @see name_string_size */ u32 description_string_size; - u32 reserved_0[2]; + u64 reserved_0; /** * Right after this structure, the VPU writes name and description of * the metric group. */ }; -static_assert(sizeof(struct vpu_jsm_metric_group_descriptor) % 8 == 0, - "vpu_jsm_metric_group_descriptor is misaligned"); - /** * Metric counter description, placed in the buffer after vpu_jsm_metric_group_descriptor. * @see VPU_JSM_MSG_METRIC_STREAMER_INFO @@ -894,16 +903,13 @@ struct vpu_jsm_metric_counter_descriptor { u32 component_string_size; /** Counter string size, @see name_string_size */ u32 units_string_size; - u32 reserved_0[2]; + u64 reserved_0; /** * Right after this structure, the VPU writes name, description * component and unit strings. */ }; -static_assert(sizeof(struct vpu_jsm_metric_counter_descriptor) % 8 == 0, - "vpu_jsm_metric_counter_descriptor is misaligned"); - /** * Payload for VPU_JSM_MSG_DYNDBG_CONTROL requests. * @@ -977,6 +983,8 @@ union vpu_ipc_msg_payload { * to allow proper handling of VPU cache operations. */ struct vpu_jsm_msg { + /* Reserved */ + u64 reserved_0; /* Message type, see vpu_ipc_msg_type enum. */ u32 type; /* Buffer status, see vpu_ipc_msg_status enum. */ @@ -988,6 +996,7 @@ struct vpu_jsm_msg { u32 request_id; /* Request return code set by the VPU, see VPU_JSM_STATUS_* defines. */ u32 result; + u64 reserved_1; /* Message payload depending on message type, see vpu_ipc_msg_payload union. */ union vpu_ipc_msg_payload payload; }; From dffaa98c8bcf973e94a58d8f29c0254e003b538c Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Thu, 2 Feb 2023 10:21:12 +0100 Subject: [PATCH 3/8] accel/ivpu: Send VPU_JSM_MSG_CONTEXT_DELETE when deleting context The VPU_JSM_MSG_CONTEXT_DELETE will remove any resources associated with the SSID, that included any blobs create by the user space application. The command can also remove doorbell registrations, but since this does not work in HW scheduling case, we do not depend on this capability and unregister the doorbells explicitly. Fixes: cd7272215c44 ("accel/ivpu: Add command buffer submission logic") Signed-off-by: Andrzej Kacprowski Signed-off-by: Stanislaw Gruszka Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20230202092114.2637452-3-stanislaw.gruszka@linux.intel.com (cherry picked from commit 38257f514d85cd9d3f7586e768cec4f246635f77) Signed-off-by: Jacek Lawrynowicz --- drivers/accel/ivpu/ivpu_drv.c | 1 + drivers/accel/ivpu/ivpu_jsm_msg.c | 11 +++++++++++ drivers/accel/ivpu/ivpu_jsm_msg.h | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index a29e8ee0dce6..70c104851c6d 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -90,6 +90,7 @@ static void file_priv_release(struct kref *ref) ivpu_cmdq_release_all(file_priv); ivpu_bo_remove_all_bos_from_context(&file_priv->ctx); + ivpu_jsm_context_release(vdev, file_priv->ctx.id); ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); drm_WARN_ON(&vdev->drm, xa_erase_irq(&vdev->context_xa, file_priv->ctx.id) != file_priv); mutex_destroy(&file_priv->lock); diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index af77dafac97e..831bfd2b2d39 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -167,3 +167,14 @@ int ivpu_jsm_trace_set_config(struct ivpu_device *vdev, u32 trace_level, u32 tra return ret; } + +int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid) +{ + struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SSID_RELEASE }; + struct vpu_jsm_msg resp; + + req.payload.ssid_release.host_ssid = host_ssid; + + return ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); +} diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.h b/drivers/accel/ivpu/ivpu_jsm_msg.h index 1a3e2e2740bd..ab50d7b017c1 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.h +++ b/drivers/accel/ivpu/ivpu_jsm_msg.h @@ -19,5 +19,5 @@ int ivpu_jsm_trace_get_capability(struct ivpu_device *vdev, u32 *trace_destinati u64 *trace_hw_component_mask); int ivpu_jsm_trace_set_config(struct ivpu_device *vdev, u32 trace_level, u32 trace_destination_mask, u64 trace_hw_component_mask); - +int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid); #endif From 62079b6f2cf1e6356c6241cbdc5defdb0d66b4fe Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 2 Feb 2023 10:21:13 +0100 Subject: [PATCH 4/8] accel/ivpu: Set dma max_segment_size Avoid below spurious warning: [ 264.844029] DMA-API: intel_vpu 0000:00:0b.0: mapping sg segment longer than device claims to support [len=143360] [max=65536] [ 264.844038] WARNING: CPU: 0 PID: 1254 at kernel/dma/debug.c:1160 debug_dma_map_sg+0x6ca/0xb70 Fixes: 263b2ba5fc93 ("accel/ivpu: Add Intel VPU MMU support") Signed-off-by: Stanislaw Gruszka Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20230202092114.2637452-4-stanislaw.gruszka@linux.intel.com (cherry picked from commit 07ccb63a5c4cf860754666f1de030a0cbd5193b6) Signed-off-by: Jacek Lawrynowicz --- drivers/accel/ivpu/ivpu_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 70c104851c6d..231f29bb5025 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -428,6 +428,7 @@ static int ivpu_pci_init(struct ivpu_device *vdev) ivpu_err(vdev, "Failed to set DMA mask: %d\n", ret); return ret; } + dma_set_max_seg_size(vdev->drm.dev, UINT_MAX); /* Clear any pending errors */ pcie_capability_clear_word(pdev, PCI_EXP_DEVSTA, 0x3f); From d20a8f409259f1782f080b434054854020878f23 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 2 Feb 2023 10:21:14 +0100 Subject: [PATCH 5/8] accel/ivpu: Fix old dma_buf api usage Update according to new dma-buf locking scheme. Remove redundant WARN_ON()'s, dma_buf functions internally have the same warnings already. Fixes: 647371a6609d ("accel/ivpu: Add GEM buffer object management") Signed-off-by: Stanislaw Gruszka Reviewed-by: Jeffrey Hugo Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20230202092114.2637452-5-stanislaw.gruszka@linux.intel.com (cherry picked from commit ec6ec9c6ca637f7678f1931cb835b2bb8ab6dfd2) Signed-off-by: Jacek Lawrynowicz --- drivers/accel/ivpu/ivpu_gem.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index d1f923971b4c..01d47d3bad5b 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -42,9 +42,7 @@ static int prime_map_pages_locked(struct ivpu_bo *bo) struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); struct sg_table *sgt; - WARN_ON(!bo->base.import_attach); - - sgt = dma_buf_map_attachment(bo->base.import_attach, DMA_BIDIRECTIONAL); + sgt = dma_buf_map_attachment_unlocked(bo->base.import_attach, DMA_BIDIRECTIONAL); if (IS_ERR(sgt)) { ivpu_err(vdev, "Failed to map attachment: %ld\n", PTR_ERR(sgt)); return PTR_ERR(sgt); @@ -56,9 +54,7 @@ static int prime_map_pages_locked(struct ivpu_bo *bo) static void prime_unmap_pages_locked(struct ivpu_bo *bo) { - WARN_ON(!bo->base.import_attach); - - dma_buf_unmap_attachment(bo->base.import_attach, bo->sgt, DMA_BIDIRECTIONAL); + dma_buf_unmap_attachment_unlocked(bo->base.import_attach, bo->sgt, DMA_BIDIRECTIONAL); bo->sgt = NULL; } From 91f43949662c9eb4a443203a188e806df8290bc9 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 24 Jan 2023 12:45:47 +0200 Subject: [PATCH 6/8] drm/probe_helper: extract two helper functions Extract drm_kms_helper_enable_hpd() and drm_kms_helper_disable_hpd(), two helpers that enable and disable HPD handling on all device's connectors. Signed-off-by: Dmitry Baryshkov Reviewed-by: Neil Armstrong Reviewed-by: Jani Nikula Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230124104548.3234554-1-dmitry.baryshkov@linaro.org (cherry picked from commit cbf143b282c64e59559cc8351c0b5b1ab4bbdcbe) Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_probe_helper.c | 68 ++++++++++++++++++------------ 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 95aeeed33cf5..ab787d71fa66 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -222,6 +222,45 @@ drm_connector_mode_valid(struct drm_connector *connector, return ret; } +static void drm_kms_helper_disable_hpd(struct drm_device *dev) +{ + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + const struct drm_connector_helper_funcs *funcs = + connector->helper_private; + + if (funcs && funcs->disable_hpd) + funcs->disable_hpd(connector); + } + drm_connector_list_iter_end(&conn_iter); +} + +static bool drm_kms_helper_enable_hpd(struct drm_device *dev) +{ + bool poll = false; + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + const struct drm_connector_helper_funcs *funcs = + connector->helper_private; + + if (funcs && funcs->enable_hpd) + funcs->enable_hpd(connector); + + if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT)) + poll = true; + } + drm_connector_list_iter_end(&conn_iter); + + return poll; +} + #define DRM_OUTPUT_POLL_PERIOD (10*HZ) /** * drm_kms_helper_poll_enable - re-enable output polling. @@ -241,26 +280,12 @@ drm_connector_mode_valid(struct drm_connector *connector, void drm_kms_helper_poll_enable(struct drm_device *dev) { bool poll = false; - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; unsigned long delay = DRM_OUTPUT_POLL_PERIOD; if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) return; - drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { - const struct drm_connector_helper_funcs *funcs = - connector->helper_private; - - if (funcs && funcs->enable_hpd) - funcs->enable_hpd(connector); - - if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT)) - poll = true; - } - drm_connector_list_iter_end(&conn_iter); + poll = drm_kms_helper_enable_hpd(dev); if (dev->mode_config.delayed_event) { /* @@ -810,24 +835,13 @@ EXPORT_SYMBOL(drm_kms_helper_is_poll_worker); static void drm_kms_helper_poll_disable_fini(struct drm_device *dev, bool fini) { - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; - if (!dev->mode_config.poll_enabled) return; if (fini) dev->mode_config.poll_enabled = false; - drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { - const struct drm_connector_helper_funcs *funcs = - connector->helper_private; - - if (funcs && funcs->disable_hpd) - funcs->disable_hpd(connector); - } - drm_connector_list_iter_end(&conn_iter); + drm_kms_helper_disable_hpd(dev); cancel_delayed_work_sync(&dev->mode_config.output_poll_work); } From a4e771729a51168bc36317effaa9962e336d4f5e Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 24 Jan 2023 12:45:48 +0200 Subject: [PATCH 7/8] drm/probe_helper: sort out poll_running vs poll_enabled There are two flags attemting to guard connector polling: poll_enabled and poll_running. While poll_enabled semantics is clearly defined and fully adhered (mark that drm_kms_helper_poll_init() was called and not finalized by the _fini() call), the poll_running flag doesn't have such clearliness. This flag is used only in drm_helper_probe_single_connector_modes() to guard calling of drm_kms_helper_poll_enable, it doesn't guard the drm_kms_helper_poll_fini(), etc. Change it to only be set if the polling is actually running. Tie HPD enablement to this flag. This fixes the following warning reported after merging the HPD series: Hot plug detection already enabled WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_bridge.c:1257 drm_bridge_hpd_enable+0x94/0x9c [drm] Modules linked in: videobuf2_memops snd_soc_simple_card snd_soc_simple_card_utils fsl_imx8_ddr_perf videobuf2_common snd_soc_imx_spdif adv7511 etnaviv imx8m_ddrc imx_dcss mc cec nwl_dsi gov CPU: 2 PID: 9 Comm: kworker/u8:0 Not tainted 6.2.0-rc2-15208-g25b283acd578 #6 Hardware name: NXP i.MX8MQ EVK (DT) Workqueue: events_unbound deferred_probe_work_func pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : drm_bridge_hpd_enable+0x94/0x9c [drm] lr : drm_bridge_hpd_enable+0x94/0x9c [drm] sp : ffff800009ef3740 x29: ffff800009ef3740 x28: ffff000009331f00 x27: 0000000000001000 x26: 0000000000000020 x25: ffff800001148ed8 x24: ffff00000a8fe000 x23: 00000000fffffffd x22: ffff000005086348 x21: ffff800001133ee0 x20: ffff00000550d800 x19: ffff000005086288 x18: 0000000000000006 x17: 0000000000000000 x16: ffff8000096ef008 x15: 97ffff2891004260 x14: 2a1403e194000000 x13: 97ffff2891004260 x12: 2a1403e194000000 x11: 7100385f29400801 x10: 0000000000000aa0 x9 : ffff800008112744 x8 : ffff000000250b00 x7 : 0000000000000003 x6 : 0000000000000011 x5 : 0000000000000000 x4 : ffff0000bd986a48 x3 : 0000000000000001 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000000250000 Call trace: drm_bridge_hpd_enable+0x94/0x9c [drm] drm_bridge_connector_enable_hpd+0x2c/0x3c [drm_kms_helper] drm_kms_helper_poll_enable+0x94/0x10c [drm_kms_helper] drm_helper_probe_single_connector_modes+0x1a8/0x510 [drm_kms_helper] drm_client_modeset_probe+0x204/0x1190 [drm] __drm_fb_helper_initial_config_and_unlock+0x5c/0x4a4 [drm_kms_helper] drm_fb_helper_initial_config+0x54/0x6c [drm_kms_helper] drm_fbdev_client_hotplug+0xd0/0x140 [drm_kms_helper] drm_fbdev_generic_setup+0x90/0x154 [drm_kms_helper] dcss_kms_attach+0x1c8/0x254 [imx_dcss] dcss_drv_platform_probe+0x90/0xfc [imx_dcss] platform_probe+0x70/0xcc really_probe+0xc4/0x2e0 __driver_probe_device+0x80/0xf0 driver_probe_device+0xe0/0x164 __device_attach_driver+0xc0/0x13c bus_for_each_drv+0x84/0xe0 __device_attach+0xa4/0x1a0 device_initial_probe+0x1c/0x30 bus_probe_device+0xa4/0xb0 deferred_probe_work_func+0x90/0xd0 process_one_work+0x200/0x474 worker_thread+0x74/0x43c kthread+0xfc/0x110 ret_from_fork+0x10/0x20 ---[ end trace 0000000000000000 ]--- Reported-by: Laurentiu Palcu Fixes: c8268795c9a9 ("drm/probe-helper: enable and disable HPD on connectors") Tested-by: Marek Szyprowski Tested-by: Chen-Yu Tsai Acked-by: Laurentiu Palcu Tested-by: Laurentiu Palcu Tested-by: Laurent Pinchart Signed-off-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230124104548.3234554-2-dmitry.baryshkov@linaro.org (cherry picked from commit d33a54e3991dfce88b4fc6d9c3360951c2c5660d) Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_probe_helper.c | 42 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index ab787d71fa66..8127be134c39 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -282,7 +282,8 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) bool poll = false; unsigned long delay = DRM_OUTPUT_POLL_PERIOD; - if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) + if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll || + dev->mode_config.poll_running) return; poll = drm_kms_helper_enable_hpd(dev); @@ -304,6 +305,8 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) if (poll) schedule_delayed_work(&dev->mode_config.output_poll_work, delay); + + dev->mode_config.poll_running = true; } EXPORT_SYMBOL(drm_kms_helper_poll_enable); @@ -592,10 +595,7 @@ retry: } /* Re-enable polling in case the global poll config changed. */ - if (drm_kms_helper_poll != dev->mode_config.poll_running) - drm_kms_helper_poll_enable(dev); - - dev->mode_config.poll_running = drm_kms_helper_poll; + drm_kms_helper_poll_enable(dev); if (connector->status == connector_status_disconnected) { DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", @@ -735,8 +735,11 @@ static void output_poll_execute(struct work_struct *work) changed = dev->mode_config.delayed_event; dev->mode_config.delayed_event = false; - if (!drm_kms_helper_poll) + if (!drm_kms_helper_poll && dev->mode_config.poll_running) { + drm_kms_helper_disable_hpd(dev); + dev->mode_config.poll_running = false; goto out; + } if (!mutex_trylock(&dev->mode_config.mutex)) { repoll = true; @@ -833,19 +836,6 @@ bool drm_kms_helper_is_poll_worker(void) } EXPORT_SYMBOL(drm_kms_helper_is_poll_worker); -static void drm_kms_helper_poll_disable_fini(struct drm_device *dev, bool fini) -{ - if (!dev->mode_config.poll_enabled) - return; - - if (fini) - dev->mode_config.poll_enabled = false; - - drm_kms_helper_disable_hpd(dev); - - cancel_delayed_work_sync(&dev->mode_config.output_poll_work); -} - /** * drm_kms_helper_poll_disable - disable output polling * @dev: drm_device @@ -862,7 +852,12 @@ static void drm_kms_helper_poll_disable_fini(struct drm_device *dev, bool fini) */ void drm_kms_helper_poll_disable(struct drm_device *dev) { - drm_kms_helper_poll_disable_fini(dev, false); + if (dev->mode_config.poll_running) + drm_kms_helper_disable_hpd(dev); + + cancel_delayed_work_sync(&dev->mode_config.output_poll_work); + + dev->mode_config.poll_running = false; } EXPORT_SYMBOL(drm_kms_helper_poll_disable); @@ -900,7 +895,12 @@ EXPORT_SYMBOL(drm_kms_helper_poll_init); */ void drm_kms_helper_poll_fini(struct drm_device *dev) { - drm_kms_helper_poll_disable_fini(dev, true); + if (!dev->mode_config.poll_enabled) + return; + + drm_kms_helper_poll_disable(dev); + + dev->mode_config.poll_enabled = false; } EXPORT_SYMBOL(drm_kms_helper_poll_fini); From 467fbc77f673ecc9dcf4e58ffc1fa426a22df7fd Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 7 Feb 2023 11:04:36 +0100 Subject: [PATCH 8/8] dt-bindings: display: panel: visionox,vtdr6130: add missing reg property Add missing reg property and update example to add dsi top node. Fixes: ef85db911134 ("dt-bindings: display: panel: document the Visionox VTDR6130 AMOLED DSI Panel") Acked-by: Sam Ravnborg Acked-by: Rob Herring Reviewed-by: Krzysztof Kozlowski Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230207-topic-sm8550-upstream-vtdr6130-bindings-fix-v1-1-0ba2323420c5@linaro.org --- .../display/panel/visionox,vtdr6130.yaml | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml b/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml index 49e2fd4b4e99..84562a5b710a 100644 --- a/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml +++ b/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml @@ -16,6 +16,10 @@ properties: compatible: const: visionox,vtdr6130 + reg: + maxItems: 1 + description: DSI virtual channel + vddio-supply: true vci-supply: true vdd-supply: true @@ -26,6 +30,7 @@ additionalProperties: false required: - compatible + - reg - vddio-supply - vci-supply - vdd-supply @@ -35,18 +40,23 @@ required: examples: - | #include - panel { - compatible = "visionox,vtdr6130"; + dsi { + #address-cells = <1>; + #size-cells = <0>; + panel@0 { + compatible = "visionox,vtdr6130"; + reg = <0>; - vddio-supply = <&vreg_l12b_1p8>; - vci-supply = <&vreg_l13b_3p0>; - vdd-supply = <&vreg_l11b_1p2>; + vddio-supply = <&vreg_l12b_1p8>; + vci-supply = <&vreg_l13b_3p0>; + vdd-supply = <&vreg_l11b_1p2>; - reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>; + reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>; - port { - panel0_in: endpoint { - remote-endpoint = <&dsi0_out>; + port { + panel0_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; }; }; };