/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright ( C ) STMicroelectronics SA 2014
* Authors : Fabien Dessenne < fabien . dessenne @ st . com > for STMicroelectronics .
*/
#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 4 K 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 1 st 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 1 st 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
* @ 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 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);
void 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);
Messung V0.5 in Prozent C=94 H=93 G=93
¤ Dauer der Verarbeitung: 0.7 Sekunden
¤
*© Formatika GbR, Deutschland