camif-core.h (10910B)
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * s3c24xx/s3c64xx SoC series Camera Interface (CAMIF) driver 4 * 5 * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com> 6 * Copyright (C) 2012 Tomasz Figa <tomasz.figa@gmail.com> 7*/ 8 9#ifndef CAMIF_CORE_H_ 10#define CAMIF_CORE_H_ 11 12#include <linux/io.h> 13#include <linux/irq.h> 14#include <linux/platform_device.h> 15#include <linux/sched.h> 16#include <linux/spinlock.h> 17#include <linux/types.h> 18#include <linux/videodev2.h> 19 20#include <media/media-entity.h> 21#include <media/v4l2-ctrls.h> 22#include <media/v4l2-dev.h> 23#include <media/v4l2-device.h> 24#include <media/v4l2-mediabus.h> 25#include <media/videobuf2-v4l2.h> 26#include <media/drv-intf/s3c_camif.h> 27 28#define S3C_CAMIF_DRIVER_NAME "s3c-camif" 29#define CAMIF_REQ_BUFS_MIN 3 30#define CAMIF_MAX_OUT_BUFS 4 31#define CAMIF_MAX_PIX_WIDTH 4096 32#define CAMIF_MAX_PIX_HEIGHT 4096 33#define SCALER_MAX_RATIO 64 34#define CAMIF_DEF_WIDTH 640 35#define CAMIF_DEF_HEIGHT 480 36#define CAMIF_STOP_TIMEOUT 1500 /* ms */ 37 38#define S3C244X_CAMIF_IP_REV 0x20 /* 2.0 */ 39#define S3C2450_CAMIF_IP_REV 0x30 /* 3.0 - not implemented, not tested */ 40#define S3C6400_CAMIF_IP_REV 0x31 /* 3.1 - not implemented, not tested */ 41#define S3C6410_CAMIF_IP_REV 0x32 /* 3.2 */ 42 43/* struct camif_vp::state */ 44 45#define ST_VP_PENDING (1 << 0) 46#define ST_VP_RUNNING (1 << 1) 47#define ST_VP_STREAMING (1 << 2) 48#define ST_VP_SENSOR_STREAMING (1 << 3) 49 50#define ST_VP_ABORTING (1 << 4) 51#define ST_VP_OFF (1 << 5) 52#define ST_VP_LASTIRQ (1 << 6) 53 54#define ST_VP_CONFIG (1 << 8) 55 56#define CAMIF_SD_PAD_SINK 0 57#define CAMIF_SD_PAD_SOURCE_C 1 58#define CAMIF_SD_PAD_SOURCE_P 2 59#define CAMIF_SD_PADS_NUM 3 60 61enum img_fmt { 62 IMG_FMT_RGB565 = 0x0010, 63 IMG_FMT_RGB666, 64 IMG_FMT_XRGB8888, 65 IMG_FMT_YCBCR420 = 0x0020, 66 IMG_FMT_YCRCB420, 67 IMG_FMT_YCBCR422P, 68 IMG_FMT_YCBYCR422 = 0x0040, 69 IMG_FMT_YCRYCB422, 70 IMG_FMT_CBYCRY422, 71 IMG_FMT_CRYCBY422, 72}; 73 74#define img_fmt_is_rgb(x) ((x) & 0x10) 75#define img_fmt_is_ycbcr(x) ((x) & 0x60) 76 77/* Possible values for struct camif_fmt::flags */ 78#define FMT_FL_S3C24XX_CODEC (1 << 0) 79#define FMT_FL_S3C24XX_PREVIEW (1 << 1) 80#define FMT_FL_S3C64XX (1 << 2) 81 82/** 83 * struct camif_fmt - pixel format description 84 * @fourcc: fourcc code for this format, 0 if not applicable 85 * @color: a corresponding enum img_fmt 86 * @colplanes: number of physically contiguous data planes 87 * @flags: indicate for which SoCs revisions this format is valid 88 * @depth: bits per pixel (total) 89 * @ybpp: number of luminance bytes per pixel 90 */ 91struct camif_fmt { 92 u32 fourcc; 93 u32 color; 94 u16 colplanes; 95 u16 flags; 96 u8 depth; 97 u8 ybpp; 98}; 99 100/** 101 * struct camif_dma_offset - pixel offset information for DMA 102 * @initial: offset (in pixels) to first pixel 103 * @line: offset (in pixels) from end of line to start of next line 104 */ 105struct camif_dma_offset { 106 int initial; 107 int line; 108}; 109 110/** 111 * struct camif_frame - source/target frame properties 112 * @f_width: full pixel width 113 * @f_height: full pixel height 114 * @rect: crop/composition rectangle 115 * @dma_offset: DMA offset configuration 116 */ 117struct camif_frame { 118 u16 f_width; 119 u16 f_height; 120 struct v4l2_rect rect; 121 struct camif_dma_offset dma_offset; 122}; 123 124/* CAMIF clocks enumeration */ 125enum { 126 CLK_GATE, 127 CLK_CAM, 128 CLK_MAX_NUM, 129}; 130 131struct vp_pix_limits { 132 u16 max_out_width; 133 u16 max_sc_out_width; 134 u16 out_width_align; 135 u16 max_height; 136 u8 min_out_width; 137 u16 out_hor_offset_align; 138}; 139 140struct camif_pix_limits { 141 u16 win_hor_offset_align; 142}; 143 144/** 145 * struct s3c_camif_variant - CAMIF variant structure 146 * @vp_pix_limits: pixel limits for the codec and preview paths 147 * @pix_limits: pixel limits for the camera input interface 148 * @ip_revision: the CAMIF IP revision: 0x20 for s3c244x, 0x32 for s3c6410 149 * @has_img_effect: supports image effects 150 * @vp_offset: register offset 151 */ 152struct s3c_camif_variant { 153 struct vp_pix_limits vp_pix_limits[2]; 154 struct camif_pix_limits pix_limits; 155 u8 ip_revision; 156 u8 has_img_effect; 157 unsigned int vp_offset; 158}; 159 160struct s3c_camif_drvdata { 161 const struct s3c_camif_variant *variant; 162 unsigned long bus_clk_freq; 163}; 164 165struct camif_scaler { 166 u8 scaleup_h; 167 u8 scaleup_v; 168 u8 copy; 169 u8 enable; 170 u32 h_shift; 171 u32 v_shift; 172 u32 pre_h_ratio; 173 u32 pre_v_ratio; 174 u32 pre_dst_width; 175 u32 pre_dst_height; 176 u32 main_h_ratio; 177 u32 main_v_ratio; 178}; 179 180struct camif_dev; 181 182/** 183 * struct camif_vp - CAMIF data processing path structure (codec/preview) 184 * @irq_queue: interrupt handling waitqueue 185 * @irq: interrupt number for this data path 186 * @camif: pointer to the camif structure 187 * @pad: media pad for the video node 188 * @vdev: video device 189 * @ctrl_handler: video node controls handler 190 * @owner: file handle that own the streaming 191 * @vb_queue: vb2 buffer queue 192 * @pending_buf_q: pending (empty) buffers queue head 193 * @active_buf_q: active (being written) buffers queue head 194 * @active_buffers: counter of buffer set up at the DMA engine 195 * @buf_index: identifier of a last empty buffer set up in H/W 196 * @frame_sequence: image frame sequence counter 197 * @reqbufs_count: the number of buffers requested 198 * @scaler: the scaler structure 199 * @out_fmt: pixel format at this video path output 200 * @payload: the output data frame payload size 201 * @out_frame: the output pixel resolution 202 * @state: the video path's state 203 * @fmt_flags: flags determining supported pixel formats 204 * @id: CAMIF id, 0 - codec, 1 - preview 205 * @rotation: current image rotation value 206 * @hflip: apply horizontal flip if set 207 * @vflip: apply vertical flip if set 208 * @offset: register offset 209 */ 210struct camif_vp { 211 wait_queue_head_t irq_queue; 212 int irq; 213 struct camif_dev *camif; 214 struct media_pad pad; 215 struct video_device vdev; 216 struct v4l2_ctrl_handler ctrl_handler; 217 struct v4l2_fh *owner; 218 struct vb2_queue vb_queue; 219 struct list_head pending_buf_q; 220 struct list_head active_buf_q; 221 unsigned int active_buffers; 222 unsigned int buf_index; 223 unsigned int frame_sequence; 224 unsigned int reqbufs_count; 225 struct camif_scaler scaler; 226 const struct camif_fmt *out_fmt; 227 unsigned int payload; 228 struct camif_frame out_frame; 229 unsigned int state; 230 u16 fmt_flags; 231 u8 id; 232 u16 rotation; 233 u8 hflip; 234 u8 vflip; 235 unsigned int offset; 236}; 237 238/* Video processing path enumeration */ 239#define VP_CODEC 0 240#define VP_PREVIEW 1 241#define CAMIF_VP_NUM 2 242 243/** 244 * struct camif_dev - the CAMIF driver private data structure 245 * @media_dev: top-level media device structure 246 * @v4l2_dev: root v4l2_device 247 * @subdev: camera interface ("catchcam") subdev 248 * @mbus_fmt: camera input media bus format 249 * @camif_crop: camera input interface crop rectangle 250 * @pads: the camif subdev's media pads 251 * @stream_count: the camera interface streaming reference counter 252 * @sensor: image sensor data structure 253 * @m_pipeline: video entity pipeline description 254 * @ctrl_handler: v4l2 control handler (owned by @subdev) 255 * @ctrl_test_pattern: V4L2_CID_TEST_PATTERN control 256 * @ctrl_colorfx: V4L2_CID_COLORFX control 257 * @ctrl_colorfx_cbcr: V4L2_CID_COLORFX_CBCR control 258 * @test_pattern: test pattern 259 * @colorfx: color effect 260 * @colorfx_cb: Cb value for V4L2_COLORFX_SET_CBCR 261 * @colorfx_cr: Cr value for V4L2_COLORFX_SET_CBCR 262 * @vp: video path (DMA) description (codec/preview) 263 * @variant: variant information for this device 264 * @dev: pointer to the CAMIF device struct 265 * @pdata: a copy of the driver's platform data 266 * @clock: clocks required for the CAMIF operation 267 * @lock: mutex protecting this data structure 268 * @slock: spinlock protecting CAMIF registers 269 * @io_base: start address of the mmapped CAMIF registers 270 */ 271struct camif_dev { 272 struct media_device media_dev; 273 struct v4l2_device v4l2_dev; 274 struct v4l2_subdev subdev; 275 struct v4l2_mbus_framefmt mbus_fmt; 276 struct v4l2_rect camif_crop; 277 struct media_pad pads[CAMIF_SD_PADS_NUM]; 278 int stream_count; 279 280 struct cam_sensor { 281 struct v4l2_subdev *sd; 282 short power_count; 283 short stream_count; 284 } sensor; 285 struct media_pipeline *m_pipeline; 286 287 struct v4l2_ctrl_handler ctrl_handler; 288 struct v4l2_ctrl *ctrl_test_pattern; 289 struct { 290 struct v4l2_ctrl *ctrl_colorfx; 291 struct v4l2_ctrl *ctrl_colorfx_cbcr; 292 }; 293 u8 test_pattern; 294 u8 colorfx; 295 u8 colorfx_cb; 296 u8 colorfx_cr; 297 298 struct camif_vp vp[CAMIF_VP_NUM]; 299 300 const struct s3c_camif_variant *variant; 301 struct device *dev; 302 struct s3c_camif_plat_data pdata; 303 struct clk *clock[CLK_MAX_NUM]; 304 struct mutex lock; 305 spinlock_t slock; 306 void __iomem *io_base; 307}; 308 309/** 310 * struct camif_addr - Y/Cb/Cr DMA start address structure 311 * @y: luminance plane dma address 312 * @cb: Cb plane dma address 313 * @cr: Cr plane dma address 314 */ 315struct camif_addr { 316 dma_addr_t y; 317 dma_addr_t cb; 318 dma_addr_t cr; 319}; 320 321/** 322 * struct camif_buffer - the camif video buffer structure 323 * @vb: vb2 buffer 324 * @list: list head for the buffers queue 325 * @paddr: DMA start addresses 326 * @index: an identifier of this buffer at the DMA engine 327 */ 328struct camif_buffer { 329 struct vb2_v4l2_buffer vb; 330 struct list_head list; 331 struct camif_addr paddr; 332 unsigned int index; 333}; 334 335const struct camif_fmt *s3c_camif_find_format(struct camif_vp *vp, 336 const u32 *pixelformat, int index); 337int s3c_camif_register_video_node(struct camif_dev *camif, int idx); 338void s3c_camif_unregister_video_node(struct camif_dev *camif, int idx); 339irqreturn_t s3c_camif_irq_handler(int irq, void *priv); 340int s3c_camif_create_subdev(struct camif_dev *camif); 341void s3c_camif_unregister_subdev(struct camif_dev *camif); 342int s3c_camif_set_defaults(struct camif_dev *camif); 343int s3c_camif_get_scaler_config(struct camif_vp *vp, 344 struct camif_scaler *scaler); 345 346static inline void camif_active_queue_add(struct camif_vp *vp, 347 struct camif_buffer *buf) 348{ 349 list_add_tail(&buf->list, &vp->active_buf_q); 350 vp->active_buffers++; 351} 352 353static inline struct camif_buffer *camif_active_queue_pop( 354 struct camif_vp *vp) 355{ 356 struct camif_buffer *buf = list_first_entry(&vp->active_buf_q, 357 struct camif_buffer, list); 358 list_del(&buf->list); 359 vp->active_buffers--; 360 return buf; 361} 362 363static inline struct camif_buffer *camif_active_queue_peek( 364 struct camif_vp *vp, int index) 365{ 366 struct camif_buffer *tmp, *buf; 367 368 if (WARN_ON(list_empty(&vp->active_buf_q))) 369 return NULL; 370 371 list_for_each_entry_safe(buf, tmp, &vp->active_buf_q, list) { 372 if (buf->index == index) { 373 list_del(&buf->list); 374 vp->active_buffers--; 375 return buf; 376 } 377 } 378 379 return NULL; 380} 381 382static inline void camif_pending_queue_add(struct camif_vp *vp, 383 struct camif_buffer *buf) 384{ 385 list_add_tail(&buf->list, &vp->pending_buf_q); 386} 387 388static inline struct camif_buffer *camif_pending_queue_pop( 389 struct camif_vp *vp) 390{ 391 struct camif_buffer *buf = list_first_entry(&vp->pending_buf_q, 392 struct camif_buffer, list); 393 list_del(&buf->list); 394 return buf; 395} 396 397#endif /* CAMIF_CORE_H_ */