1*e7b8153eSMauro Carvalho Chehab /* SPDX-License-Identifier: GPL-2.0 */ 2*e7b8153eSMauro Carvalho Chehab /* 3*e7b8153eSMauro Carvalho Chehab * Copyright (C) STMicroelectronics SA 2014 4*e7b8153eSMauro Carvalho Chehab * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics. 5*e7b8153eSMauro Carvalho Chehab */ 6*e7b8153eSMauro Carvalho Chehab 7*e7b8153eSMauro Carvalho Chehab #include <linux/clk.h> 8*e7b8153eSMauro Carvalho Chehab #include <linux/ktime.h> 9*e7b8153eSMauro Carvalho Chehab #include <linux/platform_device.h> 10*e7b8153eSMauro Carvalho Chehab #include <linux/spinlock.h> 11*e7b8153eSMauro Carvalho Chehab 12*e7b8153eSMauro Carvalho Chehab #include <media/v4l2-ctrls.h> 13*e7b8153eSMauro Carvalho Chehab #include <media/v4l2-device.h> 14*e7b8153eSMauro Carvalho Chehab #include <media/v4l2-mem2mem.h> 15*e7b8153eSMauro Carvalho Chehab 16*e7b8153eSMauro Carvalho Chehab #include <media/videobuf2-dma-contig.h> 17*e7b8153eSMauro Carvalho Chehab 18*e7b8153eSMauro Carvalho Chehab #define BDISP_NAME "bdisp" 19*e7b8153eSMauro Carvalho Chehab 20*e7b8153eSMauro Carvalho Chehab /* 21*e7b8153eSMauro Carvalho Chehab * Max nb of nodes in node-list: 22*e7b8153eSMauro Carvalho Chehab * - 2 nodes to handle wide 4K pictures 23*e7b8153eSMauro Carvalho Chehab * - 2 nodes to handle two planes (Y & CbCr) */ 24*e7b8153eSMauro Carvalho Chehab #define MAX_OUTPUT_PLANES 2 25*e7b8153eSMauro Carvalho Chehab #define MAX_VERTICAL_STRIDES 2 26*e7b8153eSMauro Carvalho Chehab #define MAX_NB_NODE (MAX_OUTPUT_PLANES * MAX_VERTICAL_STRIDES) 27*e7b8153eSMauro Carvalho Chehab 28*e7b8153eSMauro Carvalho Chehab /* struct bdisp_ctrls - bdisp control set 29*e7b8153eSMauro Carvalho Chehab * @hflip: horizontal flip 30*e7b8153eSMauro Carvalho Chehab * @vflip: vertical flip 31*e7b8153eSMauro Carvalho Chehab */ 32*e7b8153eSMauro Carvalho Chehab struct bdisp_ctrls { 33*e7b8153eSMauro Carvalho Chehab struct v4l2_ctrl *hflip; 34*e7b8153eSMauro Carvalho Chehab struct v4l2_ctrl *vflip; 35*e7b8153eSMauro Carvalho Chehab }; 36*e7b8153eSMauro Carvalho Chehab 37*e7b8153eSMauro Carvalho Chehab /** 38*e7b8153eSMauro Carvalho Chehab * struct bdisp_fmt - driver's internal color format data 39*e7b8153eSMauro Carvalho Chehab * @pixelformat:fourcc code for this format 40*e7b8153eSMauro Carvalho Chehab * @nb_planes: number of planes (ex: [0]=RGB/Y - [1]=Cb/Cr, ...) 41*e7b8153eSMauro Carvalho Chehab * @bpp: bits per pixel (general) 42*e7b8153eSMauro Carvalho Chehab * @bpp_plane0: byte per pixel for the 1st plane 43*e7b8153eSMauro Carvalho Chehab * @w_align: width alignment in pixel (multiple of) 44*e7b8153eSMauro Carvalho Chehab * @h_align: height alignment in pixel (multiple of) 45*e7b8153eSMauro Carvalho Chehab */ 46*e7b8153eSMauro Carvalho Chehab struct bdisp_fmt { 47*e7b8153eSMauro Carvalho Chehab u32 pixelformat; 48*e7b8153eSMauro Carvalho Chehab u8 nb_planes; 49*e7b8153eSMauro Carvalho Chehab u8 bpp; 50*e7b8153eSMauro Carvalho Chehab u8 bpp_plane0; 51*e7b8153eSMauro Carvalho Chehab u8 w_align; 52*e7b8153eSMauro Carvalho Chehab u8 h_align; 53*e7b8153eSMauro Carvalho Chehab }; 54*e7b8153eSMauro Carvalho Chehab 55*e7b8153eSMauro Carvalho Chehab /** 56*e7b8153eSMauro Carvalho Chehab * struct bdisp_frame - frame properties 57*e7b8153eSMauro Carvalho Chehab * 58*e7b8153eSMauro Carvalho Chehab * @width: frame width (including padding) 59*e7b8153eSMauro Carvalho Chehab * @height: frame height (including padding) 60*e7b8153eSMauro Carvalho Chehab * @fmt: pointer to frame format descriptor 61*e7b8153eSMauro Carvalho Chehab * @field: frame / field type 62*e7b8153eSMauro Carvalho Chehab * @bytesperline: stride of the 1st plane 63*e7b8153eSMauro Carvalho Chehab * @sizeimage: image size in bytes 64*e7b8153eSMauro Carvalho Chehab * @colorspace: colorspace 65*e7b8153eSMauro Carvalho Chehab * @crop: crop area 66*e7b8153eSMauro Carvalho Chehab * @paddr: image physical addresses per plane ([0]=RGB/Y - [1]=Cb/Cr, ...) 67*e7b8153eSMauro Carvalho Chehab */ 68*e7b8153eSMauro Carvalho Chehab struct bdisp_frame { 69*e7b8153eSMauro Carvalho Chehab u32 width; 70*e7b8153eSMauro Carvalho Chehab u32 height; 71*e7b8153eSMauro Carvalho Chehab const struct bdisp_fmt *fmt; 72*e7b8153eSMauro Carvalho Chehab enum v4l2_field field; 73*e7b8153eSMauro Carvalho Chehab u32 bytesperline; 74*e7b8153eSMauro Carvalho Chehab u32 sizeimage; 75*e7b8153eSMauro Carvalho Chehab enum v4l2_colorspace colorspace; 76*e7b8153eSMauro Carvalho Chehab struct v4l2_rect crop; 77*e7b8153eSMauro Carvalho Chehab dma_addr_t paddr[4]; 78*e7b8153eSMauro Carvalho Chehab }; 79*e7b8153eSMauro Carvalho Chehab 80*e7b8153eSMauro Carvalho Chehab /** 81*e7b8153eSMauro Carvalho Chehab * struct bdisp_request - bdisp request 82*e7b8153eSMauro Carvalho Chehab * 83*e7b8153eSMauro Carvalho Chehab * @src: source frame properties 84*e7b8153eSMauro Carvalho Chehab * @dst: destination frame properties 85*e7b8153eSMauro Carvalho Chehab * @hflip: horizontal flip 86*e7b8153eSMauro Carvalho Chehab * @vflip: vertical flip 87*e7b8153eSMauro Carvalho Chehab * @nb_req: number of run request 88*e7b8153eSMauro Carvalho Chehab */ 89*e7b8153eSMauro Carvalho Chehab struct bdisp_request { 90*e7b8153eSMauro Carvalho Chehab struct bdisp_frame src; 91*e7b8153eSMauro Carvalho Chehab struct bdisp_frame dst; 92*e7b8153eSMauro Carvalho Chehab unsigned int hflip:1; 93*e7b8153eSMauro Carvalho Chehab unsigned int vflip:1; 94*e7b8153eSMauro Carvalho Chehab int nb_req; 95*e7b8153eSMauro Carvalho Chehab }; 96*e7b8153eSMauro Carvalho Chehab 97*e7b8153eSMauro Carvalho Chehab /** 98*e7b8153eSMauro Carvalho Chehab * struct bdisp_ctx - device context data 99*e7b8153eSMauro Carvalho Chehab * 100*e7b8153eSMauro Carvalho Chehab * @src: source frame properties 101*e7b8153eSMauro Carvalho Chehab * @dst: destination frame properties 102*e7b8153eSMauro Carvalho Chehab * @state: flags to keep track of user configuration 103*e7b8153eSMauro Carvalho Chehab * @hflip: horizontal flip 104*e7b8153eSMauro Carvalho Chehab * @vflip: vertical flip 105*e7b8153eSMauro Carvalho Chehab * @bdisp_dev: the device this context applies to 106*e7b8153eSMauro Carvalho Chehab * @node: node array 107*e7b8153eSMauro Carvalho Chehab * @node_paddr: node physical address array 108*e7b8153eSMauro Carvalho Chehab * @fh: v4l2 file handle 109*e7b8153eSMauro Carvalho Chehab * @ctrl_handler: v4l2 controls handler 110*e7b8153eSMauro Carvalho Chehab * @bdisp_ctrls: bdisp control set 111*e7b8153eSMauro Carvalho Chehab * @ctrls_rdy: true if the control handler is initialized 112*e7b8153eSMauro Carvalho Chehab */ 113*e7b8153eSMauro Carvalho Chehab struct bdisp_ctx { 114*e7b8153eSMauro Carvalho Chehab struct bdisp_frame src; 115*e7b8153eSMauro Carvalho Chehab struct bdisp_frame dst; 116*e7b8153eSMauro Carvalho Chehab u32 state; 117*e7b8153eSMauro Carvalho Chehab unsigned int hflip:1; 118*e7b8153eSMauro Carvalho Chehab unsigned int vflip:1; 119*e7b8153eSMauro Carvalho Chehab struct bdisp_dev *bdisp_dev; 120*e7b8153eSMauro Carvalho Chehab struct bdisp_node *node[MAX_NB_NODE]; 121*e7b8153eSMauro Carvalho Chehab dma_addr_t node_paddr[MAX_NB_NODE]; 122*e7b8153eSMauro Carvalho Chehab struct v4l2_fh fh; 123*e7b8153eSMauro Carvalho Chehab struct v4l2_ctrl_handler ctrl_handler; 124*e7b8153eSMauro Carvalho Chehab struct bdisp_ctrls bdisp_ctrls; 125*e7b8153eSMauro Carvalho Chehab bool ctrls_rdy; 126*e7b8153eSMauro Carvalho Chehab }; 127*e7b8153eSMauro Carvalho Chehab 128*e7b8153eSMauro Carvalho Chehab /** 129*e7b8153eSMauro Carvalho Chehab * struct bdisp_m2m_device - v4l2 memory-to-memory device data 130*e7b8153eSMauro Carvalho Chehab * 131*e7b8153eSMauro Carvalho Chehab * @vdev: video device node for v4l2 m2m mode 132*e7b8153eSMauro Carvalho Chehab * @m2m_dev: v4l2 m2m device data 133*e7b8153eSMauro Carvalho Chehab * @ctx: hardware context data 134*e7b8153eSMauro Carvalho Chehab * @refcnt: reference counter 135*e7b8153eSMauro Carvalho Chehab */ 136*e7b8153eSMauro Carvalho Chehab struct bdisp_m2m_device { 137*e7b8153eSMauro Carvalho Chehab struct video_device *vdev; 138*e7b8153eSMauro Carvalho Chehab struct v4l2_m2m_dev *m2m_dev; 139*e7b8153eSMauro Carvalho Chehab struct bdisp_ctx *ctx; 140*e7b8153eSMauro Carvalho Chehab int refcnt; 141*e7b8153eSMauro Carvalho Chehab }; 142*e7b8153eSMauro Carvalho Chehab 143*e7b8153eSMauro Carvalho Chehab /** 144*e7b8153eSMauro Carvalho Chehab * struct bdisp_dbg - debug info 145*e7b8153eSMauro Carvalho Chehab * 146*e7b8153eSMauro Carvalho Chehab * @debugfs_entry: debugfs 147*e7b8153eSMauro Carvalho Chehab * @copy_node: array of last used nodes 148*e7b8153eSMauro Carvalho Chehab * @copy_request: last bdisp request 149*e7b8153eSMauro Carvalho Chehab * @hw_start: start time of last HW request 150*e7b8153eSMauro Carvalho Chehab * @last_duration: last HW processing duration in microsecs 151*e7b8153eSMauro Carvalho Chehab * @min_duration: min HW processing duration in microsecs 152*e7b8153eSMauro Carvalho Chehab * @max_duration: max HW processing duration in microsecs 153*e7b8153eSMauro Carvalho Chehab * @tot_duration: total HW processing duration in microsecs 154*e7b8153eSMauro Carvalho Chehab */ 155*e7b8153eSMauro Carvalho Chehab struct bdisp_dbg { 156*e7b8153eSMauro Carvalho Chehab struct dentry *debugfs_entry; 157*e7b8153eSMauro Carvalho Chehab struct bdisp_node *copy_node[MAX_NB_NODE]; 158*e7b8153eSMauro Carvalho Chehab struct bdisp_request copy_request; 159*e7b8153eSMauro Carvalho Chehab ktime_t hw_start; 160*e7b8153eSMauro Carvalho Chehab s64 last_duration; 161*e7b8153eSMauro Carvalho Chehab s64 min_duration; 162*e7b8153eSMauro Carvalho Chehab s64 max_duration; 163*e7b8153eSMauro Carvalho Chehab s64 tot_duration; 164*e7b8153eSMauro Carvalho Chehab }; 165*e7b8153eSMauro Carvalho Chehab 166*e7b8153eSMauro Carvalho Chehab /** 167*e7b8153eSMauro Carvalho Chehab * struct bdisp_dev - abstraction for bdisp entity 168*e7b8153eSMauro Carvalho Chehab * 169*e7b8153eSMauro Carvalho Chehab * @v4l2_dev: v4l2 device 170*e7b8153eSMauro Carvalho Chehab * @vdev: video device 171*e7b8153eSMauro Carvalho Chehab * @pdev: platform device 172*e7b8153eSMauro Carvalho Chehab * @dev: device 173*e7b8153eSMauro Carvalho Chehab * @lock: mutex protecting this data structure 174*e7b8153eSMauro Carvalho Chehab * @slock: spinlock protecting this data structure 175*e7b8153eSMauro Carvalho Chehab * @id: device index 176*e7b8153eSMauro Carvalho Chehab * @m2m: memory-to-memory V4L2 device information 177*e7b8153eSMauro Carvalho Chehab * @state: flags used to synchronize m2m and capture mode operation 178*e7b8153eSMauro Carvalho Chehab * @clock: IP clock 179*e7b8153eSMauro Carvalho Chehab * @regs: registers 180*e7b8153eSMauro Carvalho Chehab * @irq_queue: interrupt handler waitqueue 181*e7b8153eSMauro Carvalho Chehab * @work_queue: workqueue to handle timeouts 182*e7b8153eSMauro Carvalho Chehab * @timeout_work: IRQ timeout structure 183*e7b8153eSMauro Carvalho Chehab * @dbg: debug info 184*e7b8153eSMauro Carvalho Chehab */ 185*e7b8153eSMauro Carvalho Chehab struct bdisp_dev { 186*e7b8153eSMauro Carvalho Chehab struct v4l2_device v4l2_dev; 187*e7b8153eSMauro Carvalho Chehab struct video_device vdev; 188*e7b8153eSMauro Carvalho Chehab struct platform_device *pdev; 189*e7b8153eSMauro Carvalho Chehab struct device *dev; 190*e7b8153eSMauro Carvalho Chehab spinlock_t slock; 191*e7b8153eSMauro Carvalho Chehab struct mutex lock; 192*e7b8153eSMauro Carvalho Chehab u16 id; 193*e7b8153eSMauro Carvalho Chehab struct bdisp_m2m_device m2m; 194*e7b8153eSMauro Carvalho Chehab unsigned long state; 195*e7b8153eSMauro Carvalho Chehab struct clk *clock; 196*e7b8153eSMauro Carvalho Chehab void __iomem *regs; 197*e7b8153eSMauro Carvalho Chehab wait_queue_head_t irq_queue; 198*e7b8153eSMauro Carvalho Chehab struct workqueue_struct *work_queue; 199*e7b8153eSMauro Carvalho Chehab struct delayed_work timeout_work; 200*e7b8153eSMauro Carvalho Chehab struct bdisp_dbg dbg; 201*e7b8153eSMauro Carvalho Chehab }; 202*e7b8153eSMauro Carvalho Chehab 203*e7b8153eSMauro Carvalho Chehab void bdisp_hw_free_nodes(struct bdisp_ctx *ctx); 204*e7b8153eSMauro Carvalho Chehab int bdisp_hw_alloc_nodes(struct bdisp_ctx *ctx); 205*e7b8153eSMauro Carvalho Chehab void bdisp_hw_free_filters(struct device *dev); 206*e7b8153eSMauro Carvalho Chehab int bdisp_hw_alloc_filters(struct device *dev); 207*e7b8153eSMauro Carvalho Chehab int bdisp_hw_reset(struct bdisp_dev *bdisp); 208*e7b8153eSMauro Carvalho Chehab int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp); 209*e7b8153eSMauro Carvalho Chehab int bdisp_hw_update(struct bdisp_ctx *ctx); 210*e7b8153eSMauro Carvalho Chehab 211*e7b8153eSMauro Carvalho Chehab void bdisp_debugfs_remove(struct bdisp_dev *bdisp); 212*e7b8153eSMauro Carvalho Chehab void bdisp_debugfs_create(struct bdisp_dev *bdisp); 213*e7b8153eSMauro Carvalho Chehab void bdisp_dbg_perf_begin(struct bdisp_dev *bdisp); 214*e7b8153eSMauro Carvalho Chehab void bdisp_dbg_perf_end(struct bdisp_dev *bdisp); 215