162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ispvideo.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * TI OMAP3 ISP - Generic video node 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2009-2010 Nokia Corporation 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 1062306a36Sopenharmony_ci * Sakari Ailus <sakari.ailus@iki.fi> 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#ifndef OMAP3_ISP_VIDEO_H 1462306a36Sopenharmony_ci#define OMAP3_ISP_VIDEO_H 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/v4l2-mediabus.h> 1762306a36Sopenharmony_ci#include <media/media-entity.h> 1862306a36Sopenharmony_ci#include <media/v4l2-dev.h> 1962306a36Sopenharmony_ci#include <media/v4l2-fh.h> 2062306a36Sopenharmony_ci#include <media/videobuf2-v4l2.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define ISP_VIDEO_DRIVER_NAME "ispvideo" 2362306a36Sopenharmony_ci#define ISP_VIDEO_DRIVER_VERSION "0.0.2" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistruct isp_device; 2662306a36Sopenharmony_cistruct isp_video; 2762306a36Sopenharmony_cistruct v4l2_mbus_framefmt; 2862306a36Sopenharmony_cistruct v4l2_pix_format; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * struct isp_format_info - ISP media bus format information 3262306a36Sopenharmony_ci * @code: V4L2 media bus format code 3362306a36Sopenharmony_ci * @truncated: V4L2 media bus format code for the same format truncated to 10 3462306a36Sopenharmony_ci * bits. Identical to @code if the format is 10 bits wide or less. 3562306a36Sopenharmony_ci * @uncompressed: V4L2 media bus format code for the corresponding uncompressed 3662306a36Sopenharmony_ci * format. Identical to @code if the format is not DPCM compressed. 3762306a36Sopenharmony_ci * @flavor: V4L2 media bus format code for the same pixel layout but 3862306a36Sopenharmony_ci * shifted to be 8 bits per pixel. =0 if format is not shiftable. 3962306a36Sopenharmony_ci * @pixelformat: V4L2 pixel format FCC identifier 4062306a36Sopenharmony_ci * @width: Bits per pixel (when transferred over a bus) 4162306a36Sopenharmony_ci * @bpp: Bytes per pixel (when stored in memory) 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_cistruct isp_format_info { 4462306a36Sopenharmony_ci u32 code; 4562306a36Sopenharmony_ci u32 truncated; 4662306a36Sopenharmony_ci u32 uncompressed; 4762306a36Sopenharmony_ci u32 flavor; 4862306a36Sopenharmony_ci u32 pixelformat; 4962306a36Sopenharmony_ci unsigned int width; 5062306a36Sopenharmony_ci unsigned int bpp; 5162306a36Sopenharmony_ci}; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cienum isp_pipeline_stream_state { 5462306a36Sopenharmony_ci ISP_PIPELINE_STREAM_STOPPED = 0, 5562306a36Sopenharmony_ci ISP_PIPELINE_STREAM_CONTINUOUS = 1, 5662306a36Sopenharmony_ci ISP_PIPELINE_STREAM_SINGLESHOT = 2, 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cienum isp_pipeline_state { 6062306a36Sopenharmony_ci /* The stream has been started on the input video node. */ 6162306a36Sopenharmony_ci ISP_PIPELINE_STREAM_INPUT = 1, 6262306a36Sopenharmony_ci /* The stream has been started on the output video node. */ 6362306a36Sopenharmony_ci ISP_PIPELINE_STREAM_OUTPUT = 2, 6462306a36Sopenharmony_ci /* At least one buffer is queued on the input video node. */ 6562306a36Sopenharmony_ci ISP_PIPELINE_QUEUE_INPUT = 4, 6662306a36Sopenharmony_ci /* At least one buffer is queued on the output video node. */ 6762306a36Sopenharmony_ci ISP_PIPELINE_QUEUE_OUTPUT = 8, 6862306a36Sopenharmony_ci /* The input entity is idle, ready to be started. */ 6962306a36Sopenharmony_ci ISP_PIPELINE_IDLE_INPUT = 16, 7062306a36Sopenharmony_ci /* The output entity is idle, ready to be started. */ 7162306a36Sopenharmony_ci ISP_PIPELINE_IDLE_OUTPUT = 32, 7262306a36Sopenharmony_ci /* The pipeline is currently streaming. */ 7362306a36Sopenharmony_ci ISP_PIPELINE_STREAM = 64, 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* 7762306a36Sopenharmony_ci * struct isp_pipeline - An ISP hardware pipeline 7862306a36Sopenharmony_ci * @field: The field being processed by the pipeline 7962306a36Sopenharmony_ci * @error: A hardware error occurred during capture 8062306a36Sopenharmony_ci * @ent_enum: Entities in the pipeline 8162306a36Sopenharmony_ci */ 8262306a36Sopenharmony_cistruct isp_pipeline { 8362306a36Sopenharmony_ci struct media_pipeline pipe; 8462306a36Sopenharmony_ci spinlock_t lock; /* Pipeline state and queue flags */ 8562306a36Sopenharmony_ci unsigned int state; 8662306a36Sopenharmony_ci enum isp_pipeline_stream_state stream_state; 8762306a36Sopenharmony_ci struct isp_video *input; 8862306a36Sopenharmony_ci struct isp_video *output; 8962306a36Sopenharmony_ci struct media_entity_enum ent_enum; 9062306a36Sopenharmony_ci unsigned long l3_ick; 9162306a36Sopenharmony_ci unsigned int max_rate; 9262306a36Sopenharmony_ci enum v4l2_field field; 9362306a36Sopenharmony_ci atomic_t frame_number; 9462306a36Sopenharmony_ci bool do_propagation; /* of frame number */ 9562306a36Sopenharmony_ci bool error; 9662306a36Sopenharmony_ci struct v4l2_fract max_timeperframe; 9762306a36Sopenharmony_ci struct v4l2_subdev *external; 9862306a36Sopenharmony_ci unsigned int external_rate; 9962306a36Sopenharmony_ci unsigned int external_width; 10062306a36Sopenharmony_ci}; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic inline struct isp_pipeline *to_isp_pipeline(struct media_entity *entity) 10362306a36Sopenharmony_ci{ 10462306a36Sopenharmony_ci struct media_pipeline *pipe = media_entity_pipeline(entity); 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci if (!pipe) 10762306a36Sopenharmony_ci return NULL; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci return container_of(pipe, struct isp_pipeline, pipe); 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic inline int isp_pipeline_ready(struct isp_pipeline *pipe) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci return pipe->state == (ISP_PIPELINE_STREAM_INPUT | 11562306a36Sopenharmony_ci ISP_PIPELINE_STREAM_OUTPUT | 11662306a36Sopenharmony_ci ISP_PIPELINE_QUEUE_INPUT | 11762306a36Sopenharmony_ci ISP_PIPELINE_QUEUE_OUTPUT | 11862306a36Sopenharmony_ci ISP_PIPELINE_IDLE_INPUT | 11962306a36Sopenharmony_ci ISP_PIPELINE_IDLE_OUTPUT); 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci/** 12362306a36Sopenharmony_ci * struct isp_buffer - ISP video buffer 12462306a36Sopenharmony_ci * @vb: videobuf2 buffer 12562306a36Sopenharmony_ci * @irqlist: List head for insertion into IRQ queue 12662306a36Sopenharmony_ci * @dma: DMA address 12762306a36Sopenharmony_ci */ 12862306a36Sopenharmony_cistruct isp_buffer { 12962306a36Sopenharmony_ci struct vb2_v4l2_buffer vb; 13062306a36Sopenharmony_ci struct list_head irqlist; 13162306a36Sopenharmony_ci dma_addr_t dma; 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci#define to_isp_buffer(buf) container_of(buf, struct isp_buffer, vb) 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cienum isp_video_dmaqueue_flags { 13762306a36Sopenharmony_ci /* Set if DMA queue becomes empty when ISP_PIPELINE_STREAM_CONTINUOUS */ 13862306a36Sopenharmony_ci ISP_VIDEO_DMAQUEUE_UNDERRUN = (1 << 0), 13962306a36Sopenharmony_ci /* Set when queuing buffer to an empty DMA queue */ 14062306a36Sopenharmony_ci ISP_VIDEO_DMAQUEUE_QUEUED = (1 << 1), 14162306a36Sopenharmony_ci}; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci#define isp_video_dmaqueue_flags_clr(video) \ 14462306a36Sopenharmony_ci ({ (video)->dmaqueue_flags = 0; }) 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/* 14762306a36Sopenharmony_ci * struct isp_video_operations - ISP video operations 14862306a36Sopenharmony_ci * @queue: Resume streaming when a buffer is queued. Called on VIDIOC_QBUF 14962306a36Sopenharmony_ci * if there was no buffer previously queued. 15062306a36Sopenharmony_ci */ 15162306a36Sopenharmony_cistruct isp_video_operations { 15262306a36Sopenharmony_ci int(*queue)(struct isp_video *video, struct isp_buffer *buffer); 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistruct isp_video { 15662306a36Sopenharmony_ci struct video_device video; 15762306a36Sopenharmony_ci enum v4l2_buf_type type; 15862306a36Sopenharmony_ci struct media_pad pad; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci struct mutex mutex; /* format and crop settings */ 16162306a36Sopenharmony_ci atomic_t active; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci struct isp_device *isp; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci unsigned int capture_mem; 16662306a36Sopenharmony_ci unsigned int bpl_alignment; /* alignment value */ 16762306a36Sopenharmony_ci unsigned int bpl_zero_padding; /* whether the alignment is optional */ 16862306a36Sopenharmony_ci unsigned int bpl_max; /* maximum bytes per line value */ 16962306a36Sopenharmony_ci unsigned int bpl_value; /* bytes per line value */ 17062306a36Sopenharmony_ci unsigned int bpl_padding; /* padding at end of line */ 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci /* Pipeline state */ 17362306a36Sopenharmony_ci struct isp_pipeline pipe; 17462306a36Sopenharmony_ci struct mutex stream_lock; /* pipeline and stream states */ 17562306a36Sopenharmony_ci bool error; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* Video buffers queue */ 17862306a36Sopenharmony_ci struct vb2_queue *queue; 17962306a36Sopenharmony_ci struct mutex queue_lock; /* protects the queue */ 18062306a36Sopenharmony_ci spinlock_t irqlock; /* protects dmaqueue */ 18162306a36Sopenharmony_ci struct list_head dmaqueue; 18262306a36Sopenharmony_ci enum isp_video_dmaqueue_flags dmaqueue_flags; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci const struct isp_video_operations *ops; 18562306a36Sopenharmony_ci}; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci#define to_isp_video(vdev) container_of(vdev, struct isp_video, video) 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistruct isp_video_fh { 19062306a36Sopenharmony_ci struct v4l2_fh vfh; 19162306a36Sopenharmony_ci struct isp_video *video; 19262306a36Sopenharmony_ci struct vb2_queue queue; 19362306a36Sopenharmony_ci struct v4l2_format format; 19462306a36Sopenharmony_ci struct v4l2_fract timeperframe; 19562306a36Sopenharmony_ci}; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh) 19862306a36Sopenharmony_ci#define isp_video_queue_to_isp_video_fh(q) \ 19962306a36Sopenharmony_ci container_of(q, struct isp_video_fh, queue) 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ciint omap3isp_video_init(struct isp_video *video, const char *name); 20262306a36Sopenharmony_civoid omap3isp_video_cleanup(struct isp_video *video); 20362306a36Sopenharmony_ciint omap3isp_video_register(struct isp_video *video, 20462306a36Sopenharmony_ci struct v4l2_device *vdev); 20562306a36Sopenharmony_civoid omap3isp_video_unregister(struct isp_video *video); 20662306a36Sopenharmony_cistruct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video); 20762306a36Sopenharmony_civoid omap3isp_video_cancel_stream(struct isp_video *video); 20862306a36Sopenharmony_civoid omap3isp_video_resume(struct isp_video *video, int continuous); 20962306a36Sopenharmony_cistruct media_pad *omap3isp_video_remote_pad(struct isp_video *video); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ciconst struct isp_format_info * 21262306a36Sopenharmony_ciomap3isp_video_format_info(u32 code); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci#endif /* OMAP3_ISP_VIDEO_H */ 215