forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
6.5 KiB
214 lines
6.5 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
/* |
|
* Copyright (C) STMicroelectronics SA 2014 |
|
* Authors: Fabien Dessenne <[email protected]> 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 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 |
|
* @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);
|
|
|