19ed785a9SBenjamin Gaignard /* SPDX-License-Identifier: GPL-2.0 */ 228ffeebbSFabien Dessenne /* 328ffeebbSFabien Dessenne * Copyright (C) STMicroelectronics SA 2014 428ffeebbSFabien Dessenne * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics. 528ffeebbSFabien Dessenne */ 628ffeebbSFabien Dessenne 728ffeebbSFabien Dessenne #include <linux/clk.h> 828ffeebbSFabien Dessenne #include <linux/ktime.h> 928ffeebbSFabien Dessenne #include <linux/platform_device.h> 1028ffeebbSFabien Dessenne #include <linux/spinlock.h> 1128ffeebbSFabien Dessenne 1228ffeebbSFabien Dessenne #include <media/v4l2-ctrls.h> 1328ffeebbSFabien Dessenne #include <media/v4l2-device.h> 1428ffeebbSFabien Dessenne #include <media/v4l2-mem2mem.h> 1528ffeebbSFabien Dessenne 1628ffeebbSFabien Dessenne #include <media/videobuf2-dma-contig.h> 1728ffeebbSFabien Dessenne 1828ffeebbSFabien Dessenne #define BDISP_NAME "bdisp" 1928ffeebbSFabien Dessenne 2028ffeebbSFabien Dessenne /* 2128ffeebbSFabien Dessenne * Max nb of nodes in node-list: 2228ffeebbSFabien Dessenne * - 2 nodes to handle wide 4K pictures 2328ffeebbSFabien Dessenne * - 2 nodes to handle two planes (Y & CbCr) */ 2428ffeebbSFabien Dessenne #define MAX_OUTPUT_PLANES 2 2528ffeebbSFabien Dessenne #define MAX_VERTICAL_STRIDES 2 2628ffeebbSFabien Dessenne #define MAX_NB_NODE (MAX_OUTPUT_PLANES * MAX_VERTICAL_STRIDES) 2728ffeebbSFabien Dessenne 2828ffeebbSFabien Dessenne /* struct bdisp_ctrls - bdisp control set 2928ffeebbSFabien Dessenne * @hflip: horizontal flip 3028ffeebbSFabien Dessenne * @vflip: vertical flip 3128ffeebbSFabien Dessenne */ 3228ffeebbSFabien Dessenne struct bdisp_ctrls { 3328ffeebbSFabien Dessenne struct v4l2_ctrl *hflip; 3428ffeebbSFabien Dessenne struct v4l2_ctrl *vflip; 3528ffeebbSFabien Dessenne }; 3628ffeebbSFabien Dessenne 3728ffeebbSFabien Dessenne /** 3828ffeebbSFabien Dessenne * struct bdisp_fmt - driver's internal color format data 3928ffeebbSFabien Dessenne * @pixelformat:fourcc code for this format 4028ffeebbSFabien Dessenne * @nb_planes: number of planes (ex: [0]=RGB/Y - [1]=Cb/Cr, ...) 4128ffeebbSFabien Dessenne * @bpp: bits per pixel (general) 4228ffeebbSFabien Dessenne * @bpp_plane0: byte per pixel for the 1st plane 4328ffeebbSFabien Dessenne * @w_align: width alignment in pixel (multiple of) 4428ffeebbSFabien Dessenne * @h_align: height alignment in pixel (multiple of) 4528ffeebbSFabien Dessenne */ 4628ffeebbSFabien Dessenne struct bdisp_fmt { 4728ffeebbSFabien Dessenne u32 pixelformat; 4828ffeebbSFabien Dessenne u8 nb_planes; 4928ffeebbSFabien Dessenne u8 bpp; 5028ffeebbSFabien Dessenne u8 bpp_plane0; 5128ffeebbSFabien Dessenne u8 w_align; 5228ffeebbSFabien Dessenne u8 h_align; 5328ffeebbSFabien Dessenne }; 5428ffeebbSFabien Dessenne 5528ffeebbSFabien Dessenne /** 5628ffeebbSFabien Dessenne * struct bdisp_frame - frame properties 5728ffeebbSFabien Dessenne * 5828ffeebbSFabien Dessenne * @width: frame width (including padding) 5928ffeebbSFabien Dessenne * @height: frame height (including padding) 6028ffeebbSFabien Dessenne * @fmt: pointer to frame format descriptor 6128ffeebbSFabien Dessenne * @field: frame / field type 6228ffeebbSFabien Dessenne * @bytesperline: stride of the 1st plane 6328ffeebbSFabien Dessenne * @sizeimage: image size in bytes 6428ffeebbSFabien Dessenne * @colorspace: colorspace 6528ffeebbSFabien Dessenne * @crop: crop area 6628ffeebbSFabien Dessenne * @paddr: image physical addresses per plane ([0]=RGB/Y - [1]=Cb/Cr, ...) 6728ffeebbSFabien Dessenne */ 6828ffeebbSFabien Dessenne struct bdisp_frame { 6928ffeebbSFabien Dessenne u32 width; 7028ffeebbSFabien Dessenne u32 height; 7128ffeebbSFabien Dessenne const struct bdisp_fmt *fmt; 7228ffeebbSFabien Dessenne enum v4l2_field field; 7328ffeebbSFabien Dessenne u32 bytesperline; 7428ffeebbSFabien Dessenne u32 sizeimage; 7528ffeebbSFabien Dessenne enum v4l2_colorspace colorspace; 7628ffeebbSFabien Dessenne struct v4l2_rect crop; 7728ffeebbSFabien Dessenne dma_addr_t paddr[4]; 7828ffeebbSFabien Dessenne }; 7928ffeebbSFabien Dessenne 8028ffeebbSFabien Dessenne /** 8128ffeebbSFabien Dessenne * struct bdisp_request - bdisp request 8228ffeebbSFabien Dessenne * 8328ffeebbSFabien Dessenne * @src: source frame properties 8428ffeebbSFabien Dessenne * @dst: destination frame properties 8528ffeebbSFabien Dessenne * @hflip: horizontal flip 8628ffeebbSFabien Dessenne * @vflip: vertical flip 8728ffeebbSFabien Dessenne * @nb_req: number of run request 8828ffeebbSFabien Dessenne */ 8928ffeebbSFabien Dessenne struct bdisp_request { 9028ffeebbSFabien Dessenne struct bdisp_frame src; 9128ffeebbSFabien Dessenne struct bdisp_frame dst; 9228ffeebbSFabien Dessenne unsigned int hflip:1; 9328ffeebbSFabien Dessenne unsigned int vflip:1; 9428ffeebbSFabien Dessenne int nb_req; 9528ffeebbSFabien Dessenne }; 9628ffeebbSFabien Dessenne 9728ffeebbSFabien Dessenne /** 9828ffeebbSFabien Dessenne * struct bdisp_ctx - device context data 9928ffeebbSFabien Dessenne * 10028ffeebbSFabien Dessenne * @src: source frame properties 10128ffeebbSFabien Dessenne * @dst: destination frame properties 10228ffeebbSFabien Dessenne * @state: flags to keep track of user configuration 10328ffeebbSFabien Dessenne * @hflip: horizontal flip 10428ffeebbSFabien Dessenne * @vflip: vertical flip 10528ffeebbSFabien Dessenne * @bdisp_dev: the device this context applies to 10628ffeebbSFabien Dessenne * @node: node array 10728ffeebbSFabien Dessenne * @node_paddr: node physical address array 10828ffeebbSFabien Dessenne * @fh: v4l2 file handle 10928ffeebbSFabien Dessenne * @ctrl_handler: v4l2 controls handler 11028ffeebbSFabien Dessenne * @bdisp_ctrls: bdisp control set 11128ffeebbSFabien Dessenne * @ctrls_rdy: true if the control handler is initialized 11228ffeebbSFabien Dessenne */ 11328ffeebbSFabien Dessenne struct bdisp_ctx { 11428ffeebbSFabien Dessenne struct bdisp_frame src; 11528ffeebbSFabien Dessenne struct bdisp_frame dst; 11628ffeebbSFabien Dessenne u32 state; 11728ffeebbSFabien Dessenne unsigned int hflip:1; 11828ffeebbSFabien Dessenne unsigned int vflip:1; 11928ffeebbSFabien Dessenne struct bdisp_dev *bdisp_dev; 12028ffeebbSFabien Dessenne struct bdisp_node *node[MAX_NB_NODE]; 12128ffeebbSFabien Dessenne dma_addr_t node_paddr[MAX_NB_NODE]; 12228ffeebbSFabien Dessenne struct v4l2_fh fh; 12328ffeebbSFabien Dessenne struct v4l2_ctrl_handler ctrl_handler; 12428ffeebbSFabien Dessenne struct bdisp_ctrls bdisp_ctrls; 12528ffeebbSFabien Dessenne bool ctrls_rdy; 12628ffeebbSFabien Dessenne }; 12728ffeebbSFabien Dessenne 12828ffeebbSFabien Dessenne /** 12928ffeebbSFabien Dessenne * struct bdisp_m2m_device - v4l2 memory-to-memory device data 13028ffeebbSFabien Dessenne * 13128ffeebbSFabien Dessenne * @vdev: video device node for v4l2 m2m mode 13228ffeebbSFabien Dessenne * @m2m_dev: v4l2 m2m device data 13328ffeebbSFabien Dessenne * @ctx: hardware context data 13428ffeebbSFabien Dessenne * @refcnt: reference counter 13528ffeebbSFabien Dessenne */ 13628ffeebbSFabien Dessenne struct bdisp_m2m_device { 13728ffeebbSFabien Dessenne struct video_device *vdev; 13828ffeebbSFabien Dessenne struct v4l2_m2m_dev *m2m_dev; 13928ffeebbSFabien Dessenne struct bdisp_ctx *ctx; 14028ffeebbSFabien Dessenne int refcnt; 14128ffeebbSFabien Dessenne }; 14228ffeebbSFabien Dessenne 14328ffeebbSFabien Dessenne /** 14434b6beb6SFabien Dessenne * struct bdisp_dbg - debug info 14534b6beb6SFabien Dessenne * 14634b6beb6SFabien Dessenne * @debugfs_entry: debugfs 14734b6beb6SFabien Dessenne * @copy_node: array of last used nodes 14834b6beb6SFabien Dessenne * @copy_request: last bdisp request 14934b6beb6SFabien Dessenne * @hw_start: start time of last HW request 15034b6beb6SFabien Dessenne * @last_duration: last HW processing duration in microsecs 15134b6beb6SFabien Dessenne * @min_duration: min HW processing duration in microsecs 15234b6beb6SFabien Dessenne * @max_duration: max HW processing duration in microsecs 15334b6beb6SFabien Dessenne * @tot_duration: total HW processing duration in microsecs 15434b6beb6SFabien Dessenne */ 15534b6beb6SFabien Dessenne struct bdisp_dbg { 15634b6beb6SFabien Dessenne struct dentry *debugfs_entry; 15734b6beb6SFabien Dessenne struct bdisp_node *copy_node[MAX_NB_NODE]; 15834b6beb6SFabien Dessenne struct bdisp_request copy_request; 15934b6beb6SFabien Dessenne ktime_t hw_start; 16034b6beb6SFabien Dessenne s64 last_duration; 16134b6beb6SFabien Dessenne s64 min_duration; 16234b6beb6SFabien Dessenne s64 max_duration; 16334b6beb6SFabien Dessenne s64 tot_duration; 16434b6beb6SFabien Dessenne }; 16534b6beb6SFabien Dessenne 16634b6beb6SFabien Dessenne /** 16728ffeebbSFabien Dessenne * struct bdisp_dev - abstraction for bdisp entity 16828ffeebbSFabien Dessenne * 16928ffeebbSFabien Dessenne * @v4l2_dev: v4l2 device 17028ffeebbSFabien Dessenne * @vdev: video device 17128ffeebbSFabien Dessenne * @pdev: platform device 17228ffeebbSFabien Dessenne * @dev: device 17328ffeebbSFabien Dessenne * @lock: mutex protecting this data structure 17428ffeebbSFabien Dessenne * @slock: spinlock protecting this data structure 17528ffeebbSFabien Dessenne * @id: device index 17628ffeebbSFabien Dessenne * @m2m: memory-to-memory V4L2 device information 17728ffeebbSFabien Dessenne * @state: flags used to synchronize m2m and capture mode operation 17828ffeebbSFabien Dessenne * @clock: IP clock 17928ffeebbSFabien Dessenne * @regs: registers 18028ffeebbSFabien Dessenne * @irq_queue: interrupt handler waitqueue 18128ffeebbSFabien Dessenne * @work_queue: workqueue to handle timeouts 18228ffeebbSFabien Dessenne * @timeout_work: IRQ timeout structure 18334b6beb6SFabien Dessenne * @dbg: debug info 18428ffeebbSFabien Dessenne */ 18528ffeebbSFabien Dessenne struct bdisp_dev { 18628ffeebbSFabien Dessenne struct v4l2_device v4l2_dev; 18728ffeebbSFabien Dessenne struct video_device vdev; 18828ffeebbSFabien Dessenne struct platform_device *pdev; 18928ffeebbSFabien Dessenne struct device *dev; 19028ffeebbSFabien Dessenne spinlock_t slock; 19128ffeebbSFabien Dessenne struct mutex lock; 19228ffeebbSFabien Dessenne u16 id; 19328ffeebbSFabien Dessenne struct bdisp_m2m_device m2m; 19428ffeebbSFabien Dessenne unsigned long state; 19528ffeebbSFabien Dessenne struct clk *clock; 19628ffeebbSFabien Dessenne void __iomem *regs; 19728ffeebbSFabien Dessenne wait_queue_head_t irq_queue; 19828ffeebbSFabien Dessenne struct workqueue_struct *work_queue; 19928ffeebbSFabien Dessenne struct delayed_work timeout_work; 20034b6beb6SFabien Dessenne struct bdisp_dbg dbg; 20128ffeebbSFabien Dessenne }; 20228ffeebbSFabien Dessenne 20328ffeebbSFabien Dessenne void bdisp_hw_free_nodes(struct bdisp_ctx *ctx); 20428ffeebbSFabien Dessenne int bdisp_hw_alloc_nodes(struct bdisp_ctx *ctx); 20528ffeebbSFabien Dessenne void bdisp_hw_free_filters(struct device *dev); 20628ffeebbSFabien Dessenne int bdisp_hw_alloc_filters(struct device *dev); 20728ffeebbSFabien Dessenne int bdisp_hw_reset(struct bdisp_dev *bdisp); 20828ffeebbSFabien Dessenne int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp); 20928ffeebbSFabien Dessenne int bdisp_hw_update(struct bdisp_ctx *ctx); 21034b6beb6SFabien Dessenne 21134b6beb6SFabien Dessenne void bdisp_debugfs_remove(struct bdisp_dev *bdisp); 212*8c23f411SGreg Kroah-Hartman void bdisp_debugfs_create(struct bdisp_dev *bdisp); 21334b6beb6SFabien Dessenne void bdisp_dbg_perf_begin(struct bdisp_dev *bdisp); 21434b6beb6SFabien Dessenne void bdisp_dbg_perf_end(struct bdisp_dev *bdisp); 215