/* * linux/drivers/gpu/drm/omapdrm/omap_wb.h * * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ * Author: Benoit Parrot, * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation version 2. * * This program is distributed "as is" WITHOUT ANY WARRANTY of any * kind, whether express or implied; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef __OMAP_WB_H__ #define __OMAP_WB_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dss/omapdss.h" #include "omap_drv.h" #define WB_MODULE_NAME "omapwb" #define WBM2M_MODULE_NAME "omapwb-m2m" #define WBCAP_MODULE_NAME "omapwb-cap" extern unsigned wbdebug; #define log_dbg(dev, fmt, arg...) \ v4l2_dbg(1, wbdebug, &dev->v4l2_dev, "%s: " fmt, \ __func__, ## arg) #define log_err(dev, fmt, arg...) \ v4l2_err(&dev->v4l2_dev, fmt, ## arg) #define log_info(dev, fmt, arg...) \ v4l2_info(&dev->v4l2_dev, fmt, ## arg) /* minimum and maximum frame sizes */ #define MIN_W 32 #define MIN_H 32 #define MAX_W 2048 #define MAX_H 2048 /* required alignments */ #define S_ALIGN 0 /* multiple of 1 */ #define H_ALIGN 0 /* multiple of 2 */ /* used as plane indices */ #define MAX_PLANES 2 #define LUMA_PLANE 0 #define CHROMA_PLANE 1 enum omap_wb_mode { OMAP_WB_NOT_CONFIGURED = 0, /* mem2mem from single ovl to wb */ OMAP_WB_MEM2MEM_OVL = 1, /* mem2mem from N overlays via single mgr to wb */ OMAP_WB_MEM2MEM_MGR = 2, /* capture from single mgr to wb */ OMAP_WB_CAPTURE_MGR = 3 }; enum wb_state { WB_STATE_NONE = 0, WB_STATE_FIRST_FRAME, WB_STATE_CAPTURING, WB_STATE_STOPPING, WB_STATE_STOPPED, }; /* driver info for each of the supported video formats */ struct wb_fmt { u32 fourcc; /* standard format identifier */ u8 coplanar; /* set for unpacked Luma and Chroma */ u8 depth[MAX_PLANES]; /* Bits per pixel per plane*/ }; extern struct wb_fmt wb_formats[]; extern unsigned int num_wb_formats; /* Return a specific unsigned byte from an unsigned int */ #define GET_BYTE(c, b) ((c >> (b * 8)) & 0xff) struct wb_buffer { struct vb2_v4l2_buffer vb; struct list_head list; }; /* * per-queue, driver-specific private data. * MEM-2-MEM: Source: V4L2_BUF_TYPE_VIDEO_OUTPUT* * Destination: V4L2_BUF_TYPE_VIDEO_CAPTURE* * CAPTURE: Destination: V4L2_BUF_TYPE_VIDEO_CAPTURE* only */ struct wb_q_data { /* format info */ struct v4l2_format format; /* crop/compose rectangle */ struct v4l2_rect c_rect; /* format info */ struct wb_fmt *fmt; }; enum { Q_DATA_SRC = 0, Q_DATA_DST = 1, }; /* find our format description corresponding to the passed v4l2_format */ struct wb_fmt *find_format(struct v4l2_format *f); struct wb_dev { struct v4l2_device v4l2_dev; struct drm_device *drm_dev; struct omap_drm_irq wb_irq; atomic_t irq_enabled; /* v4l2_ioctl mutex */ struct mutex lock; enum omap_wb_mode mode; struct wbcap_dev *cap; struct wbm2m_dev *m2m; }; /* * there is one wbcap_dev structure in the driver. */ struct wbcap_dev { struct v4l2_device v4l2_dev; struct video_device vdev; struct v4l2_fh fh; struct wb_dev *dev; struct v4l2_ctrl_handler hdl; /* dst queue data */ struct wb_q_data q_data[2]; unsigned input; struct vb2_queue queue; struct vb2_alloc_ctx *alloc_ctx; spinlock_t qlock; struct list_head buf_list; /* Current v4l2_buffer */ struct wb_buffer *cur_frm; /* Next v4l2_buffer */ struct wb_buffer *next_frm; unsigned field; unsigned sequence; bool stopping; wait_queue_head_t event; enum wb_state state; /* timer used to wait for wb go bit to be cleared */ struct hrtimer wbgo_timer; }; /* * there is one wbm2m_dev structure in the driver. */ struct wbm2m_dev { struct v4l2_device v4l2_dev; struct video_device vfd; struct v4l2_m2m_dev *m2m_dev; struct wb_dev *dev; struct drm_plane *plane; /* v4l2 buffers lock */ spinlock_t lock; struct vb2_alloc_ctx *alloc_ctx; }; /* * There is one wbm2m_ctx structure for each m2m context. */ struct wbm2m_ctx { struct v4l2_fh fh; struct wbm2m_dev *dev; struct v4l2_ctrl_handler hdl; /* current frame seq */ unsigned int sequence; /* abort after next irq */ unsigned int aborting; /* src & dst queue data */ struct wb_q_data q_data[2]; }; static inline struct wb_buffer *to_wb_buffer(struct vb2_buffer *vb2) { return container_of(vb2, struct wb_buffer, vb.vb2_buf); } static inline dma_addr_t vb2_dma_addr_plus_data_offset(struct vb2_buffer *vb, unsigned int plane_no) { return vb2_dma_contig_plane_dma_addr(vb, plane_no) + vb->planes[plane_no].data_offset; } enum omap_color_mode fourcc_to_dss(u32 fourcc); void wbm2m_irq(struct wbm2m_dev *dev, uint32_t irqstatus); int wbm2m_init(struct wb_dev *dev); void wbm2m_cleanup(struct wb_dev *dev); void wbcap_irq(struct wbcap_dev *dev, u32 irqstatus); int wbcap_init(struct wb_dev *dev); void wbcap_cleanup(struct wb_dev *dev); #endif /* __OMAP_WB_H__ */