Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2018 Intel Corporation */ #ifndef __IPU3_H #define __IPU3_H #include <linux/iova.h> #include <linux/pci.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/videobuf2-dma-sg.h> #include "ipu3-css.h" #define IMGU_NAME "ipu3-imgu" /* * The semantics of the driver is that whenever there is a buffer available in * master queue, the driver queues a buffer also to all other active nodes. * If user space hasn't provided a buffer to all other video nodes first, * the driver gets an internal dummy buffer and queues it. */ #define IMGU_QUEUE_MASTER IPU3_CSS_QUEUE_IN #define IMGU_QUEUE_FIRST_INPUT IPU3_CSS_QUEUE_OUT #define IMGU_MAX_QUEUE_DEPTH (2 + 2) #define IMGU_NODE_IN 0 /* Input RAW image */ #define IMGU_NODE_PARAMS 1 /* Input parameters */ #define IMGU_NODE_OUT 2 /* Main output for still or video */ #define IMGU_NODE_VF 3 /* Preview */ #define IMGU_NODE_STAT_3A 4 /* 3A statistics */ #define IMGU_NODE_NUM 5 #define file_to_intel_imgu_node(__file) \ container_of(video_devdata(__file), struct imgu_video_device, vdev) #define IPU3_INPUT_MIN_WIDTH 0U #define IPU3_INPUT_MIN_HEIGHT 0U #define IPU3_INPUT_MAX_WIDTH 5120U #define IPU3_INPUT_MAX_HEIGHT 38404U #define IPU3_OUTPUT_MIN_WIDTH 2U #define IPU3_OUTPUT_MIN_HEIGHT 2U #define IPU3_OUTPUT_MAX_WIDTH 4480U #define IPU3_OUTPUT_MAX_HEIGHT 34004U struct imgu_vb2_buffer { /* Public fields */ struct vb2_v4l2_buffer vbb; /* Must be the first field */ /* Private fields */ struct list_head list; }; struct imgu_buffer { struct imgu_vb2_buffer vid_buf; /* Must be the first field */ struct imgu_css_buffer css_buf; struct imgu_css_map map; }; struct imgu_node_mapping { unsigned int css_queue; const char *name; }; struct imgu_video_device { const char *name; bool output; bool enabled; struct v4l2_format vdev_fmt; /* Currently set format */ /* Private fields */ struct video_device vdev; struct media_pad vdev_pad; struct v4l2_mbus_framefmt pad_fmt; struct vb2_queue vbq; struct list_head buffers; /* Protect vb2_queue and vdev structs*/ struct mutex lock; atomic_t sequence; unsigned int id; unsigned int pipe; }; struct imgu_v4l2_subdev { unsigned int pipe; struct v4l2_subdev subdev; struct media_pad subdev_pads[IMGU_NODE_NUM]; struct { struct v4l2_rect eff; /* effective resolution */ struct v4l2_rect bds; /* bayer-domain scaled resolution*/ struct v4l2_rect gdc; /* gdc output resolution */ } rect; struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl *ctrl; atomic_t running_mode; bool active; }; struct imgu_media_pipe { unsigned int pipe; /* Internally enabled queues */ struct { struct imgu_css_map dmap; struct imgu_css_buffer dummybufs[IMGU_MAX_QUEUE_DEPTH]; } queues[IPU3_CSS_QUEUES]; struct imgu_video_device nodes[IMGU_NODE_NUM]; bool queue_enabled[IMGU_NODE_NUM]; struct media_pipeline pipeline; struct imgu_v4l2_subdev imgu_sd; }; /* * imgu_device -- ImgU (Imaging Unit) driver */ struct imgu_device { struct pci_dev *pci_dev; void __iomem *base; /* Public fields, fill before registering */ unsigned int buf_struct_size; bool streaming; /* Public read only */ struct imgu_media_pipe imgu_pipe[IMGU_MAX_PIPE_NUM]; /* Private fields */ struct v4l2_device v4l2_dev; struct media_device media_dev; struct v4l2_file_operations v4l2_file_ops; /* MMU driver for css */ struct imgu_mmu_info *mmu; struct iova_domain iova_domain; /* css - Camera Sub-System */ struct imgu_css css; /* * Coarse-grained lock to protect * vid_buf.list and css->queue */ struct mutex lock; /* Lock to protect writes to streaming flag in this struct */ struct mutex streaming_lock; /* Forbid streaming and buffer queuing during system suspend. */ atomic_t qbuf_barrier; /* Indicate if system suspend take place while imgu is streaming. */ bool suspend_in_stream; /* Used to wait for FW buffer queue drain. */ wait_queue_head_t buf_drain_wq; }; unsigned int imgu_node_to_queue(unsigned int node); unsigned int imgu_map_node(struct imgu_device *imgu, unsigned int css_queue); int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe); int imgu_v4l2_register(struct imgu_device *dev); int imgu_v4l2_unregister(struct imgu_device *dev); void imgu_v4l2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); int imgu_s_stream(struct imgu_device *imgu, int enable); static inline u32 imgu_bytesperline(const unsigned int width, enum imgu_abi_frame_format frame_format) { if (frame_format == IMGU_ABI_FRAME_FORMAT_NV12) return ALIGN(width, IPU3_UAPI_ISP_VEC_ELEMS); /* * 64 bytes for every 50 pixels, the line length * in bytes is multiple of 64 (line end alignment). */ return DIV_ROUND_UP(width, 50) * 64; } #endif |