From d16ee2f176345effc9981b4e733633f4a8ac6fab Mon Sep 17 00:00:00 2001 From: Divyamani Tripathi Date: Thu, 13 Aug 2026 07:50:35 +0300 Subject: [PATCH] ipu7: Add IPU8 ABI version 1.0.14 and select it at runtime Tracked-On: #JSWBALINUX-155 Signed-off-by: Divyamani Tripathi --- .../pci/intel/ipu7/abi/ipu7_fw_isys_abi.h | 82 ++- drivers/media/pci/intel/ipu7/ipu7-fw-isys.c | 155 ++++- .../media/pci/intel/ipu7/ipu7-isys-queue.c | 10 +- .../media/pci/intel/ipu7/ipu7-isys-video.c | 32 +- drivers/media/pci/intel/ipu7/ipu7-isys.h | 9 + ...-IPU8-ABI-version-1.0.14-and-select-.patch | 569 ++++++++++++++++++ 6 files changed, 794 insertions(+), 63 deletions(-) create mode 100644 patch/v7.0.0/0008-staging-ipu7-Add-IPU8-ABI-version-1.0.14-and-select-.patch diff --git a/drivers/media/pci/intel/ipu7/abi/ipu7_fw_isys_abi.h b/drivers/media/pci/intel/ipu7/abi/ipu7_fw_isys_abi.h index f32674f..5d1e23a 100644 --- a/drivers/media/pci/intel/ipu7/abi/ipu7_fw_isys_abi.h +++ b/drivers/media/pci/intel/ipu7/abi/ipu7_fw_isys_abi.h @@ -125,6 +125,15 @@ enum ipu7_insys_frame_format_type { IPU_INSYS_FRAME_FORMAT_ARGB888 = 31, IPU_INSYS_FRAME_FORMAT_BGRA888 = 32, IPU_INSYS_FRAME_FORMAT_ABGR888 = 33, + IPU_INSYS_FRAME_FORMAT_RGB888 = 34, + IPU_INSYS_FRAME_FORMAT_YUV420_LEGACY = 35, + IPU_INSYS_FRAME_FORMAT_RAW6 = 36, + IPU_INSYS_FRAME_FORMAT_RAW7 = 37, + IPU_INSYS_FRAME_FORMAT_RGB444 = 38, + IPU_INSYS_FRAME_FORMAT_RGB666 = 39, + IPU_INSYS_FRAME_FORMAT_RAW20 = 40, + IPU_INSYS_FRAME_FORMAT_P010 = 41, + IPU_INSYS_FRAME_FORMAT_RGB555 = 42, N_IPU_INSYS_FRAME_FORMAT }; @@ -251,13 +260,16 @@ struct ipu7_insys_output_link { u8 pad[2]; }; +struct ipu7_insys_output_cropping_v1 { + u16 line_top; + u16 line_bottom; +}; + struct ipu7_insys_output_cropping { u16 line_top; u16 line_bottom; -#ifdef IPU8_INSYS_NEW_ABI u16 column_left; u16 column_right; -#endif }; struct ipu7_insys_output_dpcm { @@ -267,7 +279,6 @@ struct ipu7_insys_output_dpcm { u8 pad; }; -#ifdef IPU8_INSYS_NEW_ABI enum ipu_insys_cfa_dim { IPU_INSYS_CFA_DIM_2x2 = 0, IPU_INSYS_CFA_DIM_4x4 = 1, @@ -294,28 +305,31 @@ struct ipu7_insys_capture_output_pin_cfg { ia_gofo_addr_t upipe_capture_cfg; }; -#endif +struct ipu7_insys_output_pin_v1 { + struct ipu7_insys_output_link link; + struct ipu7_insys_output_cropping_v1 crop; + struct ipu7_insys_output_dpcm dpcm; + u32 stride; + u16 ft; + u8 send_irq; + u8 input_pin_id; + u8 early_ack_en; + u8 pad[3]; +}; + struct ipu7_insys_output_pin { struct ipu7_insys_output_link link; struct ipu7_insys_output_cropping crop; struct ipu7_insys_output_dpcm dpcm; -#ifdef IPU8_INSYS_NEW_ABI struct ipu7_insys_upipe_output_pin upipe_pin_cfg; -#endif u32 stride; u16 ft; -#ifdef IPU8_INSYS_NEW_ABI u8 upipe_enable; -#endif u8 send_irq; u8 input_pin_id; u8 early_ack_en; -#ifdef IPU8_INSYS_NEW_ABI u8 cfa_dim; u8 binning_factor; -#else - u8 pad[3]; -#endif }; struct ipu7_insys_input_pin { @@ -328,6 +342,17 @@ struct ipu7_insys_input_pin { u8 pad[2]; }; +struct ipu7_insys_stream_cfg_v1 { + struct ipu7_insys_input_pin input_pins[4]; + struct ipu7_insys_output_pin_v1 output_pins[4]; + u16 stream_msg_map; + u8 port_id; + u8 vc; + u8 nof_input_pins; + u8 nof_output_pins; + u8 pad[2]; +}; + struct ipu7_insys_stream_cfg { struct ipu7_insys_input_pin input_pins[4]; struct ipu7_insys_output_pin output_pins[4]; @@ -339,35 +364,48 @@ struct ipu7_insys_stream_cfg { u8 pad[2]; }; +struct ipu7_insys_buffset_v1 { + struct ipu7_insys_capture_output_pin_payload output_pins[4]; + u8 capture_msg_map; + u8 frame_id; + u8 skip_frame; + u8 pad[5]; +}; + struct ipu7_insys_buffset { -#ifdef IPU8_INSYS_NEW_ABI struct ipu7_insys_capture_output_pin_cfg output_pins[4]; -#else - struct ipu7_insys_capture_output_pin_payload output_pins[4]; -#endif u8 capture_msg_map; u8 frame_id; u8 skip_frame; u8 pad[5]; }; -struct ipu7_insys_resp { +struct ipu7_insys_resp_v1 { u64 buf_id; struct ipu7_insys_capture_output_pin_payload pin; struct ia_gofo_msg_err error_info; u32 timestamp[2]; -#ifdef IPU8_INSYS_NEW_ABI + u8 type; + u8 msg_link_streaming_mode; + u8 stream_id; + u8 pin_id; + u8 frame_id; + u8 skip_frame; u16 mipi_fn; -#endif +}; + +struct ipu7_insys_resp { + u64 buf_id; + struct ipu7_insys_capture_output_pin_payload pin; + struct ia_gofo_msg_err error_info; + u32 timestamp[2]; u8 type; u8 msg_link_streaming_mode; u8 stream_id; u8 pin_id; u8 frame_id; u8 skip_frame; -#ifndef IPU8_INSYS_NEW_ABI u16 mipi_fn; -#endif }; struct ipu7_insys_resp_queue_token { @@ -424,14 +462,12 @@ enum insys_msg_err_stream { INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES_OUTPUT = 36, INSYS_MSG_ERR_STREAM_WIDTH_OUTPUT_SIZE = 37, INSYS_MSG_ERR_STREAM_CLOSED = 38, -#ifdef IPU8_INSYS_NEW_ABI INSYS_MSG_ERR_STREAM_BINNING_FACTOR_NOT_SUPPORTED = 39, INSYS_MSG_ERR_STREAM_CFA_DIM_NOT_SUPPORTED = 40, INSYS_MSG_ERR_STREAM_INVALID_UPIPE_ENABLE = 41, INSYS_MSG_ERR_STREAM_INVALID_UPIPE_UOB_SINGLE = 42, INSYS_MSG_ERR_STREAM_INVALID_UPIPE_UOB_SHARED = 43, INSYS_MSG_ERR_STREAM_INVALID_UPIPE_OPAQUE_PIN_CFG = 44, -#endif INSYS_MSG_ERR_STREAM_N }; diff --git a/drivers/media/pci/intel/ipu7/ipu7-fw-isys.c b/drivers/media/pci/intel/ipu7/ipu7-fw-isys.c index 2958e39..70bfec9 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-fw-isys.c +++ b/drivers/media/pci/intel/ipu7/ipu7-fw-isys.c @@ -31,6 +31,119 @@ static const char * const send_msg_types[N_IPU_INSYS_SEND_TYPE] = { "STREAM_CLOSE" }; +static void isys_stream_cfg_to_v1(struct ipu7_insys_stream_cfg_v1 *dst, + const struct ipu7_insys_stream_cfg *src) +{ + unsigned int i; + + memset(dst, 0, sizeof(*dst)); + memcpy(dst->input_pins, src->input_pins, sizeof(dst->input_pins)); + dst->stream_msg_map = src->stream_msg_map; + dst->port_id = src->port_id; + dst->vc = src->vc; + dst->nof_input_pins = src->nof_input_pins; + dst->nof_output_pins = src->nof_output_pins; + + for (i = 0; i < ARRAY_SIZE(dst->output_pins); i++) { + dst->output_pins[i].link = src->output_pins[i].link; + dst->output_pins[i].crop.line_top = + src->output_pins[i].crop.line_top; + dst->output_pins[i].crop.line_bottom = + src->output_pins[i].crop.line_bottom; + dst->output_pins[i].dpcm = src->output_pins[i].dpcm; + dst->output_pins[i].stride = src->output_pins[i].stride; + dst->output_pins[i].ft = src->output_pins[i].ft; + dst->output_pins[i].send_irq = src->output_pins[i].send_irq; + dst->output_pins[i].input_pin_id = + src->output_pins[i].input_pin_id; + dst->output_pins[i].early_ack_en = + src->output_pins[i].early_ack_en; + } +} + +static void isys_buffset_to_v1(struct ipu7_insys_buffset_v1 *dst, + const struct ipu7_insys_buffset *src) +{ + unsigned int i; + + memset(dst, 0, sizeof(*dst)); + for (i = 0; i < ARRAY_SIZE(dst->output_pins); i++) + dst->output_pins[i] = src->output_pins[i].pin_payload; + + dst->capture_msg_map = src->capture_msg_map; + dst->frame_id = src->frame_id; + dst->skip_frame = src->skip_frame; +} + +static size_t isys_prepare_fw_payload_v1(void *cpu_mapped_buf, + u16 send_type, size_t size) +{ + if (!cpu_mapped_buf) + return 0; + + switch (send_type) { + case IPU_INSYS_SEND_TYPE_STREAM_OPEN: { + struct ipu7_insys_stream_cfg cfg; + + memcpy(&cfg, cpu_mapped_buf, sizeof(cfg)); + isys_stream_cfg_to_v1(cpu_mapped_buf, &cfg); + return sizeof(struct ipu7_insys_stream_cfg_v1); + } + case IPU_INSYS_SEND_TYPE_STREAM_START_AND_CAPTURE: + case IPU_INSYS_SEND_TYPE_STREAM_CAPTURE: { + struct ipu7_insys_buffset set; + + memcpy(&set, cpu_mapped_buf, sizeof(set)); + isys_buffset_to_v1(cpu_mapped_buf, &set); + return sizeof(struct ipu7_insys_buffset_v1); + } + default: + return size; + } +} + +static size_t isys_prepare_fw_payload(void *cpu_mapped_buf, + u16 send_type, size_t size) +{ + if (!cpu_mapped_buf) + return 0; + + switch (send_type) { + case IPU_INSYS_SEND_TYPE_STREAM_OPEN: + return sizeof(struct ipu7_insys_stream_cfg); + case IPU_INSYS_SEND_TYPE_STREAM_START_AND_CAPTURE: + case IPU_INSYS_SEND_TYPE_STREAM_CAPTURE: + return sizeof(struct ipu7_insys_buffset); + default: + return size; + } +} + +static __maybe_unused void isys_decode_resp_v1(struct ipu7_insys_resp *dst, + const void *token) +{ + const struct ipu7_insys_resp_v1 *src = token; + + memset(dst, 0, sizeof(*dst)); + dst->buf_id = src->buf_id; + dst->pin = src->pin; + dst->error_info = src->error_info; + dst->timestamp[0] = src->timestamp[0]; + dst->timestamp[1] = src->timestamp[1]; + dst->type = src->type; + dst->msg_link_streaming_mode = src->msg_link_streaming_mode; + dst->stream_id = src->stream_id; + dst->pin_id = src->pin_id; + dst->frame_id = src->frame_id; + dst->skip_frame = src->skip_frame; + dst->mipi_fn = src->mipi_fn; +} + +static void isys_decode_resp(struct ipu7_insys_resp *dst, const void *token) +{ + memcpy(dst, token, sizeof(*dst)); +} + int ipu7_fw_isys_complex_cmd(struct ipu7_isys *isys, const unsigned int stream_handle, void *cpu_mapped_buf, @@ -50,8 +163,11 @@ int ipu7_fw_isys_complex_cmd(struct ipu7_isys *isys, * Time to flush cache in case we have some payload. Not all messages * have that */ - if (cpu_mapped_buf) + if (cpu_mapped_buf) { + size = isys->abi_ops.prepare_payload(cpu_mapped_buf, + send_type, size); clflush_cache_range(cpu_mapped_buf, size); + } token = ipu7_syscom_get_token(ctx, stream_handle + IPU_INSYS_INPUT_MSG_QUEUE); @@ -97,6 +213,14 @@ int ipu7_fw_isys_init(struct ipu7_isys *isys) if (!syscom) return -ENOMEM; + if (is_ipu8(adev->isp->hw_ver)) + isys->abi_ops.prepare_payload = isys_prepare_fw_payload; + else + isys->abi_ops.prepare_payload = isys_prepare_fw_payload_v1; + + isys->abi_ops.decode_resp = isys_decode_resp; + isys->abi_ops.resp_queue_token_size = sizeof(struct ipu7_insys_resp); + adev->syscom = syscom; syscom->num_input_queues = IPU_INSYS_MAX_INPUT_QUEUES; syscom->num_output_queues = IPU_INSYS_MAX_OUTPUT_QUEUES; @@ -111,11 +235,11 @@ int ipu7_fw_isys_init(struct ipu7_isys *isys) queue_configs[IPU_INSYS_OUTPUT_MSG_QUEUE].max_capacity = IPU_ISYS_SIZE_RECV_QUEUE; queue_configs[IPU_INSYS_OUTPUT_MSG_QUEUE].token_size_in_bytes = - sizeof(struct ipu7_insys_resp); + isys->abi_ops.resp_queue_token_size; queue_configs[IPU_INSYS_OUTPUT_LOG_QUEUE].max_capacity = IPU_ISYS_SIZE_LOG_QUEUE; queue_configs[IPU_INSYS_OUTPUT_LOG_QUEUE].token_size_in_bytes = - sizeof(struct ipu7_insys_resp); + isys->abi_ops.resp_queue_token_size; queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].max_capacity = 0; queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].token_size_in_bytes = 0; @@ -195,9 +319,15 @@ int ipu7_fw_isys_close(struct ipu7_isys *isys) struct ipu7_insys_resp *ipu7_fw_isys_get_resp(struct ipu7_isys *isys) { - return (struct ipu7_insys_resp *) - ipu7_syscom_get_token(isys->adev->syscom, - IPU_INSYS_OUTPUT_MSG_QUEUE); + void *token = ipu7_syscom_get_token(isys->adev->syscom, + IPU_INSYS_OUTPUT_MSG_QUEUE); + + if (!token) + return NULL; + + isys->abi_ops.decode_resp(&isys->resp, token); + + return &isys->resp; } void ipu7_fw_isys_put_resp(struct ipu7_isys *isys) @@ -327,20 +457,16 @@ void ipu7_fw_isys_dump_stream_cfg(struct device *dev, cfg->output_pins[i].crop.line_top); dev_dbg(dev, "\t.crop.line_bottom = %d\n", cfg->output_pins[i].crop.line_bottom); -#ifdef IPU8_INSYS_NEW_ABI dev_dbg(dev, "\t.crop.column_left = %d\n", cfg->output_pins[i].crop.column_left); - dev_dbg(dev, "\t.crop.colunm_right = %d\n", + dev_dbg(dev, "\t.crop.column_right = %d\n", cfg->output_pins[i].crop.column_right); -#endif - dev_dbg(dev, "\t.dpcm_enable = %d\n", cfg->output_pins[i].dpcm.enable); dev_dbg(dev, "\t.dpcm.type = %d\n", cfg->output_pins[i].dpcm.type); dev_dbg(dev, "\t.dpcm.predictor = %d\n", cfg->output_pins[i].dpcm.predictor); -#ifdef IPU8_INSYS_NEW_ABI dev_dbg(dev, "\t.upipe_enable = %d\n", cfg->output_pins[i].upipe_enable); dev_dbg(dev, "\t.upipe_pin_cfg.opaque_pin_cfg = %d\n", @@ -353,7 +479,6 @@ void ipu7_fw_isys_dump_stream_cfg(struct device *dev, cfg->output_pins[i].upipe_pin_cfg.single_uob_fifo); dev_dbg(dev, "\t.upipe_pin_cfg.shared_uob_fifo = %d\n", cfg->output_pins[i].upipe_pin_cfg.shared_uob_fifo); -#endif } dev_dbg(dev, "---------------------------\n"); } @@ -372,18 +497,12 @@ void ipu7_fw_isys_dump_frame_buff_set(struct device *dev, for (i = 0; i < outputs; i++) { dev_dbg(dev, ".output_pin[%d]:\n", i); -#ifndef IPU8_INSYS_NEW_ABI - dev_dbg(dev, "\t.user_token = %llx\n", - buf->output_pins[i].user_token); - dev_dbg(dev, "\t.addr = 0x%x\n", buf->output_pins[i].addr); -#else dev_dbg(dev, "\t.pin_payload.user_token = %llx\n", buf->output_pins[i].pin_payload.user_token); dev_dbg(dev, "\t.pin_payload.addr = 0x%x\n", buf->output_pins[i].pin_payload.addr); dev_dbg(dev, "\t.pin_payload.upipe_capture_cfg = 0x%x\n", buf->output_pins[i].upipe_capture_cfg); -#endif } dev_dbg(dev, "---------------------------\n"); } diff --git a/drivers/media/pci/intel/ipu7/ipu7-isys-queue.c b/drivers/media/pci/intel/ipu7/ipu7-isys-queue.c index dc6f310..a97f5bf 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-isys-queue.c +++ b/drivers/media/pci/intel/ipu7/ipu7-isys-queue.c @@ -23,6 +23,7 @@ #include "abi/ipu7_fw_isys_abi.h" +#include "ipu7.h" #include "ipu7-bus.h" #include "ipu7-dma.h" #include "ipu7-fw-isys.h" @@ -264,15 +265,12 @@ static void ipu7_isys_buf_to_fw_frame_buf_pin(struct vb2_buffer *vb, struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb); struct ipu7_isys_video_buffer *ivb = vb2_buffer_to_ipu7_isys_video_buffer(vvb); + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); -#ifndef IPU8_INSYS_NEW_ABI - set->output_pins[aq->fw_output].addr = ivb->dma_addr; - set->output_pins[aq->fw_output].user_token = (uintptr_t)set; -#else set->output_pins[aq->fw_output].pin_payload.addr = ivb->dma_addr; set->output_pins[aq->fw_output].pin_payload.user_token = (uintptr_t)set; - set->output_pins[aq->fw_output].upipe_capture_cfg = 0; -#endif + if (is_ipu8(av->isys->adev->isp->hw_ver)) + set->output_pins[aq->fw_output].upipe_capture_cfg = 0; } /* diff --git a/drivers/media/pci/intel/ipu7/ipu7-isys-video.c b/drivers/media/pci/intel/ipu7/ipu7-isys-video.c index 20a0cf8..e95bbc8 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-isys-video.c +++ b/drivers/media/pci/intel/ipu7/ipu7-isys-video.c @@ -455,26 +455,26 @@ static int ipu7_isys_fw_pin_cfg(struct ipu7_isys_video *av, /* output pin crop */ output_pin->crop.line_top = 0; output_pin->crop.line_bottom = 0; -#ifdef IPU8_INSYS_NEW_ABI - output_pin->crop.column_left = 0; - output_pin->crop.column_right = 0; -#endif + if (is_ipu8(isys->adev->isp->hw_ver)) { + output_pin->crop.column_left = 0; + output_pin->crop.column_right = 0; + } /* output de-compression */ output_pin->dpcm.enable = 0; -#ifdef IPU8_INSYS_NEW_ABI - /* upipe_cfg */ - output_pin->upipe_pin_cfg.opaque_pin_cfg = 0; - output_pin->upipe_pin_cfg.plane_offset_1 = 0; - output_pin->upipe_pin_cfg.plane_offset_2 = 0; - output_pin->upipe_pin_cfg.single_uob_fifo = 0; - output_pin->upipe_pin_cfg.shared_uob_fifo = 0; - output_pin->upipe_enable = 0; - output_pin->binning_factor = 0; - /* stupid setting, even unused, SW still need to set a valid value */ - output_pin->cfa_dim = IPU_INSYS_CFA_DIM_2x2; -#endif + if (is_ipu8(isys->adev->isp->hw_ver)) { + /* upipe_cfg */ + output_pin->upipe_pin_cfg.opaque_pin_cfg = 0; + output_pin->upipe_pin_cfg.plane_offset_1 = 0; + output_pin->upipe_pin_cfg.plane_offset_2 = 0; + output_pin->upipe_pin_cfg.single_uob_fifo = 0; + output_pin->upipe_pin_cfg.shared_uob_fifo = 0; + output_pin->upipe_enable = 0; + output_pin->binning_factor = 0; + /* even unused, SW still needs to set a valid value */ + output_pin->cfa_dim = IPU_INSYS_CFA_DIM_2x2; + } /* frame format type */ pfmt = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); diff --git a/drivers/media/pci/intel/ipu7/ipu7-isys.h b/drivers/media/pci/intel/ipu7/ipu7-isys.h index 2e45258..c950f24 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-isys.h +++ b/drivers/media/pci/intel/ipu7/ipu7-isys.h @@ -67,6 +67,13 @@ struct isys_fw_log { u32 size; /* actual size of log content, in bits */ }; +struct ipu7_isys_abi_ops { + size_t (*prepare_payload)(void *cpu_mapped_buf, u16 send_type, + size_t size); + void (*decode_resp)(struct ipu7_insys_resp *dst, const void *token); + size_t resp_queue_token_size; +}; + /* * struct ipu7_isys * @@ -124,6 +131,8 @@ struct ipu7_isys { struct list_head framebuflist; struct list_head framebuflist_fw; struct v4l2_async_notifier notifier; + struct ipu7_isys_abi_ops abi_ops; + struct ipu7_insys_resp resp; struct ipu7_insys_config *subsys_config; dma_addr_t subsys_config_dma_addr; diff --git a/patch/v7.0.0/0008-staging-ipu7-Add-IPU8-ABI-version-1.0.14-and-select-.patch b/patch/v7.0.0/0008-staging-ipu7-Add-IPU8-ABI-version-1.0.14-and-select-.patch new file mode 100644 index 0000000..4594371 --- /dev/null +++ b/patch/v7.0.0/0008-staging-ipu7-Add-IPU8-ABI-version-1.0.14-and-select-.patch @@ -0,0 +1,569 @@ +From 3d811c645c1c5fd506eca641f52b41474a8f8f39 Mon Sep 17 00:00:00 2001 +From: Avinash Kumar +Date: Thu, 2 Jul 2026 07:21:12 +0000 +Subject: [PATCH 8/8] staging: ipu7: Add IPU8 ABI version 1.0.14 and select it + at runtime + +Starting from firmware ABI 1.0.14 the IPU8 InSys message layout diverges +from IPU7. The output pin gains a horizontal cropping window +(column_left/column_right), a uPipe configuration block, a CFA dimension +and a binning factor; the capture buffer set references a per-pin config +structure instead of a bare payload; and the response message carries +mipi_fn ahead of the type and stream fields. + +So far the two layouts were picked at build time through the +IPU8_INSYS_NEW_ABI macro, which means a single module binary cannot drive +both IPU7 and IPU8. Select the layout at runtime instead: + + - Use the IPU8 1.0.14 message definitions as the driver internal + representation and add _v1 counterparts of ipu7_insys_output_cropping, + ipu7_insys_output_pin, ipu7_insys_stream_cfg, ipu7_insys_buffset and + ipu7_insys_resp describing the legacy IPU7 layout. + + - Add struct ipu7_isys_abi_ops holding prepare_payload(), decode_resp() + and resp_queue_token_size, and bind it in ipu7_fw_isys_init() according + to is_ipu8(). On IPU7 the stream config and the buffer set are + converted in place to the _v1 layout before the payload is flushed to + the firmware; on IPU8 they are passed through unchanged. + + - Decode the response queue token into isys->resp through the same ops, + so that callers keep working with a single struct ipu7_insys_resp. + + - Replace the remaining IPU8_INSYS_NEW_ABI conditionals in the InSys + queue and video code with is_ipu8() checks. + + - Make the frame format types and the stream error codes introduced by + ABI 1.0.14 unconditional, and correct a "colunm_right" typo in a debug + message. + +Tracked-On: #JSWBALINUX-155 +Signed-off-by: Avinash Kumar +Signed-off-by: Divyamani Tripathi +--- + drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h | 82 ++++++++--- + drivers/staging/media/ipu7/ipu7-fw-isys.c | 155 ++++++++++++++++++-- + drivers/staging/media/ipu7/ipu7-isys-queue.c | 10 +- + drivers/staging/media/ipu7/ipu7-isys-video.c | 32 ++-- + drivers/staging/media/ipu7/ipu7-isys.h | 9 + + 5 files changed, 225 insertions(+), 63 deletions(-) + +diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h +index f32674f081d2..5d1e23a9403b 100644 +--- a/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h ++++ b/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h +@@ -125,6 +125,15 @@ enum ipu7_insys_frame_format_type { + IPU_INSYS_FRAME_FORMAT_ARGB888 = 31, + IPU_INSYS_FRAME_FORMAT_BGRA888 = 32, + IPU_INSYS_FRAME_FORMAT_ABGR888 = 33, ++ IPU_INSYS_FRAME_FORMAT_RGB888 = 34, ++ IPU_INSYS_FRAME_FORMAT_YUV420_LEGACY = 35, ++ IPU_INSYS_FRAME_FORMAT_RAW6 = 36, ++ IPU_INSYS_FRAME_FORMAT_RAW7 = 37, ++ IPU_INSYS_FRAME_FORMAT_RGB444 = 38, ++ IPU_INSYS_FRAME_FORMAT_RGB666 = 39, ++ IPU_INSYS_FRAME_FORMAT_RAW20 = 40, ++ IPU_INSYS_FRAME_FORMAT_P010 = 41, ++ IPU_INSYS_FRAME_FORMAT_RGB555 = 42, + N_IPU_INSYS_FRAME_FORMAT + }; + +@@ -251,13 +260,16 @@ struct ipu7_insys_output_link { + u8 pad[2]; + }; + ++struct ipu7_insys_output_cropping_v1 { ++ u16 line_top; ++ u16 line_bottom; ++}; ++ + struct ipu7_insys_output_cropping { + u16 line_top; + u16 line_bottom; +-#ifdef IPU8_INSYS_NEW_ABI + u16 column_left; + u16 column_right; +-#endif + }; + + struct ipu7_insys_output_dpcm { +@@ -267,7 +279,6 @@ struct ipu7_insys_output_dpcm { + u8 pad; + }; + +-#ifdef IPU8_INSYS_NEW_ABI + enum ipu_insys_cfa_dim { + IPU_INSYS_CFA_DIM_2x2 = 0, + IPU_INSYS_CFA_DIM_4x4 = 1, +@@ -294,28 +305,31 @@ struct ipu7_insys_capture_output_pin_cfg { + ia_gofo_addr_t upipe_capture_cfg; + }; + +-#endif ++struct ipu7_insys_output_pin_v1 { ++ struct ipu7_insys_output_link link; ++ struct ipu7_insys_output_cropping_v1 crop; ++ struct ipu7_insys_output_dpcm dpcm; ++ u32 stride; ++ u16 ft; ++ u8 send_irq; ++ u8 input_pin_id; ++ u8 early_ack_en; ++ u8 pad[3]; ++}; ++ + struct ipu7_insys_output_pin { + struct ipu7_insys_output_link link; + struct ipu7_insys_output_cropping crop; + struct ipu7_insys_output_dpcm dpcm; +-#ifdef IPU8_INSYS_NEW_ABI + struct ipu7_insys_upipe_output_pin upipe_pin_cfg; +-#endif + u32 stride; + u16 ft; +-#ifdef IPU8_INSYS_NEW_ABI + u8 upipe_enable; +-#endif + u8 send_irq; + u8 input_pin_id; + u8 early_ack_en; +-#ifdef IPU8_INSYS_NEW_ABI + u8 cfa_dim; + u8 binning_factor; +-#else +- u8 pad[3]; +-#endif + }; + + struct ipu7_insys_input_pin { +@@ -328,6 +342,17 @@ struct ipu7_insys_input_pin { + u8 pad[2]; + }; + ++struct ipu7_insys_stream_cfg_v1 { ++ struct ipu7_insys_input_pin input_pins[4]; ++ struct ipu7_insys_output_pin_v1 output_pins[4]; ++ u16 stream_msg_map; ++ u8 port_id; ++ u8 vc; ++ u8 nof_input_pins; ++ u8 nof_output_pins; ++ u8 pad[2]; ++}; ++ + struct ipu7_insys_stream_cfg { + struct ipu7_insys_input_pin input_pins[4]; + struct ipu7_insys_output_pin output_pins[4]; +@@ -339,35 +364,48 @@ struct ipu7_insys_stream_cfg { + u8 pad[2]; + }; + ++struct ipu7_insys_buffset_v1 { ++ struct ipu7_insys_capture_output_pin_payload output_pins[4]; ++ u8 capture_msg_map; ++ u8 frame_id; ++ u8 skip_frame; ++ u8 pad[5]; ++}; ++ + struct ipu7_insys_buffset { +-#ifdef IPU8_INSYS_NEW_ABI + struct ipu7_insys_capture_output_pin_cfg output_pins[4]; +-#else +- struct ipu7_insys_capture_output_pin_payload output_pins[4]; +-#endif + u8 capture_msg_map; + u8 frame_id; + u8 skip_frame; + u8 pad[5]; + }; + +-struct ipu7_insys_resp { ++struct ipu7_insys_resp_v1 { + u64 buf_id; + struct ipu7_insys_capture_output_pin_payload pin; + struct ia_gofo_msg_err error_info; + u32 timestamp[2]; +-#ifdef IPU8_INSYS_NEW_ABI ++ u8 type; ++ u8 msg_link_streaming_mode; ++ u8 stream_id; ++ u8 pin_id; ++ u8 frame_id; ++ u8 skip_frame; + u16 mipi_fn; +-#endif ++}; ++ ++struct ipu7_insys_resp { ++ u64 buf_id; ++ struct ipu7_insys_capture_output_pin_payload pin; ++ struct ia_gofo_msg_err error_info; ++ u32 timestamp[2]; + u8 type; + u8 msg_link_streaming_mode; + u8 stream_id; + u8 pin_id; + u8 frame_id; + u8 skip_frame; +-#ifndef IPU8_INSYS_NEW_ABI + u16 mipi_fn; +-#endif + }; + + struct ipu7_insys_resp_queue_token { +@@ -424,14 +462,12 @@ enum insys_msg_err_stream { + INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES_OUTPUT = 36, + INSYS_MSG_ERR_STREAM_WIDTH_OUTPUT_SIZE = 37, + INSYS_MSG_ERR_STREAM_CLOSED = 38, +-#ifdef IPU8_INSYS_NEW_ABI + INSYS_MSG_ERR_STREAM_BINNING_FACTOR_NOT_SUPPORTED = 39, + INSYS_MSG_ERR_STREAM_CFA_DIM_NOT_SUPPORTED = 40, + INSYS_MSG_ERR_STREAM_INVALID_UPIPE_ENABLE = 41, + INSYS_MSG_ERR_STREAM_INVALID_UPIPE_UOB_SINGLE = 42, + INSYS_MSG_ERR_STREAM_INVALID_UPIPE_UOB_SHARED = 43, + INSYS_MSG_ERR_STREAM_INVALID_UPIPE_OPAQUE_PIN_CFG = 44, +-#endif + INSYS_MSG_ERR_STREAM_N + }; + +diff --git a/drivers/staging/media/ipu7/ipu7-fw-isys.c b/drivers/staging/media/ipu7/ipu7-fw-isys.c +index 2958e39a359e..70bfec9326f7 100644 +--- a/drivers/staging/media/ipu7/ipu7-fw-isys.c ++++ b/drivers/staging/media/ipu7/ipu7-fw-isys.c +@@ -31,6 +31,119 @@ static const char * const send_msg_types[N_IPU_INSYS_SEND_TYPE] = { + "STREAM_CLOSE" + }; + ++static void isys_stream_cfg_to_v1(struct ipu7_insys_stream_cfg_v1 *dst, ++ const struct ipu7_insys_stream_cfg *src) ++{ ++ unsigned int i; ++ ++ memset(dst, 0, sizeof(*dst)); ++ memcpy(dst->input_pins, src->input_pins, sizeof(dst->input_pins)); ++ dst->stream_msg_map = src->stream_msg_map; ++ dst->port_id = src->port_id; ++ dst->vc = src->vc; ++ dst->nof_input_pins = src->nof_input_pins; ++ dst->nof_output_pins = src->nof_output_pins; ++ ++ for (i = 0; i < ARRAY_SIZE(dst->output_pins); i++) { ++ dst->output_pins[i].link = src->output_pins[i].link; ++ dst->output_pins[i].crop.line_top = ++ src->output_pins[i].crop.line_top; ++ dst->output_pins[i].crop.line_bottom = ++ src->output_pins[i].crop.line_bottom; ++ dst->output_pins[i].dpcm = src->output_pins[i].dpcm; ++ dst->output_pins[i].stride = src->output_pins[i].stride; ++ dst->output_pins[i].ft = src->output_pins[i].ft; ++ dst->output_pins[i].send_irq = src->output_pins[i].send_irq; ++ dst->output_pins[i].input_pin_id = ++ src->output_pins[i].input_pin_id; ++ dst->output_pins[i].early_ack_en = ++ src->output_pins[i].early_ack_en; ++ } ++} ++ ++static void isys_buffset_to_v1(struct ipu7_insys_buffset_v1 *dst, ++ const struct ipu7_insys_buffset *src) ++{ ++ unsigned int i; ++ ++ memset(dst, 0, sizeof(*dst)); ++ for (i = 0; i < ARRAY_SIZE(dst->output_pins); i++) ++ dst->output_pins[i] = src->output_pins[i].pin_payload; ++ ++ dst->capture_msg_map = src->capture_msg_map; ++ dst->frame_id = src->frame_id; ++ dst->skip_frame = src->skip_frame; ++} ++ ++static size_t isys_prepare_fw_payload_v1(void *cpu_mapped_buf, ++ u16 send_type, size_t size) ++{ ++ if (!cpu_mapped_buf) ++ return 0; ++ ++ switch (send_type) { ++ case IPU_INSYS_SEND_TYPE_STREAM_OPEN: { ++ struct ipu7_insys_stream_cfg cfg; ++ ++ memcpy(&cfg, cpu_mapped_buf, sizeof(cfg)); ++ isys_stream_cfg_to_v1(cpu_mapped_buf, &cfg); ++ return sizeof(struct ipu7_insys_stream_cfg_v1); ++ } ++ case IPU_INSYS_SEND_TYPE_STREAM_START_AND_CAPTURE: ++ case IPU_INSYS_SEND_TYPE_STREAM_CAPTURE: { ++ struct ipu7_insys_buffset set; ++ ++ memcpy(&set, cpu_mapped_buf, sizeof(set)); ++ isys_buffset_to_v1(cpu_mapped_buf, &set); ++ return sizeof(struct ipu7_insys_buffset_v1); ++ } ++ default: ++ return size; ++ } ++} ++ ++static size_t isys_prepare_fw_payload(void *cpu_mapped_buf, ++ u16 send_type, size_t size) ++{ ++ if (!cpu_mapped_buf) ++ return 0; ++ ++ switch (send_type) { ++ case IPU_INSYS_SEND_TYPE_STREAM_OPEN: ++ return sizeof(struct ipu7_insys_stream_cfg); ++ case IPU_INSYS_SEND_TYPE_STREAM_START_AND_CAPTURE: ++ case IPU_INSYS_SEND_TYPE_STREAM_CAPTURE: ++ return sizeof(struct ipu7_insys_buffset); ++ default: ++ return size; ++ } ++} ++ ++static __maybe_unused void isys_decode_resp_v1(struct ipu7_insys_resp *dst, ++ const void *token) ++{ ++ const struct ipu7_insys_resp_v1 *src = token; ++ ++ memset(dst, 0, sizeof(*dst)); ++ dst->buf_id = src->buf_id; ++ dst->pin = src->pin; ++ dst->error_info = src->error_info; ++ dst->timestamp[0] = src->timestamp[0]; ++ dst->timestamp[1] = src->timestamp[1]; ++ dst->type = src->type; ++ dst->msg_link_streaming_mode = src->msg_link_streaming_mode; ++ dst->stream_id = src->stream_id; ++ dst->pin_id = src->pin_id; ++ dst->frame_id = src->frame_id; ++ dst->skip_frame = src->skip_frame; ++ dst->mipi_fn = src->mipi_fn; ++} ++ ++static void isys_decode_resp(struct ipu7_insys_resp *dst, const void *token) ++{ ++ memcpy(dst, token, sizeof(*dst)); ++} ++ + int ipu7_fw_isys_complex_cmd(struct ipu7_isys *isys, + const unsigned int stream_handle, + void *cpu_mapped_buf, +@@ -50,8 +163,11 @@ int ipu7_fw_isys_complex_cmd(struct ipu7_isys *isys, + * Time to flush cache in case we have some payload. Not all messages + * have that + */ +- if (cpu_mapped_buf) ++ if (cpu_mapped_buf) { ++ size = isys->abi_ops.prepare_payload(cpu_mapped_buf, ++ send_type, size); + clflush_cache_range(cpu_mapped_buf, size); ++ } + + token = ipu7_syscom_get_token(ctx, stream_handle + + IPU_INSYS_INPUT_MSG_QUEUE); +@@ -97,6 +213,14 @@ int ipu7_fw_isys_init(struct ipu7_isys *isys) + if (!syscom) + return -ENOMEM; + ++ if (is_ipu8(adev->isp->hw_ver)) ++ isys->abi_ops.prepare_payload = isys_prepare_fw_payload; ++ else ++ isys->abi_ops.prepare_payload = isys_prepare_fw_payload_v1; ++ ++ isys->abi_ops.decode_resp = isys_decode_resp; ++ isys->abi_ops.resp_queue_token_size = sizeof(struct ipu7_insys_resp); ++ + adev->syscom = syscom; + syscom->num_input_queues = IPU_INSYS_MAX_INPUT_QUEUES; + syscom->num_output_queues = IPU_INSYS_MAX_OUTPUT_QUEUES; +@@ -111,11 +235,11 @@ int ipu7_fw_isys_init(struct ipu7_isys *isys) + queue_configs[IPU_INSYS_OUTPUT_MSG_QUEUE].max_capacity = + IPU_ISYS_SIZE_RECV_QUEUE; + queue_configs[IPU_INSYS_OUTPUT_MSG_QUEUE].token_size_in_bytes = +- sizeof(struct ipu7_insys_resp); ++ isys->abi_ops.resp_queue_token_size; + queue_configs[IPU_INSYS_OUTPUT_LOG_QUEUE].max_capacity = + IPU_ISYS_SIZE_LOG_QUEUE; + queue_configs[IPU_INSYS_OUTPUT_LOG_QUEUE].token_size_in_bytes = +- sizeof(struct ipu7_insys_resp); ++ isys->abi_ops.resp_queue_token_size; + queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].max_capacity = 0; + queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].token_size_in_bytes = 0; + +@@ -195,9 +319,15 @@ int ipu7_fw_isys_close(struct ipu7_isys *isys) + + struct ipu7_insys_resp *ipu7_fw_isys_get_resp(struct ipu7_isys *isys) + { +- return (struct ipu7_insys_resp *) +- ipu7_syscom_get_token(isys->adev->syscom, +- IPU_INSYS_OUTPUT_MSG_QUEUE); ++ void *token = ipu7_syscom_get_token(isys->adev->syscom, ++ IPU_INSYS_OUTPUT_MSG_QUEUE); ++ ++ if (!token) ++ return NULL; ++ ++ isys->abi_ops.decode_resp(&isys->resp, token); ++ ++ return &isys->resp; + } + + void ipu7_fw_isys_put_resp(struct ipu7_isys *isys) +@@ -327,20 +457,16 @@ void ipu7_fw_isys_dump_stream_cfg(struct device *dev, + cfg->output_pins[i].crop.line_top); + dev_dbg(dev, "\t.crop.line_bottom = %d\n", + cfg->output_pins[i].crop.line_bottom); +-#ifdef IPU8_INSYS_NEW_ABI + dev_dbg(dev, "\t.crop.column_left = %d\n", + cfg->output_pins[i].crop.column_left); +- dev_dbg(dev, "\t.crop.colunm_right = %d\n", ++ dev_dbg(dev, "\t.crop.column_right = %d\n", + cfg->output_pins[i].crop.column_right); +-#endif +- + dev_dbg(dev, "\t.dpcm_enable = %d\n", + cfg->output_pins[i].dpcm.enable); + dev_dbg(dev, "\t.dpcm.type = %d\n", + cfg->output_pins[i].dpcm.type); + dev_dbg(dev, "\t.dpcm.predictor = %d\n", + cfg->output_pins[i].dpcm.predictor); +-#ifdef IPU8_INSYS_NEW_ABI + dev_dbg(dev, "\t.upipe_enable = %d\n", + cfg->output_pins[i].upipe_enable); + dev_dbg(dev, "\t.upipe_pin_cfg.opaque_pin_cfg = %d\n", +@@ -353,7 +479,6 @@ void ipu7_fw_isys_dump_stream_cfg(struct device *dev, + cfg->output_pins[i].upipe_pin_cfg.single_uob_fifo); + dev_dbg(dev, "\t.upipe_pin_cfg.shared_uob_fifo = %d\n", + cfg->output_pins[i].upipe_pin_cfg.shared_uob_fifo); +-#endif + } + dev_dbg(dev, "---------------------------\n"); + } +@@ -372,18 +497,12 @@ void ipu7_fw_isys_dump_frame_buff_set(struct device *dev, + + for (i = 0; i < outputs; i++) { + dev_dbg(dev, ".output_pin[%d]:\n", i); +-#ifndef IPU8_INSYS_NEW_ABI +- dev_dbg(dev, "\t.user_token = %llx\n", +- buf->output_pins[i].user_token); +- dev_dbg(dev, "\t.addr = 0x%x\n", buf->output_pins[i].addr); +-#else + dev_dbg(dev, "\t.pin_payload.user_token = %llx\n", + buf->output_pins[i].pin_payload.user_token); + dev_dbg(dev, "\t.pin_payload.addr = 0x%x\n", + buf->output_pins[i].pin_payload.addr); + dev_dbg(dev, "\t.pin_payload.upipe_capture_cfg = 0x%x\n", + buf->output_pins[i].upipe_capture_cfg); +-#endif + } + dev_dbg(dev, "---------------------------\n"); + } +diff --git a/drivers/staging/media/ipu7/ipu7-isys-queue.c b/drivers/staging/media/ipu7/ipu7-isys-queue.c +index dc6f3105cdd2..a97f5bf2941c 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys-queue.c ++++ b/drivers/staging/media/ipu7/ipu7-isys-queue.c +@@ -23,6 +23,7 @@ + + #include "abi/ipu7_fw_isys_abi.h" + ++#include "ipu7.h" + #include "ipu7-bus.h" + #include "ipu7-dma.h" + #include "ipu7-fw-isys.h" +@@ -264,15 +265,12 @@ static void ipu7_isys_buf_to_fw_frame_buf_pin(struct vb2_buffer *vb, + struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb); + struct ipu7_isys_video_buffer *ivb = + vb2_buffer_to_ipu7_isys_video_buffer(vvb); ++ struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + +-#ifndef IPU8_INSYS_NEW_ABI +- set->output_pins[aq->fw_output].addr = ivb->dma_addr; +- set->output_pins[aq->fw_output].user_token = (uintptr_t)set; +-#else + set->output_pins[aq->fw_output].pin_payload.addr = ivb->dma_addr; + set->output_pins[aq->fw_output].pin_payload.user_token = (uintptr_t)set; +- set->output_pins[aq->fw_output].upipe_capture_cfg = 0; +-#endif ++ if (is_ipu8(av->isys->adev->isp->hw_ver)) ++ set->output_pins[aq->fw_output].upipe_capture_cfg = 0; + } + + /* +diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.c b/drivers/staging/media/ipu7/ipu7-isys-video.c +index 20a0cf82ae6b..e95bbc83669f 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys-video.c ++++ b/drivers/staging/media/ipu7/ipu7-isys-video.c +@@ -455,26 +455,26 @@ static int ipu7_isys_fw_pin_cfg(struct ipu7_isys_video *av, + /* output pin crop */ + output_pin->crop.line_top = 0; + output_pin->crop.line_bottom = 0; +-#ifdef IPU8_INSYS_NEW_ABI +- output_pin->crop.column_left = 0; +- output_pin->crop.column_right = 0; +-#endif ++ if (is_ipu8(isys->adev->isp->hw_ver)) { ++ output_pin->crop.column_left = 0; ++ output_pin->crop.column_right = 0; ++ } + + /* output de-compression */ + output_pin->dpcm.enable = 0; + +-#ifdef IPU8_INSYS_NEW_ABI +- /* upipe_cfg */ +- output_pin->upipe_pin_cfg.opaque_pin_cfg = 0; +- output_pin->upipe_pin_cfg.plane_offset_1 = 0; +- output_pin->upipe_pin_cfg.plane_offset_2 = 0; +- output_pin->upipe_pin_cfg.single_uob_fifo = 0; +- output_pin->upipe_pin_cfg.shared_uob_fifo = 0; +- output_pin->upipe_enable = 0; +- output_pin->binning_factor = 0; +- /* stupid setting, even unused, SW still need to set a valid value */ +- output_pin->cfa_dim = IPU_INSYS_CFA_DIM_2x2; +-#endif ++ if (is_ipu8(isys->adev->isp->hw_ver)) { ++ /* upipe_cfg */ ++ output_pin->upipe_pin_cfg.opaque_pin_cfg = 0; ++ output_pin->upipe_pin_cfg.plane_offset_1 = 0; ++ output_pin->upipe_pin_cfg.plane_offset_2 = 0; ++ output_pin->upipe_pin_cfg.single_uob_fifo = 0; ++ output_pin->upipe_pin_cfg.shared_uob_fifo = 0; ++ output_pin->upipe_enable = 0; ++ output_pin->binning_factor = 0; ++ /* even unused, SW still needs to set a valid value */ ++ output_pin->cfa_dim = IPU_INSYS_CFA_DIM_2x2; ++ } + + /* frame format type */ + pfmt = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); +diff --git a/drivers/staging/media/ipu7/ipu7-isys.h b/drivers/staging/media/ipu7/ipu7-isys.h +index 2e45258bb6ab..c950f247100a 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys.h ++++ b/drivers/staging/media/ipu7/ipu7-isys.h +@@ -67,6 +67,13 @@ struct isys_fw_log { + u32 size; /* actual size of log content, in bits */ + }; + ++struct ipu7_isys_abi_ops { ++ size_t (*prepare_payload)(void *cpu_mapped_buf, u16 send_type, ++ size_t size); ++ void (*decode_resp)(struct ipu7_insys_resp *dst, const void *token); ++ size_t resp_queue_token_size; ++}; ++ + /* + * struct ipu7_isys + * +@@ -124,6 +131,8 @@ struct ipu7_isys { + struct list_head framebuflist; + struct list_head framebuflist_fw; + struct v4l2_async_notifier notifier; ++ struct ipu7_isys_abi_ops abi_ops; ++ struct ipu7_insys_resp resp; + + struct ipu7_insys_config *subsys_config; + dma_addr_t subsys_config_dma_addr; +-- +2.43.0