diff --git a/drivers/media/pci/intel/ipu7/Makefile b/drivers/media/pci/intel/ipu7/Makefile index 3c35ca5..5041701 100644 --- a/drivers/media/pci/intel/ipu7/Makefile +++ b/drivers/media/pci/intel/ipu7/Makefile @@ -27,6 +27,9 @@ intel-ipu7-isys-objs += ipu7-isys.o \ ipu7-isys-queue.o \ ipu7-isys-subdev.o +ifdef CONFIG_VIDEO_INTEL_IPU7_MGC +intel-ipu7-isys-objs += ipu7-isys-tpg.o +endif obj-$(CONFIG_VIDEO_INTEL_IPU7) += intel-ipu7-isys.o obj-$(CONFIG_VIDEO_INTEL_IPU7) += psys/ diff --git a/drivers/media/pci/intel/ipu7/abi/ipu7_fw_boot_abi.h b/drivers/media/pci/intel/ipu7/abi/ipu7_fw_boot_abi.h index 4ce304f..ca590f0 100644 --- a/drivers/media/pci/intel/ipu7/abi/ipu7_fw_boot_abi.h +++ b/drivers/media/pci/intel/ipu7/abi/ipu7_fw_boot_abi.h @@ -113,14 +113,18 @@ struct ia_gofo_secondary_boot_config { #define IA_GOFO_DOUBLE_EXCEPTION_ERR 0xdead0806U #define IA_GOFO_BIST_DMEM_FAULT_DETECTION_ERR 0xdead1000U #define IA_GOFO_BIST_DATA_INTEGRITY_FAILURE 0xdead1010U - +#define IA_GOFO_BOOT_STATE_UNINIT 0x57a7e000U +#define IA_GOFO_BOOT_STATE_STARTING_0 0x57a7d000U +#define IA_GOFO_BOOT_STATE_CACHE_INIT_DONE 0x57a7d010U +#define IA_GOFO_BOOT_STATE_MEM_INIT_DONE 0x57a7d020U +#define IA_GOFO_BOOT_STATE_STACK_INIT_DONE 0x57a7d030U enum ia_gofo_boot_state { IA_GOFO_FW_BOOT_STATE_SECONDARY_BOOT_CONFIG_READY = 0x57a7b000U, - IA_GOFO_FW_BOOT_STATE_UNINIT = 0x57a7e000U, - IA_GOFO_FW_BOOT_STATE_STARTING_0 = 0x57a7d000U, - IA_GOFO_FW_BOOT_STATE_CACHE_INIT_DONE = 0x57a7d010U, - IA_GOFO_FW_BOOT_STATE_MEM_INIT_DONE = 0x57a7d020U, - IA_GOFO_FW_BOOT_STATE_STACK_INIT_DONE = 0x57a7d030U, + IA_GOFO_FW_BOOT_STATE_UNINIT = IA_GOFO_BOOT_STATE_UNINIT, + IA_GOFO_FW_BOOT_STATE_STARTING_0 = IA_GOFO_BOOT_STATE_STARTING_0, + IA_GOFO_FW_BOOT_STATE_CACHE_INIT_DONE = IA_GOFO_BOOT_STATE_CACHE_INIT_DONE, + IA_GOFO_FW_BOOT_STATE_MEM_INIT_DONE = IA_GOFO_BOOT_STATE_MEM_INIT_DONE, + IA_GOFO_FW_BOOT_STATE_STACK_INIT_DONE = IA_GOFO_BOOT_STATE_STACK_INIT_DONE, IA_GOFO_FW_BOOT_STATE_EARLY_BOOT_DONE = 0x57a7d100U, IA_GOFO_FW_BOOT_STATE_BOOT_CONFIG_START = 0x57a7d200U, IA_GOFO_FW_BOOT_STATE_QUEUE_INIT_DONE = 0x57a7d300U, 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 db1bcfd..f32674f 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,15 +125,6 @@ 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 }; @@ -260,16 +251,13 @@ 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 { @@ -279,6 +267,7 @@ 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, @@ -305,31 +294,28 @@ struct ipu7_insys_capture_output_pin_cfg { ia_gofo_addr_t upipe_capture_cfg; }; -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]; -}; - +#endif 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 { @@ -342,17 +328,6 @@ 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]; @@ -364,48 +339,35 @@ 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_v1 { - 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; - u16 mipi_fn; -}; - 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]; +#ifdef IPU8_INSYS_NEW_ABI u16 mipi_fn; +#endif 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 { @@ -462,12 +424,14 @@ 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-dma.c b/drivers/media/pci/intel/ipu7/ipu7-dma.c index 48fdf70..d942412 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-dma.c +++ b/drivers/media/pci/intel/ipu7/ipu7-dma.c @@ -219,8 +219,6 @@ void *ipu7_dma_alloc(struct ipu7_bus_device *sys, size_t size, } } - mmu->tlb_invalidate(mmu); - info->vaddr = vmap(pages, count, VM_USERMAP, PAGE_KERNEL); if (!info->vaddr) goto out_unmap; @@ -265,16 +263,12 @@ void ipu7_dma_free(struct ipu7_bus_device *sys, size_t size, void *vaddr, { struct ipu7_mmu *mmu = sys->mmu; struct pci_dev *pdev = sys->isp->pdev; - struct iova *iova; + struct iova *iova = find_iova(&mmu->dmap->iovad, PHYS_PFN(dma_handle)); dma_addr_t pci_dma_addr, ipu7_iova; struct vm_info *info; struct page **pages; unsigned int i; - if (!mmu || !mmu->dmap) - return; - - iova = find_iova(&mmu->dmap->iovad, PHYS_PFN(dma_handle)); if (WARN_ON(!iova)) return; @@ -360,7 +354,8 @@ void ipu7_dma_unmap_sg(struct ipu7_bus_device *sys, struct scatterlist *sglist, { struct device *dev = &sys->auxdev.dev; struct ipu7_mmu *mmu = sys->mmu; - struct iova *iova; + struct iova *iova = find_iova(&mmu->dmap->iovad, + PHYS_PFN(sg_dma_address(sglist))); struct scatterlist *sg; dma_addr_t pci_dma_addr; unsigned int i; @@ -368,10 +363,6 @@ void ipu7_dma_unmap_sg(struct ipu7_bus_device *sys, struct scatterlist *sglist, if (!nents) return; - if (!mmu || !mmu->dmap) - return; - - iova = find_iova(&mmu->dmap->iovad, PHYS_PFN(sg_dma_address(sglist))); if (WARN_ON(!iova)) return; diff --git a/drivers/media/pci/intel/ipu7/ipu7-fw-isys.c b/drivers/media/pci/intel/ipu7/ipu7-fw-isys.c index c594dbd..2958e39 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-fw-isys.c +++ b/drivers/media/pci/intel/ipu7/ipu7-fw-isys.c @@ -31,118 +31,6 @@ 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 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, @@ -162,11 +50,8 @@ 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) { - size = isys->abi_ops.prepare_payload(cpu_mapped_buf, - send_type, size); + if (cpu_mapped_buf) clflush_cache_range(cpu_mapped_buf, size); - } token = ipu7_syscom_get_token(ctx, stream_handle + IPU_INSYS_INPUT_MSG_QUEUE); @@ -212,18 +97,6 @@ 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; - isys->abi_ops.decode_resp = isys_decode_resp; - isys->abi_ops.resp_queue_token_size = - sizeof(struct ipu7_insys_resp); - } else { - isys->abi_ops.prepare_payload = isys_prepare_fw_payload_v1; - isys->abi_ops.decode_resp = isys_decode_resp_v1; - isys->abi_ops.resp_queue_token_size = - sizeof(struct ipu7_insys_resp_v1); - } - adev->syscom = syscom; syscom->num_input_queues = IPU_INSYS_MAX_INPUT_QUEUES; syscom->num_output_queues = IPU_INSYS_MAX_OUTPUT_QUEUES; @@ -238,11 +111,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 = - isys->abi_ops.resp_queue_token_size; + sizeof(struct ipu7_insys_resp); 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 = - isys->abi_ops.resp_queue_token_size; + sizeof(struct ipu7_insys_resp); queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].max_capacity = 0; queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].token_size_in_bytes = 0; @@ -322,15 +195,9 @@ int ipu7_fw_isys_close(struct ipu7_isys *isys) struct ipu7_insys_resp *ipu7_fw_isys_get_resp(struct ipu7_isys *isys) { - 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; + return (struct ipu7_insys_resp *) + ipu7_syscom_get_token(isys->adev->syscom, + IPU_INSYS_OUTPUT_MSG_QUEUE); } void ipu7_fw_isys_put_resp(struct ipu7_isys *isys) @@ -460,10 +327,12 @@ 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.column_right = %d\n", + dev_dbg(dev, "\t.crop.colunm_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); @@ -471,6 +340,7 @@ void ipu7_fw_isys_dump_stream_cfg(struct device *dev, 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", @@ -483,6 +353,7 @@ 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"); } @@ -501,12 +372,18 @@ 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-csi2.c b/drivers/media/pci/intel/ipu7/ipu7-isys-csi2.c index 6ba21c3..0c931a7 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-isys-csi2.c +++ b/drivers/media/pci/intel/ipu7/ipu7-isys-csi2.c @@ -104,7 +104,7 @@ static int csi2_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, case V4L2_EVENT_FRAME_SYNC: return v4l2_event_subscribe(fh, sub, 10, NULL); case V4L2_EVENT_CTRL: - return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub); + return v4l2_ctrl_subscribe_event(fh, sub); default: return -EINVAL; } diff --git a/drivers/media/pci/intel/ipu7/ipu7-isys-queue.c b/drivers/media/pci/intel/ipu7/ipu7-isys-queue.c index 06d280e..dc6f310 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-isys-queue.c +++ b/drivers/media/pci/intel/ipu7/ipu7-isys-queue.c @@ -92,9 +92,7 @@ static int ipu7_isys_queue_setup(struct vb2_queue *q, unsigned int *num_buffers, static int ipu7_isys_buf_prepare(struct vb2_buffer *vb) { struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); - struct ipu7_isys *isys = vb2_get_drv_priv(vb->vb2_queue); struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); - struct sg_table *sg = vb2_dma_sg_plane_desc(vb, 0); struct device *dev = &av->isys->adev->auxdev.dev; u32 bytesperline = av->pix_fmt.bytesperline; u32 height = av->pix_fmt.height; @@ -109,9 +107,6 @@ static int ipu7_isys_buf_prepare(struct vb2_buffer *vb) av->vdev.name, bytesperline, height); vb2_set_plane_payload(vb, 0, bytesperline * height); - /* assume IPU is not DMA coherent */ - ipu7_dma_sync_sgtable(isys->adev, sg); - return 0; } @@ -270,9 +265,14 @@ static void ipu7_isys_buf_to_fw_frame_buf_pin(struct vb2_buffer *vb, struct ipu7_isys_video_buffer *ivb = vb2_buffer_to_ipu7_isys_video_buffer(vvb); +#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 } /* @@ -514,6 +514,10 @@ static int ipu7_isys_link_fmt_validate(struct ipu7_isys_queue *aq) static void return_buffers(struct ipu7_isys_queue *aq, enum vb2_buffer_state state) { +#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET + bool need_reset = false; + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); +#endif struct ipu7_isys_buffer *ib; struct vb2_buffer *vb; unsigned long flags; @@ -535,6 +539,9 @@ static void return_buffers(struct ipu7_isys_queue *aq, vb2_buffer_done(vb, state); spin_lock_irqsave(&aq->lock, flags); +#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET + need_reset = true; +#endif } while (!list_empty(&aq->incoming)) { @@ -550,6 +557,14 @@ static void return_buffers(struct ipu7_isys_queue *aq, } spin_unlock_irqrestore(&aq->lock, flags); +#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET + + if (need_reset) { + mutex_lock(&av->isys->reset_mutex); + av->isys->need_reset = true; + mutex_unlock(&av->isys->reset_mutex); + } +#endif } static void ipu7_isys_stream_cleanup(struct ipu7_isys_video *av) @@ -740,17 +755,7 @@ static int reset_start_streaming(struct ipu7_isys_video *av) goto out; bl = &__bl; - int retry = 5; - while (retry--) { - ret = buffer_list_get(stream, bl); - if (ret < 0) { - dev_dbg(dev, "wait for incoming buffer, retry %d\n", retry); - usleep_range(100000, 110000); - continue; - } - break; - } - + ret = buffer_list_get(stream, bl); /* * In reset start streaming and no buffer available, * it is considered that gstreamer has been closed, @@ -892,7 +897,7 @@ static void stop_streaming(struct vb2_queue *q) mutex_lock(&av->isys->reset_mutex); while (av->isys->state) { mutex_unlock(&av->isys->reset_mutex); - dev_dbg(dev, "stop: %s: wait for reset or stop, isys->state = %d\n", + dev_dbg(dev, "stop: %s: wait for rest or stop, isys->state = %d\n", av->vdev.name, av->isys->state); usleep_range(10000, 11000); mutex_lock(&av->isys->reset_mutex); @@ -1091,9 +1096,6 @@ void ipu7_isys_queue_buf_ready(struct ipu7_isys_stream *stream, struct device *dev = &isys->adev->auxdev.dev; struct ipu7_isys_buffer *ib; struct vb2_buffer *vb; -#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET - struct vb2_v4l2_buffer *vbuf; -#endif unsigned long flags; bool first = true; struct vb2_v4l2_buffer *buf; @@ -1138,14 +1140,6 @@ void ipu7_isys_queue_buf_ready(struct ipu7_isys_stream *stream, ipu7_isys_buf_calc_sequence_time(ib, time); -#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET - if (!IA_GOFO_MSG_ERR_IS_OK(info->error_info)){ - vbuf = to_vb2_v4l2_buffer(vb); - dev_dbg(dev, "buffer:%s sequence %u frame error, skip frame\n", - ipu7_isys_queue_to_video(aq)->vdev.name, vbuf->sequence); - atomic_set(&ib->skipframe_flag, 1); - } -#endif ipu7_isys_queue_buf_done(ib); return; diff --git a/drivers/media/pci/intel/ipu7/ipu7-isys-video.c b/drivers/media/pci/intel/ipu7/ipu7-isys-video.c index 3078cf2..20a0cf8 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-isys-video.c +++ b/drivers/media/pci/intel/ipu7/ipu7-isys-video.c @@ -455,12 +455,15 @@ 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 /* 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; @@ -471,6 +474,7 @@ static int ipu7_isys_fw_pin_cfg(struct ipu7_isys_video *av, 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 /* frame format type */ pfmt = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); @@ -989,12 +993,19 @@ int ipu7_isys_fw_open(struct ipu7_isys *isys) #ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET void ipu7_isys_fw_close(struct ipu7_isys *isys) { - mutex_lock(&isys->mutex); + int ret = 0; + mutex_lock(&isys->mutex); isys->ref_count--; - - if (!isys->ref_count) - ipu7_fw_isys_close(isys); + if (!isys->ref_count) { + /* need reset when fw close is abnormal */ + ret = ipu7_fw_isys_close(isys); + if (ret) { + mutex_lock(&isys->reset_mutex); + isys->need_reset = true; + mutex_unlock(&isys->reset_mutex); + } + } mutex_unlock(&isys->mutex); @@ -1155,13 +1166,13 @@ int ipu7_isys_video_init(struct ipu7_isys_video *av) __ipu_isys_vidioc_try_fmt_vid_cap(av, &format); av->pix_fmt = format.fmt.pix; - #ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET av->reset = false; av->skipframe = 0; av->start_streaming = 0; #endif + set_bit(V4L2_FL_USES_V4L2_FH, &av->vdev.flags); video_set_drvdata(&av->vdev, av); ret = video_register_device(&av->vdev, VFL_TYPE_VIDEO, -1); diff --git a/drivers/media/pci/intel/ipu7/ipu7-isys.c b/drivers/media/pci/intel/ipu7/ipu7-isys.c index bf4dfe1..00edeeb 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-isys.c +++ b/drivers/media/pci/intel/ipu7/ipu7-isys.c @@ -497,42 +497,6 @@ static int isys_csi2_create_media_links(struct ipu7_isys *isys) return 0; } -#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET -static void isys_v4l2_notify(struct v4l2_subdev *sd, unsigned int notification, - void *arg) -{ - struct ipu7_isys *isys = - container_of(sd->v4l2_dev, struct ipu7_isys, v4l2_dev); - struct device *dev = &isys->adev->auxdev.dev; - struct v4l2_event *ev = arg; - unsigned long flags; - - spin_lock_irqsave(&isys->power_lock, flags); - if (!isys->power) { - spin_unlock_irqrestore(&isys->power_lock, flags); - dev_dbg(dev, "%s: isys powered off, ignore notify %u\n", - sd->name, notification); - return; - } - spin_unlock_irqrestore(&isys->power_lock, flags); - - if (notification == V4L2_DEVICE_NOTIFY_EVENT) { - if ((ev->type == V4L2_EVENT_SOURCE_CHANGE || - ev->type == V4L2_EVENT_EOS) && - isys->stream_opened > 1) { - dev_dbg(dev, "%s: isys need reset due to notify %u, stream opened %d\n", - sd->name, ev->type, isys->stream_opened); - mutex_lock(&isys->reset_mutex); - isys->need_reset = true; - mutex_unlock(&isys->reset_mutex); - } - } else { - dev_warn(dev, "%s: unknown notification %u\n", - sd->name, notification); - } -} -#endif - #if IS_ENABLED(CONFIG_INTEL_IPU_ACPI) static int isys_register_devices(struct ipu7_isys *isys) { @@ -553,9 +517,6 @@ static int isys_register_devices(struct ipu7_isys *isys) isys->v4l2_dev.mdev = &isys->media_dev; isys->v4l2_dev.ctrl_handler = NULL; -#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET - isys->v4l2_dev.notify = isys_v4l2_notify; -#endif ret = v4l2_device_register(dev, &isys->v4l2_dev); if (ret < 0) goto out_media_device_unregister; @@ -1115,7 +1076,7 @@ static int isys_probe(struct auxiliary_device *auxdev, #endif cpu_latency_qos_add_request(&isys->pm_qos, PM_QOS_DEFAULT_VALUE); - ret = alloc_fw_msg_bufs(isys, 20); + ret = alloc_fw_msg_bufs(isys, 40); if (ret < 0) goto out_cleanup_isys; @@ -1131,6 +1092,9 @@ static int isys_probe(struct auxiliary_device *auxdev, if (ret) goto out_cleanup; +#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET + mutex_destroy(&isys->reset_mutex); +#endif ipu7_mmu_hw_cleanup(adev->mmu); pm_runtime_put(&auxdev->dev); @@ -1141,9 +1105,6 @@ static int isys_probe(struct auxiliary_device *auxdev, out_cleanup_fw: ipu7_fw_isys_release(isys); out_cleanup_isys: -#ifdef CONFIG_VIDEO_INTEL_IPU7_ISYS_RESET - mutex_destroy(&isys->reset_mutex); -#endif cpu_latency_qos_remove_request(&isys->pm_qos); for (unsigned int i = 0; i < IPU_ISYS_MAX_STREAMS; i++) diff --git a/drivers/media/pci/intel/ipu7/ipu7-isys.h b/drivers/media/pci/intel/ipu7/ipu7-isys.h index c950f24..2e45258 100644 --- a/drivers/media/pci/intel/ipu7/ipu7-isys.h +++ b/drivers/media/pci/intel/ipu7/ipu7-isys.h @@ -67,13 +67,6 @@ 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 * @@ -131,8 +124,6 @@ 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/drivers/media/pci/intel/ipu7/ipu7.c b/drivers/media/pci/intel/ipu7/ipu7.c index 18aebd0..64ac54a 100644 --- a/drivers/media/pci/intel/ipu7/ipu7.c +++ b/drivers/media/pci/intel/ipu7/ipu7.c @@ -2753,6 +2753,7 @@ static void ipu7_pci_remove(struct pci_dev *pdev) ipu_buttress_exit(isp); release_firmware(isp->cpd_fw); + } static void ipu7_pci_reset_prepare(struct pci_dev *pdev) @@ -2783,6 +2784,10 @@ static void ipu7_pci_reset_done(struct pci_dev *pdev) */ static int ipu7_suspend(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); + + synchronize_irq(pdev->irq); + return 0; } diff --git a/drivers/media/pci/intel/ipu7/psys/ipu-psys.c b/drivers/media/pci/intel/ipu7/psys/ipu-psys.c index d89e8b6..838f0b2 100644 --- a/drivers/media/pci/intel/ipu7/psys/ipu-psys.c +++ b/drivers/media/pci/intel/ipu7/psys/ipu-psys.c @@ -84,10 +84,8 @@ static int ipu7_psys_get_userpages(struct ipu7_dma_buf_attach *attach) flags = FOLL_WRITE | FOLL_FORCE | FOLL_LONGTERM; nr = pin_user_pages_fast(start & PAGE_MASK, npages, flags, pages); - if (nr < npages) { - ret = nr < 0 ? nr : -EFAULT; + if (nr < npages) goto error; - } attach->pages = pages; attach->npages = npages; @@ -105,7 +103,7 @@ static int ipu7_psys_get_userpages(struct ipu7_dma_buf_attach *attach) error_up_read: mmap_read_unlock(current->mm); error: - if (nr > 0) + if (nr) unpin_user_pages(pages, nr); kvfree(pages); diff --git a/drivers/media/platform/intel/ipu-acpi-pdata.c b/drivers/media/platform/intel/ipu-acpi-pdata.c index 5ac086a..3162387 100644 --- a/drivers/media/platform/intel/ipu-acpi-pdata.c +++ b/drivers/media/platform/intel/ipu-acpi-pdata.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2016-2026 Intel Corporation. + * Copyright (c) 2016-2025 Intel Corporation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version @@ -125,13 +125,6 @@ static void print_serdes_sdinfo(struct serdes_subdev_info *sdinfo) pr_debug("\t\tsuffix \t\t\t= %s", sdinfo->suffix); pr_debug("\t\tboard_info.type \t= %s", sdinfo->board_info.type); pr_debug("\t\tboard_info.addr \t= 0x%x", sdinfo->board_info.addr); - pr_debug("\t\tser_gpio \t\t= "); - for (i = 0; i < MAX_SER_GPIO_NUM; i++) { - pr_debug("\t\t\t\t\tpin[%d] = %d, func = %s, flags = %lu", i, - sdinfo->ser_gpio[i].chip_hwnum, - sdinfo->ser_gpio[i].con_id, sdinfo->ser_gpio[i].flags); - } - pr_debug("\t\tsensor_dt \t\t= %x", sdinfo->sensor_dt); pr_debug("serdes board_info.platform_data"); pr_debug("\t\tlanes \t\t\t= %d", sd_mpdata->lanes); @@ -217,7 +210,7 @@ static void print_subdev(struct ipu_isys_subdev_info *sd) pr_debug("\t\ti2c_slave_address \t= 0x%x", spdata->i2c_slave_address); pr_debug("\t\tirq_pin \t\t= %d", spdata->irq_pin); pr_debug("\t\tirq_pin_name \t\t= %s", spdata->irq_pin_name); - pr_debug("\t\tsuffix \t\t\t= %s", spdata->suffix); + pr_debug("\t\tsuffix \t\t\t= %c", spdata->suffix); pr_debug("\t\treset_pin \t\t= %d", spdata->reset_pin); pr_debug("\t\tdetect_pin \t\t= %d", spdata->detect_pin); @@ -262,21 +255,10 @@ static void update_hex(struct device *dev, } } -static void update_uint(struct device *dev, +static void update_int(struct device *dev, char msg[MSG_LEN], unsigned int *old_int, unsigned int new_int) -{ - if (*old_int != new_int) { - dev_info(dev, "%s %u -> %u", msg, *old_int, new_int); - *old_int = new_int; - } -} - -static void update_int(struct device *dev, - char msg[MSG_LEN], - int *old_int, - int new_int) { if (*old_int != new_int) { dev_info(dev, "%s %d -> %d", msg, *old_int, new_int); @@ -322,8 +304,8 @@ static void update_subdev(struct device *dev, new_sd->i2c.board_info.platform_data; /* csi2 */ - update_uint(dev, "CSI2 port", &(*old_sd)->csi2->port, new_sd->csi2->port); - update_uint(dev, "CSI2 nlanes", &(*old_sd)->csi2->nlanes, new_sd->csi2->nlanes); + update_int(dev, "CSI2 port", &(*old_sd)->csi2->port, new_sd->csi2->port); + update_int(dev, "CSI2 nlanes", &(*old_sd)->csi2->nlanes, new_sd->csi2->nlanes); /* i2c */ update_short(dev, "I2C board_info addr", &(*old_sd)->i2c.board_info.addr, @@ -332,8 +314,8 @@ static void update_subdev(struct device *dev, new_sd->i2c.i2c_adapter_bdf); /* platform data */ - update_uint(dev, "pdata port", &(old_pdata)->port, new_pdata->port); - update_uint(dev, "pdata lanes", &(old_pdata)->lanes, new_pdata->lanes); + update_int(dev, "pdata port", &(old_pdata)->port, new_pdata->port); + update_int(dev, "pdata lanes", &(old_pdata)->lanes, new_pdata->lanes); update_hex(dev, "pdata I2C slave addr", &(old_pdata)->i2c_slave_address, new_pdata->i2c_slave_address); update_int(dev, "pdata irq_pin", &(old_pdata)->irq_pin, new_pdata->irq_pin); @@ -358,8 +340,8 @@ static void update_serdes_subdev(struct device *dev, struct serdes_module_pdata *old_mpdata, *new_mpdata; /* csi2 */ - update_uint(dev, "CSI2 port", &(*old_sd)->csi2->port, new_sd->csi2->port); - update_uint(dev, "CSI2 nlanes", &(*old_sd)->csi2->nlanes, new_sd->csi2->nlanes); + update_int(dev, "CSI2 port", &(*old_sd)->csi2->port, new_sd->csi2->port); + update_int(dev, "CSI2 nlanes", &(*old_sd)->csi2->nlanes, new_sd->csi2->nlanes); /* i2c */ update_short(dev, "I2C board_info addr", &(*old_sd)->i2c.board_info.addr, @@ -367,9 +349,9 @@ static void update_serdes_subdev(struct device *dev, update_str(dev, "I2C i2c_adapter_bdf", (*old_sd)->i2c.i2c_adapter_bdf, new_sd->i2c.i2c_adapter_bdf); - update_uint(dev, "I2C Pdata reset_gpio", &old_pdata->reset_gpio, + update_int(dev, "I2C Pdata reset_gpio", &old_pdata->reset_gpio, new_pdata->reset_gpio); - update_uint(dev, "I2C Pdata FPD_gpio", &old_pdata->FPD_gpio, new_pdata->FPD_gpio); + update_int(dev, "I2C Pdata FPD_gpio", &old_pdata->FPD_gpio, new_pdata->FPD_gpio); /* platform data */ for (i = 0; i < SERDES_MAX_PORT; i++) { @@ -380,7 +362,7 @@ static void update_serdes_subdev(struct device *dev, new_mpdata = new_sdinfo->board_info.platform_data; if (!strcmp(old_sdinfo->board_info.type, new_sdinfo->board_info.type) && - !strcmp(old_sdinfo->suffix, new_sdinfo->suffix)) { + old_sdinfo->suffix == new_sdinfo->suffix) { update_short(dev, "SdInfo port", &old_sdinfo->rx_port, new_sdinfo->rx_port); update_short(dev, "SdInfo ser_alias", &old_sdinfo->ser_alias, @@ -389,7 +371,7 @@ static void update_serdes_subdev(struct device *dev, new_sdinfo->board_info.addr); if (!strcmp(old_mpdata->module_name, new_mpdata->module_name)) { - update_uint(dev, "mPdata lanes", &old_mpdata->lanes, + update_int(dev, "mPdata lanes", &old_mpdata->lanes, new_mpdata->lanes); update_int(dev, "mPdata fsin", &old_mpdata->fsin, new_mpdata->fsin); @@ -428,8 +410,8 @@ static int compare_subdev(struct device *dev, new_pdata = (struct sensor_platform_data *) new_subdev->i2c.board_info.platform_data; - if (!strcmp(old_pdata->suffix, new_pdata->suffix)) { - dev_info(dev, "Found matching sensor : %s %s", + if (old_pdata->suffix == new_pdata->suffix) { + dev_info(dev, "Found matching sensor : %s %c", old_subdev->i2c.board_info.type, old_pdata->suffix); return 0; @@ -504,7 +486,7 @@ static void update_pdata(struct device *dev, acpi_pdata = (struct sensor_platform_data *) acpi_subdev->i2c.board_info.platform_data; - dev_err(dev, "Pdata does not contain %s %s\n", + dev_err(dev, "Pdata does not contain %s %c\n", acpi_subdev->i2c.board_info.type, acpi_pdata->suffix); @@ -712,10 +694,10 @@ static int set_serdes_subdev(struct ipu_isys_subdev_info **serdes_sd, serdes_sdinfo[i].phy_i2c_addr = serdes_info.phy_i2c_addr; snprintf(serdes_sdinfo[i].suffix, sizeof(serdes_sdinfo[i].suffix), "%c-%d", SUFFIX_BASE + i, port); - serdes_sdinfo[i].ser_phys_addr = serdes_info.ser_phys_addr; - - memcpy(serdes_sdinfo[i].ser_gpio, serdes_info.ser_gpio, sizeof(struct gpiod_lookup) * MAX_SER_GPIO_NUM); - serdes_sdinfo[i].sensor_dt = serdes_info.sensor_dt; +#if IS_ENABLED(CONFIG_VIDEO_ISX031) + serdes_sdinfo[i].ser_phys_addr = 0x40; + serdes_sdinfo[i].sensor_dt = 0x1e; +#endif } (*pdata)->subdev_info = serdes_sdinfo; @@ -750,7 +732,7 @@ static int set_pdata(struct ipu_isys_subdev_info **sensor_sd, /* use ascii */ /* port for start from 0 */ if (port >= 0) { - snprintf(pdata->suffix, sizeof(pdata->suffix), "%c", port + SUFFIX_BASE); + pdata->suffix = port + SUFFIX_BASE; pr_info("IPU ACPI: create %s on port %d", sensor_name, port); } else @@ -811,10 +793,7 @@ static int set_pdata(struct ipu_isys_subdev_info **sensor_sd, static void set_serdes_info(struct device *dev, const char *sensor_name, const char *serdes_name, struct sensor_bios_data *cam_data, - int sensor_physical_addr, - int ser_physical_addr, - const struct gpiod_lookup *ser_gpio, - unsigned int sensor_dt) + int sensor_physical_addr) { int i; @@ -828,8 +807,6 @@ static void set_serdes_info(struct device *dev, const char *sensor_name, i = 1; /* serializer mapped addr */ serdes_info.ser_map_addr = cam_data->i2c[i++].addr; - /* serializer physical addr */ - serdes_info.ser_phys_addr = ser_physical_addr; /* sensor mapped addr */ serdes_info.sensor_map_addr = cam_data->i2c[i++].addr; @@ -844,14 +821,6 @@ static void set_serdes_info(struct device *dev, const char *sensor_name, serdes_info.gpio_powerup_seq = 0; serdes_info.phy_i2c_addr = sensor_physical_addr; - - /* ser_gpio is random numbering. re-order and only update serdes_info.ser_gpio if valid. */ - for (int i = 0; i < MAX_SER_GPIO_NUM; i++) { - if (ser_gpio[i].chip_hwnum < MAX_SER_GPIO_NUM && - ser_gpio[i].con_id) - serdes_info.ser_gpio[i] = ser_gpio[i]; - } - serdes_info.sensor_dt = sensor_dt; } #if IS_ENABLED(CONFIG_VIDEO_LT6911UXC) || IS_ENABLED(CONFIG_VIDEO_LT6911UXE) @@ -903,10 +872,7 @@ static int populate_sensor_pdata(struct device *dev, const char *serdes_name, const char *hid_name, int sensor_physical_addr, - int link_freq, - int ser_physical_addr, - const struct gpiod_lookup *ser_gpio, - unsigned int sensor_dt) + int link_freq) { int ret; @@ -972,7 +938,7 @@ static int populate_sensor_pdata(struct device *dev, } /* local serdes info */ - set_serdes_info(dev, sensor_name, serdes_name, cam_data, sensor_physical_addr, ser_physical_addr, ser_gpio, sensor_dt); + set_serdes_info(dev, sensor_name, serdes_name, cam_data, sensor_physical_addr); } /* Use last I2C device */ @@ -999,12 +965,12 @@ static int populate_sensor_pdata(struct device *dev, return 0; } -int get_sensor_pdata(struct device *dev, struct ipu_camera_module_data *data, - void *priv, size_t size, enum connection_type connect, - const char *sensor_name, const char *serdes_name, - const char *hid_name, int sensor_physical_addr, - int link_freq, int ser_physical_addr, const struct gpiod_lookup *ser_gpio, - unsigned int sensor_dt) +int get_sensor_pdata(struct device *dev, + struct ipu_camera_module_data *data, + void *priv, size_t size, + enum connection_type connect, const char *sensor_name, + const char *serdes_name, const char *hid_name, + int sensor_physical_addr, int link_freq) { struct sensor_bios_data *cam_data; struct control_logic_data *ctl_data; @@ -1052,9 +1018,8 @@ int get_sensor_pdata(struct device *dev, struct ipu_camera_module_data *data, /* populate pdata */ rval = populate_sensor_pdata(dev, &sensor_sd, cam_data, ctl_data, - connect, sensor_name, serdes_name, - hid_name, sensor_physical_addr, link_freq, ser_physical_addr, ser_gpio, - sensor_dt); + connect, sensor_name, serdes_name, hid_name, + sensor_physical_addr, link_freq); if (rval) { kfree(sensor_sd); kfree(cam_data); diff --git a/drivers/media/platform/intel/ipu-acpi.c b/drivers/media/platform/intel/ipu-acpi.c index ddb17ff..6f53897 100644 --- a/drivers/media/platform/intel/ipu-acpi.c +++ b/drivers/media/platform/intel/ipu-acpi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2016-2026 Intel Corporation. + * Copyright (c) 2016-2025 Intel Corporation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version @@ -37,10 +37,6 @@ #include #include -#if IS_ENABLED(CONFIG_VIDEO_ISX031) -#include -#endif - static LIST_HEAD(devices); static struct ipu_camera_module_data *add_device_to_list( @@ -80,31 +76,8 @@ static const struct ipu_acpi_devices supported_devices[] = { #if IS_ENABLED(CONFIG_VIDEO_MAX9X) #if IS_ENABLED(CONFIG_VIDEO_ISX031) - { - .hid_name = "INTC031M", - .real_driver = ISX031_NAME, - .get_platform_data = get_sensor_pdata, - .priv_data = NULL, - .priv_size = 0, - .connect = TYPE_SERDES, - .serdes_name = "max9x", - .sensor_physical_addr = ISX031_I2C_ADDRESS, - .link_freq = 1600, - .ser_physical_addr = 0x40, - .ser_gpio = { - { - .chip_hwnum = 0, - .con_id = "reset", - .flags = GPIO_ACTIVE_LOW, - }, - { - .chip_hwnum = 7, - .con_id = "fsin", - .flags = GPIO_ACTIVE_LOW, - }, - }, - .sensor_dt = MIPI_CSI2_TYPE_YUV422_8, - }, // ISX031 HID + { "INTC031M", ISX031_NAME, get_sensor_pdata, NULL, 0, TYPE_SERDES, "max9x", + ISX031_I2C_ADDRESS, 1600 }, // D3 ISX031 HID #endif #endif }; @@ -180,10 +153,7 @@ static int ipu_acpi_get_pdata(struct device *dev, int index) supported_devices[index].serdes_name, supported_devices[index].hid_name, supported_devices[index].sensor_physical_addr, - supported_devices[index].link_freq, - supported_devices[index].ser_physical_addr, - supported_devices[index].ser_gpio, - supported_devices[index].sensor_dt); + supported_devices[index].link_freq); if (rval) return -EPROBE_DEFER; diff --git a/include/media/ipu-acpi-pdata.h b/include/media/ipu-acpi-pdata.h index 17e95eb..4c754e9 100644 --- a/include/media/ipu-acpi-pdata.h +++ b/include/media/ipu-acpi-pdata.h @@ -1,8 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2023-2026 Intel Corporation */ -#ifndef _MEDIA_IPU_ACPI_PDATA_H_ -#define _MEDIA_IPU_ACPI_PDATA_H_ - +/* Copyright (C) 2023-2025 Intel Corporation */ #include #include #include @@ -27,10 +24,7 @@ int get_sensor_pdata(struct device *dev, const char *serdes_name, const char *hid_name, int sensor_physical_addr, - int link_freq, - int ser_physical_addr, - const struct gpiod_lookup *ser_gpio, - unsigned int sensor_dt); + int link_freq); struct ipu_isys_subdev_pdata *get_acpi_subdev_pdata(void); @@ -43,7 +37,7 @@ struct sensor_platform_data { char irq_pin_name[IPU_SPDATA_IRQ_PIN_NAME_LEN]; int reset_pin; int detect_pin; - char suffix[MAX_SUFFIX_LEN]; + char suffix; int gpios[IPU_SPDATA_GPIO_NUM]; }; @@ -57,7 +51,7 @@ struct serdes_module_pdata { char gpio_powerup_seq[SERDES_MAX_GPIO_POWERUP_SEQ]; unsigned int module_flags; char module_name[I2C_NAME_SIZE]; - char suffix[MAX_SUFFIX_LEN]; + char suffix; }; struct serdes_local { @@ -97,15 +91,4 @@ struct serdes_local { /* counter for total deser connected */ unsigned int deser_num; - - /* serializer physical addr */ - unsigned short ser_phys_addr; - - /* serializer gpio */ - struct gpiod_lookup ser_gpio[MAX_SER_GPIO_NUM]; - - /* sensor data type */ - unsigned int sensor_dt; }; - -#endif diff --git a/include/media/ipu-acpi.h b/include/media/ipu-acpi.h index f31833f..f06b686 100644 --- a/include/media/ipu-acpi.h +++ b/include/media/ipu-acpi.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2016-2026 Intel Corporation. + * Copyright (c) 2016-2025 Intel Corporation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version @@ -13,13 +13,12 @@ * */ -#ifndef _MEDIA_IPU_ACPI_H_ -#define _MEDIA_IPU_ACPI_H_ +#ifndef MEDIA_INTEL_IPU_ACPI_H +#define MEDIA_INTEL_IPU_ACPI_H #include #include -#include #include #include @@ -57,7 +56,6 @@ struct ipu_isys_subdev_pdata { #define MAX_ACPI_SENSOR_NUM 4 #define MAX_ACPI_I2C_NUM 12 #define MAX_ACPI_GPIO_NUM 12 -#define MAX_SER_GPIO_NUM 11 #define GPIO_RESET 0x0 #define GPIO_POWER_EN 0xb @@ -66,9 +64,6 @@ struct ipu_isys_subdev_pdata { #define IPU_SPDATA_GPIO_NUM 4 #define IPU_SPDATA_IRQ_PIN_NAME_LEN 16 -#define MAX_SUFFIX_LEN 5 - -#define MIPI_CSI2_TYPE_YUV422_8 0x1e void set_built_in_pdata(struct ipu_isys_subdev_pdata *pdata); @@ -234,19 +229,13 @@ struct ipu_acpi_devices { const char *serdes_name, const char *hid_name, int sensor_physical_addr, - int link_freq, - int ser_physical_addr, - const struct gpiod_lookup *ser_gpio, - unsigned int sensor_dt); + int link_freq); void *priv_data; size_t priv_size; enum connection_type connect; const char *serdes_name; int sensor_physical_addr; int link_freq; /* in mbps */ - int ser_physical_addr; - struct gpiod_lookup ser_gpio[MAX_SER_GPIO_NUM]; - unsigned int sensor_dt; }; #endif diff --git a/include/media/serdes-pdata.h b/include/media/serdes-pdata.h index af31389..a2eee0e 100644 --- a/include/media/serdes-pdata.h +++ b/include/media/serdes-pdata.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2023-2026 Intel Corporation */ +/* Copyright (C) 2023-2025 Intel Corporation */ -#ifndef _MEDIA_SERDES_PDATA_H_ -#define _MEDIA_SERDES_PDATA_H_ +#ifndef MEDIA_SERDES_PDATA_H +#define MEDIA_SERDES_PDATA_H #if IS_ENABLED(CONFIG_VIDEO_AR0234) #include @@ -22,8 +22,9 @@ #if IS_ENABLED(CONFIG_VIDEO_IMX390) #include #endif - -#include +#if IS_ENABLED(CONFIG_VIDEO_ISX031) +#include +#endif struct serdes_subdev_info { struct i2c_board_info board_info; @@ -31,10 +32,9 @@ struct serdes_subdev_info { unsigned short rx_port; unsigned short phy_i2c_addr; unsigned short ser_alias; - char suffix[MAX_SUFFIX_LEN]; /* suffix for subdevs */ + char suffix[5]; /* suffix for subdevs */ unsigned short ser_phys_addr; unsigned int sensor_dt; - struct gpiod_lookup ser_gpio[MAX_SER_GPIO_NUM]; }; struct serdes_platform_data { diff --git a/patch/7.0.5/0001-staging-ipu7-Use-DPHY-as-the-default-PHY-mode.patch b/patch/7.0.5/0001-staging-ipu7-Use-DPHY-as-the-default-PHY-mode.patch new file mode 100644 index 0000000..36ad1a2 --- /dev/null +++ b/patch/7.0.5/0001-staging-ipu7-Use-DPHY-as-the-default-PHY-mode.patch @@ -0,0 +1,31 @@ +From 90cbd8c0f39a2f9863c6b2b3bacc1d44fc2356bf Mon Sep 17 00:00:00 2001 +From: linya14x +Date: Fri, 24 Oct 2025 12:44:25 +0800 +Subject: [PATCH 1/7] staging: ipu7: Use DPHY as the default PHY mode + +Signed-off-by: Bingbu Cao +--- + drivers/staging/media/ipu7/ipu7-isys.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/media/ipu7/ipu7-isys.c b/drivers/staging/media/ipu7/ipu7-isys.c +index cb2f49f3e0fa..dd481f9d848d 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys.c ++++ b/drivers/staging/media/ipu7/ipu7-isys.c +@@ -81,10 +81,10 @@ isys_complete_ext_device_registration(struct ipu7_isys *isys, + } + + isys->csi2[csi2->port].nlanes = csi2->nlanes; +- if (csi2->bus_type == V4L2_MBUS_CSI2_DPHY) +- isys->csi2[csi2->port].phy_mode = PHY_MODE_DPHY; +- else ++ if (csi2->bus_type == V4L2_MBUS_CSI2_CPHY) + isys->csi2[csi2->port].phy_mode = PHY_MODE_CPHY; ++ else ++ isys->csi2[csi2->port].phy_mode = PHY_MODE_DPHY; + + return 0; + +-- +2.43.0 + diff --git a/patch/7.0.5/0002-staging-ipu7-Add-IPU7-debugfs.patch b/patch/7.0.5/0002-staging-ipu7-Add-IPU7-debugfs.patch new file mode 100644 index 0000000..3796418 --- /dev/null +++ b/patch/7.0.5/0002-staging-ipu7-Add-IPU7-debugfs.patch @@ -0,0 +1,270 @@ +From 394a1a7002677bcbbe8f3e1f053a65d001040cc9 Mon Sep 17 00:00:00 2001 +From: linya14x +Date: Mon, 20 Oct 2025 12:36:12 +0800 +Subject: [PATCH 2/7] staging: ipu7: Add IPU7 debugfs + +Signed-off-by: Hao Yao +--- + drivers/staging/media/ipu7/ipu7-isys.c | 84 ++++++++++++++++++++++++++ + drivers/staging/media/ipu7/ipu7-isys.h | 7 +++ + drivers/staging/media/ipu7/ipu7.c | 60 ++++++++++++++++++ + drivers/staging/media/ipu7/ipu7.h | 3 + + 4 files changed, 154 insertions(+) + +diff --git a/drivers/staging/media/ipu7/ipu7-isys.c b/drivers/staging/media/ipu7/ipu7-isys.c +index dd481f9d848d..b81ba4e7f786 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys.c ++++ b/drivers/staging/media/ipu7/ipu7-isys.c +@@ -9,6 +9,9 @@ + #include + #include + #include ++#ifdef CONFIG_DEBUG_FS ++#include ++#endif + #include + #include + #include +@@ -576,6 +579,10 @@ static void isys_remove(struct auxiliary_device *auxdev) + struct isys_fw_msgs *fwmsg, *safe; + struct ipu7_bus_device *adev = auxdev_to_adev(auxdev); + ++#ifdef CONFIG_DEBUG_FS ++ if (adev->isp->ipu7_dir) ++ debugfs_remove_recursive(isys->debugfsdir); ++#endif + for (int i = 0; i < IPU_ISYS_MAX_STREAMS; i++) + mutex_destroy(&isys->streams[i].mutex); + +@@ -596,6 +603,78 @@ static void isys_remove(struct auxiliary_device *auxdev) + mutex_destroy(&isys->mutex); + } + ++#ifdef CONFIG_DEBUG_FS ++static ssize_t fwlog_read(struct file *file, char __user *userbuf, size_t size, ++ loff_t *pos) ++{ ++ struct ipu7_isys *isys = file->private_data; ++ struct isys_fw_log *fw_log = isys->fw_log; ++ struct device *dev = &isys->adev->auxdev.dev; ++ u32 log_size; ++ int ret = 0; ++ void *buf; ++ ++ if (!fw_log) ++ return 0; ++ ++ buf = kvzalloc(FW_LOG_BUF_SIZE, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ mutex_lock(&fw_log->mutex); ++ if (!fw_log->size) { ++ dev_warn(dev, "no available fw log\n"); ++ mutex_unlock(&fw_log->mutex); ++ goto free_and_return; ++ } ++ ++ if (fw_log->size > FW_LOG_BUF_SIZE) ++ log_size = FW_LOG_BUF_SIZE; ++ else ++ log_size = fw_log->size; ++ ++ memcpy(buf, fw_log->addr, log_size); ++ dev_info(dev, "copy %d bytes fw log to user...\n", log_size); ++ mutex_unlock(&fw_log->mutex); ++ ++ ret = simple_read_from_buffer(userbuf, size, pos, buf, ++ log_size); ++free_and_return: ++ kvfree(buf); ++ ++ return ret; ++} ++ ++static const struct file_operations isys_fw_log_fops = { ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .read = fwlog_read, ++ .llseek = default_llseek, ++}; ++ ++static int ipu7_isys_init_debugfs(struct ipu7_isys *isys) ++{ ++ struct dentry *file; ++ struct dentry *dir; ++ ++ dir = debugfs_create_dir("isys", isys->adev->isp->ipu7_dir); ++ if (IS_ERR(dir)) ++ return -ENOMEM; ++ ++ file = debugfs_create_file("fwlog", 0400, ++ dir, isys, &isys_fw_log_fops); ++ if (IS_ERR(file)) ++ goto err; ++ ++ isys->debugfsdir = dir; ++ ++ return 0; ++err: ++ debugfs_remove_recursive(dir); ++ return -ENOMEM; ++} ++#endif ++ + static int alloc_fw_msg_bufs(struct ipu7_isys *isys, int amount) + { + struct ipu7_bus_device *adev = isys->adev; +@@ -750,6 +829,11 @@ static int isys_probe(struct auxiliary_device *auxdev, + + isys_stream_init(isys); + ++#ifdef CONFIG_DEBUG_FS ++ /* Debug fs failure is not fatal. */ ++ ipu7_isys_init_debugfs(isys); ++#endif ++ + cpu_latency_qos_add_request(&isys->pm_qos, PM_QOS_DEFAULT_VALUE); + ret = alloc_fw_msg_bufs(isys, 20); + if (ret < 0) +diff --git a/drivers/staging/media/ipu7/ipu7-isys.h b/drivers/staging/media/ipu7/ipu7-isys.h +index ef1ab1b42f6c..2579669c21a9 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys.h ++++ b/drivers/staging/media/ipu7/ipu7-isys.h +@@ -25,6 +25,10 @@ + #include "ipu7-isys-csi2.h" + #include "ipu7-isys-video.h" + ++#ifdef CONFIG_DEBUG_FS ++struct dentry; ++ ++#endif + #define IPU_ISYS_ENTITY_PREFIX "Intel IPU7" + + /* FW support max 16 streams */ +@@ -92,6 +96,9 @@ struct ipu7_isys { + unsigned int ref_count; + unsigned int stream_opened; + ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *debugfsdir; ++#endif + struct mutex mutex; /* Serialise isys video open/release related */ + struct mutex stream_mutex; /* Stream start, stop, queueing reqs */ + +diff --git a/drivers/staging/media/ipu7/ipu7.c b/drivers/staging/media/ipu7/ipu7.c +index 5cddc09c72bf..a4b0264cc5c7 100644 +--- a/drivers/staging/media/ipu7/ipu7.c ++++ b/drivers/staging/media/ipu7/ipu7.c +@@ -7,6 +7,9 @@ + #include + #include + #include ++#ifdef CONFIG_DEBUG_FS ++#include ++#endif + #include + #include + #include +@@ -2247,6 +2250,49 @@ void ipu7_dump_fw_error_log(const struct ipu7_bus_device *adev) + } + EXPORT_SYMBOL_NS_GPL(ipu7_dump_fw_error_log, "INTEL_IPU7"); + ++#ifdef CONFIG_DEBUG_FS ++static struct debugfs_blob_wrapper isys_fw_error; ++static struct debugfs_blob_wrapper psys_fw_error; ++ ++static int ipu7_init_debugfs(struct ipu7_device *isp) ++{ ++ struct dentry *file; ++ struct dentry *dir; ++ ++ dir = debugfs_create_dir(pci_name(isp->pdev), NULL); ++ if (!dir) ++ return -ENOMEM; ++ ++ isys_fw_error.data = &fw_error_log[IPU_IS]; ++ isys_fw_error.size = sizeof(fw_error_log[IPU_IS]); ++ file = debugfs_create_blob("is_fw_error", 0400, dir, &isys_fw_error); ++ if (!file) ++ goto err; ++ psys_fw_error.data = &fw_error_log[IPU_PS]; ++ psys_fw_error.size = sizeof(fw_error_log[IPU_PS]); ++ file = debugfs_create_blob("ps_fw_error", 0400, dir, &psys_fw_error); ++ if (!file) ++ goto err; ++ ++ isp->ipu7_dir = dir; ++ ++ return 0; ++err: ++ debugfs_remove_recursive(dir); ++ return -ENOMEM; ++} ++ ++static void ipu7_remove_debugfs(struct ipu7_device *isp) ++{ ++ /* ++ * Since isys and psys debugfs dir will be created under ipu root dir, ++ * mark its dentry to NULL to avoid duplicate removal. ++ */ ++ debugfs_remove_recursive(isp->ipu7_dir); ++ isp->ipu7_dir = NULL; ++} ++#endif /* CONFIG_DEBUG_FS */ ++ + static void ipu7_pci_config_setup(struct pci_dev *dev) + { + u16 pci_command; +@@ -2603,6 +2649,13 @@ static int ipu7_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + pm_runtime_put(&isp->psys->auxdev.dev); + } + ++#ifdef CONFIG_DEBUG_FS ++ ret = ipu7_init_debugfs(isp); ++ if (ret) { ++ dev_err_probe(dev, ret, "Failed to initialize debugfs\n"); ++ goto out_ipu_bus_del_devices; ++ } ++#endif + pm_runtime_put_noidle(dev); + pm_runtime_allow(dev); + +@@ -2615,6 +2668,10 @@ static int ipu7_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + ipu7_unmap_fw_code_region(isp->isys); + if (!IS_ERR_OR_NULL(isp->psys) && isp->psys->fw_sgt.nents) + ipu7_unmap_fw_code_region(isp->psys); ++#ifdef CONFIG_DEBUG_FS ++ if (!IS_ERR_OR_NULL(isp->fw_code_region)) ++ vfree(isp->fw_code_region); ++#endif + if (!IS_ERR_OR_NULL(isp->psys) && !IS_ERR_OR_NULL(isp->psys->mmu)) + ipu7_mmu_cleanup(isp->psys->mmu); + if (!IS_ERR_OR_NULL(isp->isys) && !IS_ERR_OR_NULL(isp->isys->mmu)) +@@ -2635,6 +2692,9 @@ static void ipu7_pci_remove(struct pci_dev *pdev) + { + struct ipu7_device *isp = pci_get_drvdata(pdev); + ++#ifdef CONFIG_DEBUG_FS ++ ipu7_remove_debugfs(isp); ++#endif + if (!IS_ERR_OR_NULL(isp->isys) && isp->isys->fw_sgt.nents) + ipu7_unmap_fw_code_region(isp->isys); + if (!IS_ERR_OR_NULL(isp->psys) && isp->psys->fw_sgt.nents) +diff --git a/drivers/staging/media/ipu7/ipu7.h b/drivers/staging/media/ipu7/ipu7.h +index ac8ac0689468..3b3ea5fb613f 100644 +--- a/drivers/staging/media/ipu7/ipu7.h ++++ b/drivers/staging/media/ipu7/ipu7.h +@@ -81,6 +81,9 @@ struct ipu7_device { + + void __iomem *base; + void __iomem *pb_base; ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *ipu7_dir; ++#endif + u8 hw_ver; + bool ipc_reinit; + bool secure_mode; +-- +2.43.0 + diff --git a/patch/7.0.5/0003-staging-ipu7-Add-PSYS-Makefile-and-Kconfig.patch b/patch/7.0.5/0003-staging-ipu7-Add-PSYS-Makefile-and-Kconfig.patch new file mode 100644 index 0000000..b520734 --- /dev/null +++ b/patch/7.0.5/0003-staging-ipu7-Add-PSYS-Makefile-and-Kconfig.patch @@ -0,0 +1,50 @@ +From 6a69dcf953751f2e92fd62eece787c14dea29c0c Mon Sep 17 00:00:00 2001 +From: linya14x +Date: Mon, 17 Nov 2025 16:39:47 +0800 +Subject: [PATCH 3/7] staging: ipu7: Add PSYS Makefile and Kconfig + +Signed-off-by: Hao Yao +--- + drivers/staging/media/ipu7/Kconfig | 11 ++++++++--- + drivers/staging/media/ipu7/Makefile | 2 ++ + 2 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/media/ipu7/Kconfig b/drivers/staging/media/ipu7/Kconfig +index 7d831ba7501d..561665561b46 100644 +--- a/drivers/staging/media/ipu7/Kconfig ++++ b/drivers/staging/media/ipu7/Kconfig +@@ -4,7 +4,12 @@ config VIDEO_INTEL_IPU7 + depends on VIDEO_DEV + depends on X86 && HAS_DMA + depends on IPU_BRIDGE || !IPU_BRIDGE +- depends on PCI ++ # ++ # This driver incorrectly tries to override the dma_ops. It should ++ # never have done that, but for now keep it working on architectures ++ # that use dma ops ++ # ++ depends on ARCH_HAS_DMA_OPS + select AUXILIARY_BUS + select IOMMU_IOVA + select VIDEO_V4L2_SUBDEV_API +@@ -15,5 +20,5 @@ config VIDEO_INTEL_IPU7 + This is the 7th Gen Intel Image Processing Unit, found in Intel SoCs + and used for capturing images and video from camera sensors. + +- To compile this driver, say Y here! It contains 2 modules - +- intel_ipu7 and intel_ipu7_isys. ++ To compile this driver, say Y here! It contains 3 modules - ++ intel_ipu7, intel_ipu7_isys and intel_ipu7_psys. +diff --git a/drivers/staging/media/ipu7/Makefile b/drivers/staging/media/ipu7/Makefile +index 6d2aec219e65..8c62d730e5f8 100644 +--- a/drivers/staging/media/ipu7/Makefile ++++ b/drivers/staging/media/ipu7/Makefile +@@ -21,3 +21,5 @@ intel-ipu7-isys-objs += ipu7-isys.o \ + ipu7-isys-subdev.o + + obj-$(CONFIG_VIDEO_INTEL_IPU7) += intel-ipu7-isys.o ++ ++obj-$(CONFIG_VIDEO_INTEL_IPU7) += psys/ +-- +2.43.0 + diff --git a/patch/7.0.5/0004-staging-ipu7-Update-IPU7-firmware-ABI-version-to-1.2.patch b/patch/7.0.5/0004-staging-ipu7-Update-IPU7-firmware-ABI-version-to-1.2.patch new file mode 100644 index 0000000..be08420 --- /dev/null +++ b/patch/7.0.5/0004-staging-ipu7-Update-IPU7-firmware-ABI-version-to-1.2.patch @@ -0,0 +1,86 @@ +From 87b28eaee6e463bc40abe782a3fe81b62a57e3c0 Mon Sep 17 00:00:00 2001 +From: linya14x +Date: Fri, 14 Nov 2025 18:41:08 +0800 +Subject: [PATCH 4/7] staging: ipu7: Update IPU7 firmware ABI version to + 1.2.1.20251215_224531 + +Signed-off-by: Hao Yao +--- + drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h | 1 + + drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h | 11 +++++++---- + drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h | 2 +- + 3 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h +index a1519c4fe661..4ce304f54e4b 100644 +--- a/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h ++++ b/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h +@@ -153,6 +153,7 @@ enum ia_gofo_boot_state { + IA_GOFO_FW_BOOT_STATE_CRIT_MPU_CONFIG_FAILURE = 0xdead1013U, + IA_GOFO_FW_BOOT_STATE_CRIT_SHARED_BUFFER_FAILURE = 0xdead1014U, + IA_GOFO_FW_BOOT_STATE_CRIT_CMEM_FAILURE = 0xdead1015U, ++ IA_GOFO_FW_BOOT_STATE_CRIT_SYSCOM_CONTEXT_FAILURE = 0xDEAD1016U, + IA_GOFO_FW_BOOT_STATE_SHUTDOWN_CMD = 0x57a7f001U, + IA_GOFO_FW_BOOT_STATE_SHUTDOWN_START = 0x57a7e200U, + IA_GOFO_FW_BOOT_STATE_INACTIVE = 0x57a7e300U, +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 c42d0b7a2627..7f622bfe9af6 100644 +--- a/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h ++++ b/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h +@@ -47,7 +47,6 @@ enum ipu7_insys_resp_type { + IPU_INSYS_RESP_TYPE_FRAME_EOF = 8, + IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE = 9, + IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_DONE = 10, +- IPU_INSYS_RESP_TYPE_PWM_IRQ = 11, + N_IPU_INSYS_RESP_TYPE + }; + +@@ -201,7 +200,8 @@ enum ipu7_insys_mipi_dt_rename_mode { + enum ipu7_insys_output_link_dest { + IPU_INSYS_OUTPUT_LINK_DEST_MEM = 0, + IPU_INSYS_OUTPUT_LINK_DEST_PSYS = 1, +- IPU_INSYS_OUTPUT_LINK_DEST_IPU_EXTERNAL = 2 ++ IPU_INSYS_OUTPUT_LINK_DEST_IPU_EXTERNAL = 2, ++ N_IPU_INSYS_OUTPUT_LINK_DEST + }; + + enum ipu7_insys_dpcm_type { +@@ -220,9 +220,12 @@ enum ipu7_insys_dpcm_predictor { + + enum ipu7_insys_send_queue_token_flag { + IPU_INSYS_SEND_QUEUE_TOKEN_FLAG_NONE = 0, +- IPU_INSYS_SEND_QUEUE_TOKEN_FLAG_FLUSH_FORCE = 1 ++ IPU_INSYS_SEND_QUEUE_TOKEN_FLAG_FLUSH_FORCE = 1, ++ N_IPU_INSYS_SEND_QUEUE_TOKEN_FLAG + }; + ++#define IPU_INSYS_MIPI_FRAME_NUMBER_DONT_CARE UINT16_MAX ++ + #pragma pack(push, 1) + struct ipu7_insys_resolution { + u32 width; +@@ -312,7 +315,7 @@ struct ipu7_insys_resp { + u8 pin_id; + u8 frame_id; + u8 skip_frame; +- u8 pad[2]; ++ u16 mipi_fn; + }; + + struct ipu7_insys_resp_queue_token { +diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h +index 8a78dd0936df..1319f0eb6319 100644 +--- a/drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h ++++ b/drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h +@@ -217,7 +217,7 @@ struct ipu7_msg_task { + u8 frag_id; + u8 req_done_msg; + u8 req_done_irq; +- u8 reserved[1]; ++ u8 disable_save; + ipu7_msg_teb_t payload_reuse_bm; + ia_gofo_addr_t term_buffers[IPU_MSG_MAX_NODE_TERMS]; + }; +-- +2.43.0 + diff --git a/patch/7.0.5/0005-staging-ipu7-Support-IPU8-PCI-ID.patch b/patch/7.0.5/0005-staging-ipu7-Support-IPU8-PCI-ID.patch new file mode 100644 index 0000000..c4c2d05 --- /dev/null +++ b/patch/7.0.5/0005-staging-ipu7-Support-IPU8-PCI-ID.patch @@ -0,0 +1,25 @@ +From 53ff925f22ce2a546f9cfc71e66434958caaeeda Mon Sep 17 00:00:00 2001 +From: linya14x +Date: Fri, 24 Oct 2025 15:01:40 +0800 +Subject: [PATCH 5/7] staging: ipu7: Support IPU8 PCI ID + +Signed-off-by: Bingbu Cao +--- + drivers/staging/media/ipu7/ipu7.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/staging/media/ipu7/ipu7.c b/drivers/staging/media/ipu7/ipu7.c +index a4b0264cc5c7..630a87b83b4b 100644 +--- a/drivers/staging/media/ipu7/ipu7.c ++++ b/drivers/staging/media/ipu7/ipu7.c +@@ -2807,6 +2807,7 @@ static const struct dev_pm_ops ipu7_pm_ops = { + static const struct pci_device_id ipu7_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU7_PCI_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU7P5_PCI_ID)}, ++ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU8_PCI_ID)}, + {0,} + }; + MODULE_DEVICE_TABLE(pci, ipu7_pci_tbl); +-- +2.43.0 + diff --git a/patch/7.0.5/0006-staging-ipu7-Add-IPU8-ABI-version-1.0.12.patch b/patch/7.0.5/0006-staging-ipu7-Add-IPU8-ABI-version-1.0.12.patch new file mode 100644 index 0000000..9ef4115 --- /dev/null +++ b/patch/7.0.5/0006-staging-ipu7-Add-IPU8-ABI-version-1.0.12.patch @@ -0,0 +1,274 @@ +From 998cf5f5f0e4ea225fe0c452f564c242c2f87c14 Mon Sep 17 00:00:00 2001 +From: linya14x +Date: Fri, 24 Oct 2025 12:09:58 +0800 +Subject: [PATCH 6/7] staging: ipu7: Add IPU8 ABI version 1.0.12 + +IPU8 firmware ABI should be enabled by +-DIPU8_INSYS_NEW_ABI + +Signed-off-by: Hao Yao +--- + .../staging/media/ipu7/abi/ipu7_fw_boot_abi.h | 15 +++-- + .../staging/media/ipu7/abi/ipu7_fw_isys_abi.h | 60 +++++++++++++++++++ + drivers/staging/media/ipu7/ipu7-fw-isys.c | 29 +++++++++ + drivers/staging/media/ipu7/ipu7-isys-queue.c | 6 ++ + drivers/staging/media/ipu7/ipu7-isys-video.c | 17 ++++++ + 5 files changed, 122 insertions(+), 5 deletions(-) + +diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h +index 4ce304f54e4b..539192cdd0e7 100644 +--- a/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h ++++ b/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h +@@ -113,14 +113,19 @@ struct ia_gofo_secondary_boot_config { + #define IA_GOFO_DOUBLE_EXCEPTION_ERR 0xdead0806U + #define IA_GOFO_BIST_DMEM_FAULT_DETECTION_ERR 0xdead1000U + #define IA_GOFO_BIST_DATA_INTEGRITY_FAILURE 0xdead1010U ++#define IA_GOFO_BOOT_STATE_UNINIT 0x57a7e000U ++#define IA_GOFO_BOOT_STATE_STARTING_0 0x57a7d000U ++#define IA_GOFO_BOOT_STATE_CACHE_INIT_DONE 0x57a7d010U ++#define IA_GOFO_BOOT_STATE_MEM_INIT_DONE 0x57a7d020U ++#define IA_GOFO_BOOT_STATE_STACK_INIT_DONE 0x57a7d030U + + enum ia_gofo_boot_state { + IA_GOFO_FW_BOOT_STATE_SECONDARY_BOOT_CONFIG_READY = 0x57a7b000U, +- IA_GOFO_FW_BOOT_STATE_UNINIT = 0x57a7e000U, +- IA_GOFO_FW_BOOT_STATE_STARTING_0 = 0x57a7d000U, +- IA_GOFO_FW_BOOT_STATE_CACHE_INIT_DONE = 0x57a7d010U, +- IA_GOFO_FW_BOOT_STATE_MEM_INIT_DONE = 0x57a7d020U, +- IA_GOFO_FW_BOOT_STATE_STACK_INIT_DONE = 0x57a7d030U, ++ IA_GOFO_FW_BOOT_STATE_UNINIT = IA_GOFO_BOOT_STATE_UNINIT, ++ IA_GOFO_FW_BOOT_STATE_STARTING_0 = IA_GOFO_BOOT_STATE_STARTING_0, ++ IA_GOFO_FW_BOOT_STATE_CACHE_INIT_DONE = IA_GOFO_BOOT_STATE_CACHE_INIT_DONE, ++ IA_GOFO_FW_BOOT_STATE_MEM_INIT_DONE = IA_GOFO_BOOT_STATE_MEM_INIT_DONE, ++ IA_GOFO_FW_BOOT_STATE_STACK_INIT_DONE = IA_GOFO_BOOT_STATE_STACK_INIT_DONE, + IA_GOFO_FW_BOOT_STATE_EARLY_BOOT_DONE = 0x57a7d100U, + IA_GOFO_FW_BOOT_STATE_BOOT_CONFIG_START = 0x57a7d200U, + IA_GOFO_FW_BOOT_STATE_QUEUE_INIT_DONE = 0x57a7d300U, +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 7f622bfe9af6..f32674f081d2 100644 +--- a/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h ++++ b/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h +@@ -254,6 +254,10 @@ struct ipu7_insys_output_link { + 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 { +@@ -263,16 +267,55 @@ 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, ++ N_IPU_INSYS_CFA_DIM ++}; ++ ++#define IPU_INSYS_MAX_BINNING_FACTOR (4U) ++#define IPU_INSYS_UPIPE_MAX_OUTPUTS (2U) ++#define IPU_INSYS_UPIPE_MAX_UOB_FIFO_ALLOC (4U) ++#define IPU_INSYS_UPIPE_STREAM_CFG_BUF_SIZE (32U) ++#define IPU_INSYS_UPIPE_FRAME_CFG_BUF_SIZE (36U) ++ ++struct ipu7_insys_upipe_output_pin { ++ ia_gofo_addr_t opaque_pin_cfg; ++ u16 plane_offset_1; ++ u16 plane_offset_2; ++ u8 single_uob_fifo; ++ u8 shared_uob_fifo; ++ u8 pad[2]; ++}; ++ ++struct ipu7_insys_capture_output_pin_cfg { ++ struct ipu7_insys_capture_output_pin_payload pin_payload; ++ ia_gofo_addr_t upipe_capture_cfg; ++}; ++ ++#endif + 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 { +@@ -297,7 +340,11 @@ struct ipu7_insys_stream_cfg { + }; + + 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; +@@ -309,13 +356,18 @@ struct ipu7_insys_resp { + struct ipu7_insys_capture_output_pin_payload pin; + struct ia_gofo_msg_err error_info; + u32 timestamp[2]; ++#ifdef IPU8_INSYS_NEW_ABI ++ u16 mipi_fn; ++#endif + 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 { +@@ -372,6 +424,14 @@ 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 e4b9c364572b..c98326bd9fee 100644 +--- a/drivers/staging/media/ipu7/ipu7-fw-isys.c ++++ b/drivers/staging/media/ipu7/ipu7-fw-isys.c +@@ -268,6 +268,12 @@ 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", ++ cfg->output_pins[i].crop.column_right); ++#endif + + dev_dbg(dev, "\t.dpcm_enable = %d\n", + cfg->output_pins[i].dpcm.enable); +@@ -275,6 +281,20 @@ void ipu7_fw_isys_dump_stream_cfg(struct device *dev, + 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", ++ cfg->output_pins[i].upipe_pin_cfg.opaque_pin_cfg); ++ dev_dbg(dev, "\t.upipe_pin_cfg.plane_offset_1 = %d\n", ++ cfg->output_pins[i].upipe_pin_cfg.plane_offset_1); ++ dev_dbg(dev, "\t.upipe_pin_cfg.plane_offset_2 = %d\n", ++ cfg->output_pins[i].upipe_pin_cfg.plane_offset_2); ++ dev_dbg(dev, "\t.upipe_pin_cfg.singel_uob_fifo = %d\n", ++ 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"); + } +@@ -293,9 +313,18 @@ 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 434d9d9c7158..eed46243df43 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys-queue.c ++++ b/drivers/staging/media/ipu7/ipu7-isys-queue.c +@@ -248,8 +248,14 @@ static void ipu7_isys_buf_to_fw_frame_buf_pin(struct vb2_buffer *vb, + struct ipu7_isys_video_buffer *ivb = + vb2_buffer_to_ipu7_isys_video_buffer(vvb); + ++#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 + } + + /* +diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.c b/drivers/staging/media/ipu7/ipu7-isys-video.c +index 1a7c8a91fffb..09a60170357f 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys-video.c ++++ b/drivers/staging/media/ipu7/ipu7-isys-video.c +@@ -418,10 +418,27 @@ 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 + + /* 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 ++ + /* frame format type */ + pfmt = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); + output_pin->ft = (u16)pfmt->css_pixelformat; +-- +2.43.0 + diff --git a/patch/7.0.5/0007-staging-ipu7-Define-gpreg_stride-for-different-IPU-v.patch b/patch/7.0.5/0007-staging-ipu7-Define-gpreg_stride-for-different-IPU-v.patch new file mode 100644 index 0000000..58338ed --- /dev/null +++ b/patch/7.0.5/0007-staging-ipu7-Define-gpreg_stride-for-different-IPU-v.patch @@ -0,0 +1,80 @@ +From c69967239b91104e8e53b1a1bf930ff8303c4af0 Mon Sep 17 00:00:00 2001 +From: Hao Yao +Date: Mon, 26 Jan 2026 18:10:20 +0800 +Subject: [PATCH 7/7] staging: ipu7: Define gpreg_stride for different IPU + versions + +Signed-off-by: Hao Yao +--- + drivers/staging/media/ipu7/ipu7-isys-csi-phy.c | 6 ++++-- + drivers/staging/media/ipu7/ipu7.c | 3 +++ + drivers/staging/media/ipu7/ipu7.h | 1 + + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c +index b8c5db7ae300..bd83aef7067e 100644 +--- a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c ++++ b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c +@@ -167,7 +167,8 @@ static void gpreg_write(struct ipu7_isys *isys, u32 id, u32 addr, u32 data) + { + void __iomem *isys_base = isys->pdata->base; + u32 gpreg = isys->pdata->ipdata->csi2.gpreg; +- void __iomem *base = isys_base + gpreg + 0x1000 * id; ++ void __iomem *base = isys_base + gpreg + ++ isys->pdata->ipdata->csi2.gpreg_stride * id; + struct device *dev = &isys->adev->auxdev.dev; + + dev_dbg(dev, "gpreg write: reg 0x%zx = data 0x%08x", +@@ -344,7 +345,8 @@ static int ipu7_isys_phy_ready(struct ipu7_isys *isys, u32 id) + { + void __iomem *isys_base = isys->pdata->base; + u32 gpreg_offset = isys->pdata->ipdata->csi2.gpreg; +- void __iomem *gpreg = isys_base + gpreg_offset + 0x1000 * id; ++ void __iomem *gpreg = isys_base + gpreg_offset + ++ isys->pdata->ipdata->csi2.gpreg_stride * id; + struct device *dev = &isys->adev->auxdev.dev; + unsigned int i; + u32 phy_ready; +diff --git a/drivers/staging/media/ipu7/ipu7.c b/drivers/staging/media/ipu7/ipu7.c +index 630a87b83b4b..db7e452cff04 100644 +--- a/drivers/staging/media/ipu7/ipu7.c ++++ b/drivers/staging/media/ipu7/ipu7.c +@@ -52,6 +52,7 @@ static const unsigned int ipu7_csi_offsets[] = { + static struct ipu_isys_internal_pdata ipu7p5_isys_ipdata = { + .csi2 = { + .gpreg = IS_IO_CSI2_GPREGS_BASE, ++ .gpreg_stride = 0x1000, + }, + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, +@@ -792,6 +793,7 @@ static struct ipu_psys_internal_pdata ipu7p5_psys_ipdata = { + static struct ipu_isys_internal_pdata ipu7_isys_ipdata = { + .csi2 = { + .gpreg = IS_IO_CSI2_GPREGS_BASE, ++ .gpreg_stride = 0x1000, + }, + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, +@@ -1309,6 +1311,7 @@ static struct ipu_psys_internal_pdata ipu7_psys_ipdata = { + static struct ipu_isys_internal_pdata ipu8_isys_ipdata = { + .csi2 = { + .gpreg = IPU8_IS_IO_CSI2_GPREGS_BASE, ++ .gpreg_stride = 0x2000, + }, + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, +diff --git a/drivers/staging/media/ipu7/ipu7.h b/drivers/staging/media/ipu7/ipu7.h +index 3b3ea5fb613f..95ccec4de424 100644 +--- a/drivers/staging/media/ipu7/ipu7.h ++++ b/drivers/staging/media/ipu7/ipu7.h +@@ -204,6 +204,7 @@ struct ipu7_isys_internal_csi2_pdata { + u32 nports; + u32 const *offsets; + u32 gpreg; ++ u32 gpreg_stride; + }; + + struct ipu7_hw_variants { +-- +2.43.0 +