Commit 51abe041 authored by Bingbu Cao's avatar Bingbu Cao Committed by Mauro Carvalho Chehab

media: staging/intel-ipu3: Add dual pipe support

This patch adds support to run dual pipes simultaneously.
A private ioctl to configure the pipe mode (video or still)
is also implemented.

IPU3 hardware supports a maximum of 2 streams per pipe.
With the support of dual pipes, more than 2 stream outputs
can be achieved.

This helps to support advanced camera features like
Continuous View Finder (CVF) and Snapshot During Video(SDV).

Extend ipu3 IMGU driver to support dual pipes

    1. Extend current IMGU device to contain 2 groups
       of video nodes and 2 subdevs
    2. Extend current css to support 2 pipeline and make
       CSS APIs to support 2 pipe
    3. Add a v4l2 ctrl to allow user to specify the mode
       of the pipe
    4. Check media pipeline link status to get enabled
       pipes
Signed-off-by: default avatarBingbu Cao <bingbu.cao@intel.com>
Signed-off-by: default avatarTian Shu Qiu <tian.shu.qiu@intel.com>
Signed-off-by: default avatarYong Zhi <yong.zhi@intel.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 41158dab
......@@ -12,6 +12,16 @@
#define V4L2_META_FMT_IPU3_PARAMS v4l2_fourcc('i', 'p', '3', 'p') /* IPU3 processing parameters */
#define V4L2_META_FMT_IPU3_STAT_3A v4l2_fourcc('i', 'p', '3', 's') /* IPU3 3A statistics */
/* from include/uapi/linux/v4l2-controls.h */
#define V4L2_CID_INTEL_IPU3_BASE (V4L2_CID_USER_BASE + 0x10c0)
#define V4L2_CID_INTEL_IPU3_MODE (V4L2_CID_INTEL_IPU3_BASE + 1)
/* custom ctrl to set pipe mode */
enum ipu3_running_mode {
IPU3_RUNNING_MODE_VIDEO = 0,
IPU3_RUNNING_MODE_STILL = 1,
};
/******************* ipu3_uapi_stats_3a *******************/
#define IPU3_UAPI_MAX_STRIPES 2
......
......@@ -69,16 +69,17 @@ unsigned int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi)
return obgrid_size;
}
void *ipu3_css_fw_pipeline_params(struct ipu3_css *css,
enum imgu_abi_param_class c,
enum imgu_abi_memories m,
void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, unsigned int pipe,
enum imgu_abi_param_class cls,
enum imgu_abi_memories mem,
struct imgu_fw_isp_parameter *par,
size_t par_size, void *binary_params)
{
struct imgu_fw_info *bi = &css->fwp->binary_header[css->current_binary];
struct imgu_fw_info *bi =
&css->fwp->binary_header[css->pipes[pipe].bindex];
if (par->offset + par->size >
bi->info.isp.sp.mem_initializers.params[c][m].size)
bi->info.isp.sp.mem_initializers.params[cls][mem].size)
return NULL;
if (par->size != par_size)
......
......@@ -179,9 +179,9 @@ int ipu3_css_fw_init(struct ipu3_css *css);
void ipu3_css_fw_cleanup(struct ipu3_css *css);
unsigned int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi);
void *ipu3_css_fw_pipeline_params(struct ipu3_css *css,
enum imgu_abi_param_class c,
enum imgu_abi_memories m,
void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, unsigned int pipe,
enum imgu_abi_param_class cls,
enum imgu_abi_memories mem,
struct imgu_fw_isp_parameter *par,
size_t par_size, void *binary_params);
......
......@@ -4,16 +4,19 @@
#ifndef __IPU3_PARAMS_H
#define __IPU3_PARAMS_H
int ipu3_css_cfg_acc(struct ipu3_css *css, struct ipu3_uapi_flags *use,
int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe,
struct ipu3_uapi_flags *use,
struct imgu_abi_acc_param *acc,
struct imgu_abi_acc_param *acc_old,
struct ipu3_uapi_acc_param *acc_user);
int ipu3_css_cfg_vmem0(struct ipu3_css *css, struct ipu3_uapi_flags *use,
int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe,
struct ipu3_uapi_flags *use,
void *vmem0, void *vmem0_old,
struct ipu3_uapi_params *user);
int ipu3_css_cfg_dmem0(struct ipu3_css *css, struct ipu3_uapi_flags *use,
int ipu3_css_cfg_dmem0(struct ipu3_css *css, unsigned int pipe,
struct ipu3_uapi_flags *use,
void *dmem0, void *dmem0_old,
struct ipu3_uapi_params *user);
......
This diff is collapsed.
......@@ -13,6 +13,7 @@
/* 2 stages for split isp pipeline, 1 for scaling */
#define IMGU_NUM_SP 2
#define IMGU_MAX_PIPELINE_NUM 20
#define IMGU_MAX_PIPE_NUM 2
/* For DVS etc., format FRAME_FMT_YUV420_16 */
#define IPU3_CSS_AUX_FRAME_REF 0
......@@ -57,12 +58,6 @@ struct ipu3_css_resolution {
u32 h;
};
enum ipu3_css_vf_status {
IPU3_NODE_VF_ENABLED,
IPU3_NODE_PV_ENABLED,
IPU3_NODE_VF_DISABLED
};
enum ipu3_css_buffer_state {
IPU3_CSS_BUFFER_NEW, /* Not yet queued */
IPU3_CSS_BUFFER_QUEUED, /* Queued, waiting to be filled */
......@@ -77,6 +72,7 @@ struct ipu3_css_buffer {
enum ipu3_css_buffer_state state;
struct list_head list;
u8 queue_pos;
unsigned int pipe;
};
struct ipu3_css_format {
......@@ -100,33 +96,32 @@ struct ipu3_css_queue {
} fmt;
const struct ipu3_css_format *css_fmt;
unsigned int width_pad; /* bytesperline / byp */
unsigned int width_pad;
struct list_head bufs;
};
/* IPU3 Camera Sub System structure */
struct ipu3_css {
struct device *dev;
void __iomem *base;
const struct firmware *fw;
struct imgu_fw_header *fwp;
int iomem_length;
int fw_bl, fw_sp[IMGU_NUM_SP]; /* Indices of bl and SP binaries */
struct ipu3_css_map *binary; /* fw binaries mapped to device */
unsigned int current_binary; /* Currently selected binary */
bool streaming; /* true when streaming is enabled */
enum ipu3_css_pipe_id pipe_id; /* CSS pipe ID. */
struct ipu3_css_pipe {
enum ipu3_css_pipe_id pipe_id;
unsigned int bindex;
struct ipu3_css_queue queue[IPU3_CSS_QUEUES];
struct v4l2_rect rect[IPU3_CSS_RECTS];
bool vf_output_en;
/* Protect access to queue[IPU3_CSS_QUEUES] */
spinlock_t qlock;
/* Data structures shared with IMGU and driver, always allocated */
struct ipu3_css_map sp_ddr_ptrs;
struct ipu3_css_map xmem_sp_stage_ptrs[IPU3_CSS_PIPE_ID_NUM]
[IMGU_ABI_MAX_STAGES];
struct ipu3_css_map xmem_isp_stage_ptrs[IPU3_CSS_PIPE_ID_NUM]
[IMGU_ABI_MAX_STAGES];
struct ipu3_css_map sp_ddr_ptrs;
struct ipu3_css_map xmem_sp_group_ptrs;
/* Data structures shared with IMGU and driver, binary specific */
/* PARAM_CLASS_CONFIG and PARAM_CLASS_STATE parameters */
/*
* Data structures shared with IMGU and driver, binary specific.
* PARAM_CLASS_CONFIG and PARAM_CLASS_STATE parameters.
*/
struct ipu3_css_map binary_params_cs[IMGU_ABI_PARAM_CLASS_NUM - 1]
[IMGU_ABI_NUM_MEMORIES];
......@@ -138,11 +133,6 @@ struct ipu3_css {
unsigned int bytesperpixel;
} aux_frames[IPU3_CSS_AUX_FRAME_TYPES];
struct ipu3_css_queue queue[IPU3_CSS_QUEUES];
struct v4l2_rect rect[IPU3_CSS_RECTS];
struct ipu3_css_map abi_buffers[IPU3_CSS_QUEUES]
[IMGU_ABI_HOST2SP_BUFQ_SIZE];
struct {
struct ipu3_css_pool parameter_set_info;
struct ipu3_css_pool acc;
......@@ -152,9 +142,26 @@ struct ipu3_css {
struct ipu3_css_pool binary_params_p[IMGU_ABI_NUM_MEMORIES];
} pool;
enum ipu3_css_vf_status vf_output_en;
/* Protect access to css->queue[] */
spinlock_t qlock;
struct ipu3_css_map abi_buffers[IPU3_CSS_QUEUES]
[IMGU_ABI_HOST2SP_BUFQ_SIZE];
};
/* IPU3 Camera Sub System structure */
struct ipu3_css {
struct device *dev;
void __iomem *base;
const struct firmware *fw;
struct imgu_fw_header *fwp;
int iomem_length;
int fw_bl, fw_sp[IMGU_NUM_SP]; /* Indices of bl and SP binaries */
struct ipu3_css_map *binary; /* fw binaries mapped to device */
bool streaming; /* true when streaming is enabled */
struct ipu3_css_pipe pipes[IMGU_MAX_PIPE_NUM];
struct ipu3_css_map xmem_sp_group_ptrs;
/* enabled pipe(s) */
DECLARE_BITMAP(enabled_pipes, IMGU_MAX_PIPE_NUM);
};
/******************* css v4l *******************/
......@@ -163,17 +170,21 @@ int ipu3_css_init(struct device *dev, struct ipu3_css *css,
void ipu3_css_cleanup(struct ipu3_css *css);
int ipu3_css_fmt_try(struct ipu3_css *css,
struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES],
struct v4l2_rect *rects[IPU3_CSS_RECTS]);
struct v4l2_rect *rects[IPU3_CSS_RECTS],
unsigned int pipe);
int ipu3_css_fmt_set(struct ipu3_css *css,
struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES],
struct v4l2_rect *rects[IPU3_CSS_RECTS]);
struct v4l2_rect *rects[IPU3_CSS_RECTS],
unsigned int pipe);
int ipu3_css_meta_fmt_set(struct v4l2_meta_format *fmt);
int ipu3_css_buf_queue(struct ipu3_css *css, struct ipu3_css_buffer *b);
int ipu3_css_buf_queue(struct ipu3_css *css, unsigned int pipe,
struct ipu3_css_buffer *b);
struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css);
int ipu3_css_start_streaming(struct ipu3_css *css);
void ipu3_css_stop_streaming(struct ipu3_css *css);
bool ipu3_css_queue_empty(struct ipu3_css *css);
bool ipu3_css_is_streaming(struct ipu3_css *css);
bool ipu3_css_pipe_queue_empty(struct ipu3_css *css, unsigned int pipe);
/******************* css hw *******************/
int ipu3_css_set_powerup(struct device *dev, void __iomem *base);
......@@ -181,10 +192,10 @@ void ipu3_css_set_powerdown(struct device *dev, void __iomem *base);
int ipu3_css_irq_ack(struct ipu3_css *css);
/******************* set parameters ************/
int ipu3_css_set_parameters(struct ipu3_css *css,
int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe,
struct ipu3_uapi_params *set_params);
/******************* css misc *******************/
/******************* auxiliary helpers *******************/
static inline enum ipu3_css_buffer_state
ipu3_css_buf_state(struct ipu3_css_buffer *b)
{
......
This diff is collapsed.
This diff is collapsed.
......@@ -7,6 +7,7 @@
#include <linux/iova.h>
#include <linux/pci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/videobuf2-dma-sg.h>
......@@ -28,9 +29,8 @@
#define IMGU_NODE_PARAMS 1 /* Input parameters */
#define IMGU_NODE_OUT 2 /* Main output for still or video */
#define IMGU_NODE_VF 3 /* Preview */
#define IMGU_NODE_PV 4 /* Postview for still capture */
#define IMGU_NODE_STAT_3A 5 /* 3A statistics */
#define IMGU_NODE_NUM 6
#define IMGU_NODE_STAT_3A 4 /* 3A statistics */
#define IMGU_NODE_NUM 5
#define file_to_intel_ipu3_node(__file) \
container_of(video_devdata(__file), struct imgu_video_device, vdev)
......@@ -71,7 +71,6 @@ struct imgu_node_mapping {
struct imgu_video_device {
const char *name;
bool output;
bool immutable; /* Can not be enabled/disabled */
bool enabled;
struct v4l2_format vdev_fmt; /* Currently set format */
......@@ -84,14 +83,27 @@ struct imgu_video_device {
/* Protect vb2_queue and vdev structs*/
struct mutex lock;
atomic_t sequence;
unsigned int id;
unsigned int pipe;
};
/*
* imgu_device -- ImgU (Imaging Unit) driver
*/
struct imgu_device {
struct pci_dev *pci_dev;
void __iomem *base;
struct imgu_v4l2_subdev {
unsigned int pipe;
struct v4l2_subdev subdev;
struct media_pad subdev_pads[IMGU_NODE_NUM];
struct {
struct v4l2_rect eff; /* effective resolution */
struct v4l2_rect bds; /* bayer-domain scaled resolution*/
struct v4l2_rect gdc; /* gdc output resolution */
} rect;
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *ctrl;
atomic_t running_mode;
bool active;
};
struct imgu_media_pipe {
unsigned int pipe;
/* Internally enabled queues */
struct {
......@@ -100,18 +112,26 @@ struct imgu_device {
} queues[IPU3_CSS_QUEUES];
struct imgu_video_device nodes[IMGU_NODE_NUM];
bool queue_enabled[IMGU_NODE_NUM];
struct media_pipeline pipeline;
struct imgu_v4l2_subdev imgu_sd;
};
/*
* imgu_device -- ImgU (Imaging Unit) driver
*/
struct imgu_device {
struct pci_dev *pci_dev;
void __iomem *base;
/* Public fields, fill before registering */
unsigned int buf_struct_size;
bool streaming; /* Public read only */
struct v4l2_ctrl_handler *ctrl_handler;
struct imgu_media_pipe imgu_pipe[IMGU_MAX_PIPE_NUM];
/* Private fields */
struct v4l2_device v4l2_dev;
struct media_device media_dev;
struct media_pipeline pipeline;
struct v4l2_subdev subdev;
struct media_pad subdev_pads[IMGU_NODE_NUM];
struct v4l2_file_operations v4l2_file_ops;
/* MMU driver for css */
......@@ -128,11 +148,6 @@ struct imgu_device {
struct mutex lock;
/* Forbit streaming and buffer queuing during system suspend. */
atomic_t qbuf_barrier;
struct {
struct v4l2_rect eff; /* effective resolution */
struct v4l2_rect bds; /* bayer-domain scaled resolution*/
struct v4l2_rect gdc; /* gdc output resolution */
} rect;
/* Indicate if system suspend take place while imgu is streaming. */
bool suspend_in_stream;
/* Used to wait for FW buffer queue drain. */
......@@ -141,7 +156,8 @@ struct imgu_device {
unsigned int imgu_node_to_queue(unsigned int node);
unsigned int imgu_map_node(struct imgu_device *imgu, unsigned int css_queue);
int imgu_queue_buffers(struct imgu_device *imgu, bool initial);
int imgu_queue_buffers(struct imgu_device *imgu, bool initial,
unsigned int pipe);
int imgu_v4l2_register(struct imgu_device *dev);
int imgu_v4l2_unregister(struct imgu_device *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment