123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /*
- * Copyright (C) STMicroelectronics SA 2014
- * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
- */
- #include <linux/clk.h>
- #include <linux/ktime.h>
- #include <linux/platform_device.h>
- #include <linux/spinlock.h>
- #include <media/v4l2-ctrls.h>
- #include <media/v4l2-device.h>
- #include <media/v4l2-mem2mem.h>
- #include <media/videobuf2-dma-contig.h>
- #define BDISP_NAME "bdisp"
- /*
- * Max nb of nodes in node-list:
- * - 2 nodes to handle wide 4K pictures
- * - 2 nodes to handle two planes (Y & CbCr) */
- #define MAX_OUTPUT_PLANES 2
- #define MAX_VERTICAL_STRIDES 2
- #define MAX_NB_NODE (MAX_OUTPUT_PLANES * MAX_VERTICAL_STRIDES)
- /* struct bdisp_ctrls - bdisp control set
- * @hflip: horizontal flip
- * @vflip: vertical flip
- */
- struct bdisp_ctrls {
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- };
- /**
- * struct bdisp_fmt - driver's internal color format data
- * @pixelformat:fourcc code for this format
- * @nb_planes: number of planes (ex: [0]=RGB/Y - [1]=Cb/Cr, ...)
- * @bpp: bits per pixel (general)
- * @bpp_plane0: byte per pixel for the 1st plane
- * @w_align: width alignment in pixel (multiple of)
- * @h_align: height alignment in pixel (multiple of)
- */
- struct bdisp_fmt {
- u32 pixelformat;
- u8 nb_planes;
- u8 bpp;
- u8 bpp_plane0;
- u8 w_align;
- u8 h_align;
- };
- /**
- * struct bdisp_frame - frame properties
- *
- * @width: frame width (including padding)
- * @height: frame height (including padding)
- * @fmt: pointer to frame format descriptor
- * @field: frame / field type
- * @bytesperline: stride of the 1st plane
- * @sizeimage: image size in bytes
- * @colorspace: colorspace
- * @crop: crop area
- * @paddr: image physical addresses per plane ([0]=RGB/Y - [1]=Cb/Cr, ...)
- */
- struct bdisp_frame {
- u32 width;
- u32 height;
- const struct bdisp_fmt *fmt;
- enum v4l2_field field;
- u32 bytesperline;
- u32 sizeimage;
- enum v4l2_colorspace colorspace;
- struct v4l2_rect crop;
- dma_addr_t paddr[4];
- };
- /**
- * struct bdisp_request - bdisp request
- *
- * @src: source frame properties
- * @dst: destination frame properties
- * @hflip: horizontal flip
- * @vflip: vertical flip
- * @nb_req: number of run request
- */
- struct bdisp_request {
- struct bdisp_frame src;
- struct bdisp_frame dst;
- unsigned int hflip:1;
- unsigned int vflip:1;
- int nb_req;
- };
- /**
- * struct bdisp_ctx - device context data
- *
- * @src: source frame properties
- * @dst: destination frame properties
- * @state: flags to keep track of user configuration
- * @hflip: horizontal flip
- * @vflip: vertical flip
- * @bdisp_dev: the device this context applies to
- * @node: node array
- * @node_paddr: node physical address array
- * @fh: v4l2 file handle
- * @ctrl_handler: v4l2 controls handler
- * @bdisp_ctrls: bdisp control set
- * @ctrls_rdy: true if the control handler is initialized
- */
- struct bdisp_ctx {
- struct bdisp_frame src;
- struct bdisp_frame dst;
- u32 state;
- unsigned int hflip:1;
- unsigned int vflip:1;
- struct bdisp_dev *bdisp_dev;
- struct bdisp_node *node[MAX_NB_NODE];
- dma_addr_t node_paddr[MAX_NB_NODE];
- struct v4l2_fh fh;
- struct v4l2_ctrl_handler ctrl_handler;
- struct bdisp_ctrls bdisp_ctrls;
- bool ctrls_rdy;
- };
- /**
- * struct bdisp_m2m_device - v4l2 memory-to-memory device data
- *
- * @vdev: video device node for v4l2 m2m mode
- * @m2m_dev: v4l2 m2m device data
- * @ctx: hardware context data
- * @refcnt: reference counter
- */
- struct bdisp_m2m_device {
- struct video_device *vdev;
- struct v4l2_m2m_dev *m2m_dev;
- struct bdisp_ctx *ctx;
- int refcnt;
- };
- /**
- * struct bdisp_dbg - debug info
- *
- * @debugfs_entry: debugfs
- * @copy_node: array of last used nodes
- * @copy_request: last bdisp request
- * @hw_start: start time of last HW request
- * @last_duration: last HW processing duration in microsecs
- * @min_duration: min HW processing duration in microsecs
- * @max_duration: max HW processing duration in microsecs
- * @tot_duration: total HW processing duration in microsecs
- */
- struct bdisp_dbg {
- struct dentry *debugfs_entry;
- struct bdisp_node *copy_node[MAX_NB_NODE];
- struct bdisp_request copy_request;
- ktime_t hw_start;
- s64 last_duration;
- s64 min_duration;
- s64 max_duration;
- s64 tot_duration;
- };
- /**
- * struct bdisp_dev - abstraction for bdisp entity
- *
- * @v4l2_dev: v4l2 device
- * @vdev: video device
- * @pdev: platform device
- * @dev: device
- * @lock: mutex protecting this data structure
- * @slock: spinlock protecting this data structure
- * @id: device index
- * @m2m: memory-to-memory V4L2 device information
- * @state: flags used to synchronize m2m and capture mode operation
- * @alloc_ctx: videobuf2 memory allocator context
- * @clock: IP clock
- * @regs: registers
- * @irq_queue: interrupt handler waitqueue
- * @work_queue: workqueue to handle timeouts
- * @timeout_work: IRQ timeout structure
- * @dbg: debug info
- */
- struct bdisp_dev {
- struct v4l2_device v4l2_dev;
- struct video_device vdev;
- struct platform_device *pdev;
- struct device *dev;
- spinlock_t slock;
- struct mutex lock;
- u16 id;
- struct bdisp_m2m_device m2m;
- unsigned long state;
- struct vb2_alloc_ctx *alloc_ctx;
- struct clk *clock;
- void __iomem *regs;
- wait_queue_head_t irq_queue;
- struct workqueue_struct *work_queue;
- struct delayed_work timeout_work;
- struct bdisp_dbg dbg;
- };
- void bdisp_hw_free_nodes(struct bdisp_ctx *ctx);
- int bdisp_hw_alloc_nodes(struct bdisp_ctx *ctx);
- void bdisp_hw_free_filters(struct device *dev);
- int bdisp_hw_alloc_filters(struct device *dev);
- int bdisp_hw_reset(struct bdisp_dev *bdisp);
- int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp);
- int bdisp_hw_update(struct bdisp_ctx *ctx);
- void bdisp_debugfs_remove(struct bdisp_dev *bdisp);
- int bdisp_debugfs_create(struct bdisp_dev *bdisp);
- void bdisp_dbg_perf_begin(struct bdisp_dev *bdisp);
- void bdisp_dbg_perf_end(struct bdisp_dev *bdisp);
|