brintos

brintos / linux-shallow public Read only

0
0
Text · 10.7 KiB · f3442e2 Raw
398 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * s3c24xx/s3c64xx SoC series Camera Interface (CAMIF) driver4 *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	330#define CAMIF_MAX_OUT_BUFS	431#define CAMIF_MAX_PIX_WIDTH	409632#define CAMIF_MAX_PIX_HEIGHT	409633#define SCALER_MAX_RATIO	6434#define CAMIF_DEF_WIDTH		64035#define CAMIF_DEF_HEIGHT	48036#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	057#define CAMIF_SD_PAD_SOURCE_C	158#define CAMIF_SD_PAD_SOURCE_P	259#define CAMIF_SD_PADS_NUM	360 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 description84 * @fourcc:    fourcc code for this format, 0 if not applicable85 * @color:     a corresponding enum img_fmt86 * @colplanes: number of physically contiguous data planes87 * @flags:     indicate for which SoCs revisions this format is valid88 * @depth:     bits per pixel (total)89 * @ybpp:      number of luminance bytes per pixel90 */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 DMA102 * @initial: offset (in pixels) to first pixel103 * @line: offset (in pixels) from end of line to start of next line104 */105struct camif_dma_offset {106	int	initial;107	int	line;108};109 110/**111 * struct camif_frame - source/target frame properties112 * @f_width: full pixel width113 * @f_height: full pixel height114 * @rect: crop/composition rectangle115 * @dma_offset: DMA offset configuration116 */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 structure146 * @vp_pix_limits:    pixel limits for the codec and preview paths147 * @pix_limits:       pixel limits for the camera input interface148 * @ip_revision:      the CAMIF IP revision: 0x20 for s3c244x, 0x32 for s3c6410149 * @has_img_effect:   supports image effects150 * @vp_offset:        register offset151 */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 waitqueue185 * @irq:	    interrupt number for this data path186 * @camif:	    pointer to the camif structure187 * @pad:	    media pad for the video node188 * @vdev:           video device189 * @ctrl_handler:   video node controls handler190 * @owner:	    file handle that own the streaming191 * @vb_queue:       vb2 buffer queue192 * @pending_buf_q:  pending (empty) buffers queue head193 * @active_buf_q:   active (being written) buffers queue head194 * @active_buffers: counter of buffer set up at the DMA engine195 * @buf_index:	    identifier of a last empty buffer set up in H/W196 * @frame_sequence: image frame sequence counter197 * @reqbufs_count:  the number of buffers requested198 * @scaler:	    the scaler structure199 * @out_fmt:	    pixel format at this video path output200 * @payload:	    the output data frame payload size201 * @out_frame:	    the output pixel resolution202 * @state:	    the video path's state203 * @fmt_flags:	    flags determining supported pixel formats204 * @id:		    CAMIF id, 0 - codec, 1 - preview205 * @rotation:	    current image rotation value206 * @hflip:	    apply horizontal flip if set207 * @vflip:	    apply vertical flip if set208 * @offset:	    register offset209 */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	0240#define VP_PREVIEW	1241#define CAMIF_VP_NUM	2242 243/**244 * struct camif_dev - the CAMIF driver private data structure245 * @media_dev:    top-level media device structure246 * @v4l2_dev:	  root v4l2_device247 * @subdev:       camera interface ("catchcam") subdev248 * @mbus_fmt:	  camera input media bus format249 * @camif_crop:   camera input interface crop rectangle250 * @pads:	  the camif subdev's media pads251 * @stream_count: the camera interface streaming reference counter252 * @sensor:       image sensor data structure253 * @m_pipeline:	  video entity pipeline description254 * @ctrl_handler: v4l2 control handler (owned by @subdev)255 * @ctrl_test_pattern: V4L2_CID_TEST_PATTERN control256 * @ctrl_colorfx: V4L2_CID_COLORFX control257 * @ctrl_colorfx_cbcr:  V4L2_CID_COLORFX_CBCR control258 * @test_pattern: test pattern259 * @colorfx:	  color effect260 * @colorfx_cb:   Cb value for V4L2_COLORFX_SET_CBCR261 * @colorfx_cr:   Cr value for V4L2_COLORFX_SET_CBCR262 * @vp:           video path (DMA) description (codec/preview)263 * @variant:      variant information for this device264 * @dev:	  pointer to the CAMIF device struct265 * @pdata:	  a copy of the driver's platform data266 * @clock:	  clocks required for the CAMIF operation267 * @lock:	  mutex protecting this data structure268 * @slock:	  spinlock protecting CAMIF registers269 * @io_base:	  start address of the mmapped CAMIF registers270 */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 structure311 * @y:	 luminance plane dma address312 * @cb:	 Cb plane dma address313 * @cr:	 Cr plane dma address314 */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 structure323 * @vb:    vb2 buffer324 * @list:  list head for the buffers queue325 * @paddr: DMA start addresses326 * @index: an identifier of this buffer at the DMA engine327 */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_ */398