Commit df330515 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] v4l: xilinx: Add Xilinx Video IP core

Xilinx platforms have no hardwired video capture or video processing
interface. Users create capture and memory to memory processing
pipelines in the FPGA fabric to suit their particular needs, by
instantiating video IP cores from a large library.

The Xilinx Video IP core is a framework that models a video pipeline
described in the device tree and expose the pipeline to userspace
through the media controller and V4L2 APIs.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarHyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: default avatarRadhey Shyam Pandey <radheys@xilinx.com>
Signed-off-by: default avatarMichal Simek <michal.simek@xilinx.com>
Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent c9bca8b3
DT bindings for Xilinx video IP cores
-------------------------------------
Xilinx video IP cores process video streams by acting as video sinks and/or
sources. They are connected by links through their input and output ports,
creating a video pipeline.
Each video IP core is represented by an AMBA bus child node in the device
tree using bindings documented in this directory. Connections between the IP
cores are represented as defined in ../video-interfaces.txt.
The whole pipeline is represented by an AMBA bus child node in the device
tree using bindings documented in ./xlnx,video.txt.
Common properties
-----------------
The following properties are common to all Xilinx video IP cores.
- xlnx,video-format: This property represents a video format transmitted on an
AXI bus between video IP cores, using its VF code as defined in "AXI4-Stream
Video IP and System Design Guide" [UG934]. How the format relates to the IP
core is decribed in the IP core bindings documentation.
- xlnx,video-width: This property qualifies the video format with the sample
width expressed as a number of bits per pixel component. All components must
use the same width.
- xlnx,cfa-pattern: When the video format is set to Mono/Sensor, this property
describes the sensor's color filter array pattern. Supported values are
"bggr", "gbrg", "grbg", "rggb" and "mono". If not specified, the pattern
defaults to "mono".
[UG934] http://www.xilinx.com/support/documentation/ip_documentation/axi_videoip/v1_0/ug934_axi_videoIP.pdf
Xilinx Video IP Pipeline (VIPP)
-------------------------------
General concept
---------------
Xilinx video IP pipeline processes video streams through one or more Xilinx
video IP cores. Each video IP core is represented as documented in video.txt
and IP core specific documentation, xlnx,v-*.txt, in this directory. The DT
node of the VIPP represents as a top level node of the pipeline and defines
mappings between DMAs and the video IP cores.
Required properties:
- compatible: Must be "xlnx,video".
- dmas, dma-names: List of one DMA specifier and identifier string (as defined
in Documentation/devicetree/bindings/dma/dma.txt) per port. Each port
requires a DMA channel with the identifier string set to "port" followed by
the port index.
- ports: Video port, using the DT bindings defined in ../video-interfaces.txt.
Required port properties:
- direction: should be either "input" or "output" depending on the direction
of stream.
Example:
video_cap {
compatible = "xlnx,video";
dmas = <&vdma_1 1>, <&vdma_3 1>;
dma-names = "port0", "port1";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
direction = "input";
vcap0_in0: endpoint {
remote-endpoint = <&scaler0_out>;
};
};
port@1 {
reg = <1>;
direction = "input";
vcap0_in1: endpoint {
remote-endpoint = <&switch_out1>;
};
};
};
};
......@@ -10818,6 +10818,15 @@ L: linux-serial@vger.kernel.org
S: Maintained
F: drivers/tty/serial/uartlite.c
XILINX VIDEO IP CORES
M: Hyun Kwon <hyun.kwon@xilinx.com>
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
S: Supported
F: Documentation/devicetree/bindings/media/xilinx/
F: drivers/media/platform/xilinx/
XILLYBUS DRIVER
M: Eli Billauer <eli.billauer@gmail.com>
L: linux-kernel@vger.kernel.org
......
......@@ -118,6 +118,7 @@ source "drivers/media/platform/soc_camera/Kconfig"
source "drivers/media/platform/exynos4-is/Kconfig"
source "drivers/media/platform/s5p-tv/Kconfig"
source "drivers/media/platform/am437x/Kconfig"
source "drivers/media/platform/xilinx/Kconfig"
endif # V4L_PLATFORM_DRIVERS
......
......@@ -48,4 +48,6 @@ obj-y += omap/
obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/
obj-$(CONFIG_VIDEO_XILINX) += xilinx/
ccflags-y += -I$(srctree)/drivers/media/i2c
config VIDEO_XILINX
tristate "Xilinx Video IP (EXPERIMENTAL)"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
select VIDEOBUF2_DMA_CONTIG
---help---
Driver for Xilinx Video IP Pipelines
if VIDEO_XILINX
endif #VIDEO_XILINX
xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
This diff is collapsed.
/*
* Xilinx Video DMA
*
* Copyright (C) 2013-2015 Ideas on Board
* Copyright (C) 2013-2015 Xilinx, Inc.
*
* Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
* Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __XILINX_VIP_DMA_H__
#define __XILINX_VIP_DMA_H__
#include <linux/dmaengine.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/videodev2.h>
#include <media/media-entity.h>
#include <media/v4l2-dev.h>
#include <media/videobuf2-core.h>
struct dma_chan;
struct xvip_composite_device;
struct xvip_video_format;
/**
* struct xvip_pipeline - Xilinx Video IP pipeline structure
* @pipe: media pipeline
* @lock: protects the pipeline @stream_count
* @use_count: number of DMA engines using the pipeline
* @stream_count: number of DMA engines currently streaming
* @num_dmas: number of DMA engines in the pipeline
* @output: DMA engine at the output of the pipeline
*/
struct xvip_pipeline {
struct media_pipeline pipe;
struct mutex lock;
unsigned int use_count;
unsigned int stream_count;
unsigned int num_dmas;
struct xvip_dma *output;
};
static inline struct xvip_pipeline *to_xvip_pipeline(struct media_entity *e)
{
return container_of(e->pipe, struct xvip_pipeline, pipe);
}
/**
* struct xvip_dma - Video DMA channel
* @list: list entry in a composite device dmas list
* @video: V4L2 video device associated with the DMA channel
* @pad: media pad for the video device entity
* @xdev: composite device the DMA channel belongs to
* @pipe: pipeline belonging to the DMA channel
* @port: composite device DT node port number for the DMA channel
* @lock: protects the @format, @fmtinfo and @queue fields
* @format: active V4L2 pixel format
* @fmtinfo: format information corresponding to the active @format
* @queue: vb2 buffers queue
* @alloc_ctx: allocation context for the vb2 @queue
* @sequence: V4L2 buffers sequence number
* @queued_bufs: list of queued buffers
* @queued_lock: protects the buf_queued list
* @dma: DMA engine channel
* @align: transfer alignment required by the DMA channel (in bytes)
* @xt: dma interleaved template for dma configuration
* @sgl: data chunk structure for dma_interleaved_template
*/
struct xvip_dma {
struct list_head list;
struct video_device video;
struct media_pad pad;
struct xvip_composite_device *xdev;
struct xvip_pipeline pipe;
unsigned int port;
struct mutex lock;
struct v4l2_pix_format format;
const struct xvip_video_format *fmtinfo;
struct vb2_queue queue;
void *alloc_ctx;
unsigned int sequence;
struct list_head queued_bufs;
spinlock_t queued_lock;
struct dma_chan *dma;
unsigned int align;
struct dma_interleaved_template xt;
struct data_chunk sgl[1];
};
#define to_xvip_dma(vdev) container_of(vdev, struct xvip_dma, video)
int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
enum v4l2_buf_type type, unsigned int port);
void xvip_dma_cleanup(struct xvip_dma *dma);
#endif /* __XILINX_VIP_DMA_H__ */
/*
* Xilinx Video IP Core
*
* Copyright (C) 2013-2015 Ideas on Board
* Copyright (C) 2013-2015 Xilinx, Inc.
*
* Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
* Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <dt-bindings/media/xilinx-vip.h>
#include "xilinx-vip.h"
/* -----------------------------------------------------------------------------
* Helper functions
*/
static const struct xvip_video_format xvip_video_formats[] = {
{ XVIP_VF_YUV_422, 8, NULL, MEDIA_BUS_FMT_UYVY8_1X16,
2, V4L2_PIX_FMT_YUYV, "4:2:2, packed, YUYV" },
{ XVIP_VF_YUV_444, 8, NULL, MEDIA_BUS_FMT_VUY8_1X24,
3, V4L2_PIX_FMT_YUV444, "4:4:4, packed, YUYV" },
{ XVIP_VF_RBG, 8, NULL, MEDIA_BUS_FMT_RBG888_1X24,
3, 0, NULL },
{ XVIP_VF_MONO_SENSOR, 8, "mono", MEDIA_BUS_FMT_Y8_1X8,
1, V4L2_PIX_FMT_GREY, "Greyscale 8-bit" },
{ XVIP_VF_MONO_SENSOR, 8, "rggb", MEDIA_BUS_FMT_SRGGB8_1X8,
1, V4L2_PIX_FMT_SGRBG8, "Bayer 8-bit RGGB" },
{ XVIP_VF_MONO_SENSOR, 8, "grbg", MEDIA_BUS_FMT_SGRBG8_1X8,
1, V4L2_PIX_FMT_SGRBG8, "Bayer 8-bit GRBG" },
{ XVIP_VF_MONO_SENSOR, 8, "gbrg", MEDIA_BUS_FMT_SGBRG8_1X8,
1, V4L2_PIX_FMT_SGBRG8, "Bayer 8-bit GBRG" },
{ XVIP_VF_MONO_SENSOR, 8, "bggr", MEDIA_BUS_FMT_SBGGR8_1X8,
1, V4L2_PIX_FMT_SBGGR8, "Bayer 8-bit BGGR" },
};
/**
* xvip_get_format_by_code - Retrieve format information for a media bus code
* @code: the format media bus code
*
* Return: a pointer to the format information structure corresponding to the
* given V4L2 media bus format @code, or ERR_PTR if no corresponding format can
* be found.
*/
const struct xvip_video_format *xvip_get_format_by_code(unsigned int code)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
const struct xvip_video_format *format = &xvip_video_formats[i];
if (format->code == code)
return format;
}
return ERR_PTR(-EINVAL);
}
EXPORT_SYMBOL_GPL(xvip_get_format_by_code);
/**
* xvip_get_format_by_fourcc - Retrieve format information for a 4CC
* @fourcc: the format 4CC
*
* Return: a pointer to the format information structure corresponding to the
* given V4L2 format @fourcc, or ERR_PTR if no corresponding format can be
* found.
*/
const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
const struct xvip_video_format *format = &xvip_video_formats[i];
if (format->fourcc == fourcc)
return format;
}
return ERR_PTR(-EINVAL);
}
EXPORT_SYMBOL_GPL(xvip_get_format_by_fourcc);
/**
* xvip_of_get_format - Parse a device tree node and return format information
* @node: the device tree node
*
* Read the xlnx,video-format, xlnx,video-width and xlnx,cfa-pattern properties
* from the device tree @node passed as an argument and return the corresponding
* format information.
*
* Return: a pointer to the format information structure corresponding to the
* format name and width, or ERR_PTR if no corresponding format can be found.
*/
const struct xvip_video_format *xvip_of_get_format(struct device_node *node)
{
const char *pattern = "mono";
unsigned int vf_code;
unsigned int i;
u32 width;
int ret;
ret = of_property_read_u32(node, "xlnx,video-format", &vf_code);
if (ret < 0)
return ERR_PTR(ret);
ret = of_property_read_u32(node, "xlnx,video-width", &width);
if (ret < 0)
return ERR_PTR(ret);
if (vf_code == XVIP_VF_MONO_SENSOR)
of_property_read_string(node, "xlnx,cfa-pattern", &pattern);
for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
const struct xvip_video_format *format = &xvip_video_formats[i];
if (format->vf_code != vf_code || format->width != width)
continue;
if (vf_code == XVIP_VF_MONO_SENSOR &&
strcmp(pattern, format->pattern))
continue;
return format;
}
return ERR_PTR(-EINVAL);
}
EXPORT_SYMBOL_GPL(xvip_of_get_format);
/**
* xvip_set_format_size - Set the media bus frame format size
* @format: V4L2 frame format on media bus
* @fmt: media bus format
*
* Set the media bus frame format size. The width / height from the subdevice
* format are set to the given media bus format. The new format size is stored
* in @format. The width and height are clamped using default min / max values.
*/
void xvip_set_format_size(struct v4l2_mbus_framefmt *format,
const struct v4l2_subdev_format *fmt)
{
format->width = clamp_t(unsigned int, fmt->format.width,
XVIP_MIN_WIDTH, XVIP_MAX_WIDTH);
format->height = clamp_t(unsigned int, fmt->format.height,
XVIP_MIN_HEIGHT, XVIP_MAX_HEIGHT);
}
EXPORT_SYMBOL_GPL(xvip_set_format_size);
/**
* xvip_clr_or_set - Clear or set the register with a bitmask
* @xvip: Xilinx Video IP device
* @addr: address of register
* @mask: bitmask to be set or cleared
* @set: boolean flag indicating whether to set or clear
*
* Clear or set the register at address @addr with a bitmask @mask depending on
* the boolean flag @set. When the flag @set is true, the bitmask is set in
* the register, otherwise the bitmask is cleared from the register
* when the flag @set is false.
*
* Fox eample, this function can be used to set a control with a boolean value
* requested by users. If the caller knows whether to set or clear in the first
* place, the caller should call xvip_clr() or xvip_set() directly instead of
* using this function.
*/
void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set)
{
u32 reg;
reg = xvip_read(xvip, addr);
reg = set ? reg | mask : reg & ~mask;
xvip_write(xvip, addr, reg);
}
EXPORT_SYMBOL_GPL(xvip_clr_or_set);
/**
* xvip_clr_and_set - Clear and set the register with a bitmask
* @xvip: Xilinx Video IP device
* @addr: address of register
* @clr: bitmask to be cleared
* @set: bitmask to be set
*
* Clear a bit(s) of mask @clr in the register at address @addr, then set
* a bit(s) of mask @set in the register after.
*/
void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set)
{
u32 reg;
reg = xvip_read(xvip, addr);
reg &= ~clr;
reg |= set;
xvip_write(xvip, addr, reg);
}
EXPORT_SYMBOL_GPL(xvip_clr_and_set);
int xvip_init_resources(struct xvip_device *xvip)
{
struct platform_device *pdev = to_platform_device(xvip->dev);
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
xvip->iomem = devm_ioremap_resource(xvip->dev, res);
if (IS_ERR(xvip->iomem))
return PTR_ERR(xvip->iomem);
xvip->clk = devm_clk_get(xvip->dev, NULL);
if (IS_ERR(xvip->clk))
return PTR_ERR(xvip->clk);
clk_prepare_enable(xvip->clk);
return 0;
}
EXPORT_SYMBOL_GPL(xvip_init_resources);
void xvip_cleanup_resources(struct xvip_device *xvip)
{
clk_disable_unprepare(xvip->clk);
}
EXPORT_SYMBOL_GPL(xvip_cleanup_resources);
/* -----------------------------------------------------------------------------
* Subdev operations handlers
*/
/**
* xvip_enum_mbus_code - Enumerate the media format code
* @subdev: V4L2 subdevice
* @cfg: V4L2 subdev pad configuration
* @code: returning media bus code
*
* Enumerate the media bus code of the subdevice. Return the corresponding
* pad format code. This function only works for subdevices with fixed format
* on all pads. Subdevices with multiple format should have their own
* function to enumerate mbus codes.
*
* Return: 0 if the media bus code is found, or -EINVAL if the format index
* is not valid.
*/
int xvip_enum_mbus_code(struct v4l2_subdev *subdev,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code)
{
struct v4l2_mbus_framefmt *format;
/* Enumerating frame sizes based on the active configuration isn't
* supported yet.
*/
if (code->which == V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (code->index)
return -EINVAL;
format = v4l2_subdev_get_try_format(subdev, cfg, code->pad);
code->code = format->code;
return 0;
}
EXPORT_SYMBOL_GPL(xvip_enum_mbus_code);
/**
* xvip_enum_frame_size - Enumerate the media bus frame size
* @subdev: V4L2 subdevice
* @cfg: V4L2 subdev pad configuration
* @fse: returning media bus frame size
*
* This function is a drop-in implementation of the subdev enum_frame_size pad
* operation. It assumes that the subdevice has one sink pad and one source
* pad, and that the format on the source pad is always identical to the
* format on the sink pad. Entities with different requirements need to
* implement their own enum_frame_size handlers.
*
* Return: 0 if the media bus frame size is found, or -EINVAL
* if the index or the code is not valid.
*/
int xvip_enum_frame_size(struct v4l2_subdev *subdev,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse)
{
struct v4l2_mbus_framefmt *format;
/* Enumerating frame sizes based on the active configuration isn't
* supported yet.
*/
if (fse->which == V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad);
if (fse->index || fse->code != format->code)
return -EINVAL;
if (fse->pad == XVIP_PAD_SINK) {
fse->min_width = XVIP_MIN_WIDTH;
fse->max_width = XVIP_MAX_WIDTH;
fse->min_height = XVIP_MIN_HEIGHT;
fse->max_height = XVIP_MAX_HEIGHT;
} else {
/* The size on the source pad is fixed and always identical to
* the size on the sink pad.
*/
fse->min_width = format->width;
fse->max_width = format->width;
fse->min_height = format->height;
fse->max_height = format->height;
}
return 0;
}
EXPORT_SYMBOL_GPL(xvip_enum_frame_size);
/*
* Xilinx Video IP Core
*
* Copyright (C) 2013-2015 Ideas on Board
* Copyright (C) 2013-2015 Xilinx, Inc.
*
* Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
* Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __XILINX_VIP_H__
#define __XILINX_VIP_H__
#include <linux/io.h>
#include <media/v4l2-subdev.h>
struct clk;
/*
* Minimum and maximum width and height common to most video IP cores. IP
* cores with different requirements must define their own values.
*/
#define XVIP_MIN_WIDTH 32
#define XVIP_MAX_WIDTH 7680
#define XVIP_MIN_HEIGHT 32
#define XVIP_MAX_HEIGHT 7680
/*
* Pad IDs. IP cores with with multiple inputs or outputs should define
* their own values.
*/
#define XVIP_PAD_SINK 0
#define XVIP_PAD_SOURCE 1
/* Xilinx Video IP Control Registers */
#define XVIP_CTRL_CONTROL 0x0000
#define XVIP_CTRL_CONTROL_SW_ENABLE (1 << 0)
#define XVIP_CTRL_CONTROL_REG_UPDATE (1 << 1)
#define XVIP_CTRL_CONTROL_BYPASS (1 << 4)
#define XVIP_CTRL_CONTROL_TEST_PATTERN (1 << 5)
#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET (1 << 30)
#define XVIP_CTRL_CONTROL_SW_RESET (1 << 31)
#define XVIP_CTRL_STATUS 0x0004
#define XVIP_CTRL_STATUS_PROC_STARTED (1 << 0)
#define XVIP_CTRL_STATUS_EOF (1 << 1)
#define XVIP_CTRL_ERROR 0x0008
#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY (1 << 0)
#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE (1 << 1)
#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY (1 << 2)
#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE (1 << 3)
#define XVIP_CTRL_IRQ_ENABLE 0x000c
#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED (1 << 0)
#define XVIP_CTRL_IRQ_EOF (1 << 1)
#define XVIP_CTRL_VERSION 0x0010
#define XVIP_CTRL_VERSION_MAJOR_MASK (0xff << 24)
#define XVIP_CTRL_VERSION_MAJOR_SHIFT 24
#define XVIP_CTRL_VERSION_MINOR_MASK (0xff << 16)
#define XVIP_CTRL_VERSION_MINOR_SHIFT 16
#define XVIP_CTRL_VERSION_REVISION_MASK (0xf << 12)
#define XVIP_CTRL_VERSION_REVISION_SHIFT 12
#define XVIP_CTRL_VERSION_PATCH_MASK (0xf << 8)
#define XVIP_CTRL_VERSION_PATCH_SHIFT 8
#define XVIP_CTRL_VERSION_INTERNAL_MASK (0xff << 0)
#define XVIP_CTRL_VERSION_INTERNAL_SHIFT 0
/* Xilinx Video IP Timing Registers */
#define XVIP_ACTIVE_SIZE 0x0020
#define XVIP_ACTIVE_VSIZE_MASK (0x7ff << 16)
#define XVIP_ACTIVE_VSIZE_SHIFT 16
#define XVIP_ACTIVE_HSIZE_MASK (0x7ff << 0)
#define XVIP_ACTIVE_HSIZE_SHIFT 0
#define XVIP_ENCODING 0x0028
#define XVIP_ENCODING_NBITS_8 (0 << 4)
#define XVIP_ENCODING_NBITS_10 (1 << 4)
#define XVIP_ENCODING_NBITS_12 (2 << 4)
#define XVIP_ENCODING_NBITS_16 (3 << 4)
#define XVIP_ENCODING_NBITS_MASK (3 << 4)
#define XVIP_ENCODING_NBITS_SHIFT 4
#define XVIP_ENCODING_VIDEO_FORMAT_YUV422 (0 << 0)
#define XVIP_ENCODING_VIDEO_FORMAT_YUV444 (1 << 0)
#define XVIP_ENCODING_VIDEO_FORMAT_RGB (2 << 0)
#define XVIP_ENCODING_VIDEO_FORMAT_YUV420 (3 << 0)
#define XVIP_ENCODING_VIDEO_FORMAT_MASK (3 << 0)
#define XVIP_ENCODING_VIDEO_FORMAT_SHIFT 0
/**
* struct xvip_device - Xilinx Video IP device structure
* @subdev: V4L2 subdevice
* @dev: (OF) device
* @iomem: device I/O register space remapped to kernel virtual memory
* @clk: video core clock
* @saved_ctrl: saved control register for resume / suspend
*/
struct xvip_device {
struct v4l2_subdev subdev;
struct device *dev;
void __iomem *iomem;
struct clk *clk;
u32 saved_ctrl;
};
/**
* struct xvip_video_format - Xilinx Video IP video format description
* @vf_code: AXI4 video format code
* @width: AXI4 format width in bits per component
* @pattern: CFA pattern for Mono/Sensor formats
* @code: media bus format code
* @bpp: bytes per pixel (when stored in memory)
* @fourcc: V4L2 pixel format FCC identifier
* @description: format description, suitable for userspace
*/
struct xvip_video_format {
unsigned int vf_code;
unsigned int width;
const char *pattern;
unsigned int code;
unsigned int bpp;
u32 fourcc;
const char *description;
};
const struct xvip_video_format *xvip_get_format_by_code(unsigned int code);
const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc);
const struct xvip_video_format *xvip_of_get_format(struct device_node *node);
void xvip_set_format_size(struct v4l2_mbus_framefmt *format,
const struct v4l2_subdev_format *fmt);
int xvip_enum_mbus_code(struct v4l2_subdev *subdev,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code);
int xvip_enum_frame_size(struct v4l2_subdev *subdev,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse);
static inline u32 xvip_read(struct xvip_device *xvip, u32 addr)
{
return ioread32(xvip->iomem + addr);
}
static inline void xvip_write(struct xvip_device *xvip, u32 addr, u32 value)
{
iowrite32(value, xvip->iomem + addr);
}
static inline void xvip_clr(struct xvip_device *xvip, u32 addr, u32 clr)
{
xvip_write(xvip, addr, xvip_read(xvip, addr) & ~clr);
}
static inline void xvip_set(struct xvip_device *xvip, u32 addr, u32 set)
{
xvip_write(xvip, addr, xvip_read(xvip, addr) | set);
}
void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set);
void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set);
int xvip_init_resources(struct xvip_device *xvip);
void xvip_cleanup_resources(struct xvip_device *xvip);
static inline void xvip_reset(struct xvip_device *xvip)
{
xvip_write(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_RESET);
}
static inline void xvip_start(struct xvip_device *xvip)
{
xvip_set(xvip, XVIP_CTRL_CONTROL,
XVIP_CTRL_CONTROL_SW_ENABLE | XVIP_CTRL_CONTROL_REG_UPDATE);
}
static inline void xvip_stop(struct xvip_device *xvip)
{
xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_ENABLE);
}
static inline void xvip_resume(struct xvip_device *xvip)
{
xvip_write(xvip, XVIP_CTRL_CONTROL,
xvip->saved_ctrl | XVIP_CTRL_CONTROL_SW_ENABLE);
}
static inline void xvip_suspend(struct xvip_device *xvip)
{
xvip->saved_ctrl = xvip_read(xvip, XVIP_CTRL_CONTROL);
xvip_write(xvip, XVIP_CTRL_CONTROL,
xvip->saved_ctrl & ~XVIP_CTRL_CONTROL_SW_ENABLE);
}
static inline void xvip_set_frame_size(struct xvip_device *xvip,
const struct v4l2_mbus_framefmt *format)
{
xvip_write(xvip, XVIP_ACTIVE_SIZE,
(format->height << XVIP_ACTIVE_VSIZE_SHIFT) |
(format->width << XVIP_ACTIVE_HSIZE_SHIFT));
}
static inline void xvip_get_frame_size(struct xvip_device *xvip,
struct v4l2_mbus_framefmt *format)
{
u32 reg;
reg = xvip_read(xvip, XVIP_ACTIVE_SIZE);
format->width = (reg & XVIP_ACTIVE_HSIZE_MASK) >>
XVIP_ACTIVE_HSIZE_SHIFT;
format->height = (reg & XVIP_ACTIVE_VSIZE_MASK) >>
XVIP_ACTIVE_VSIZE_SHIFT;
}
static inline void xvip_enable_reg_update(struct xvip_device *xvip)
{
xvip_set(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE);
}
static inline void xvip_disable_reg_update(struct xvip_device *xvip)
{
xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE);
}
static inline void xvip_print_version(struct xvip_device *xvip)
{
u32 version;
version = xvip_read(xvip, XVIP_CTRL_VERSION);
dev_info(xvip->dev, "device found, version %u.%02x%x\n",
((version & XVIP_CTRL_VERSION_MAJOR_MASK) >>
XVIP_CTRL_VERSION_MAJOR_SHIFT),
((version & XVIP_CTRL_VERSION_MINOR_MASK) >>
XVIP_CTRL_VERSION_MINOR_SHIFT),
((version & XVIP_CTRL_VERSION_REVISION_MASK) >>
XVIP_CTRL_VERSION_REVISION_SHIFT));
}
#endif /* __XILINX_VIP_H__ */
This diff is collapsed.
/*
* Xilinx Video IP Composite Device
*
* Copyright (C) 2013-2015 Ideas on Board
* Copyright (C) 2013-2015 Xilinx, Inc.
*
* Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
* Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __XILINX_VIPP_H__
#define __XILINX_VIPP_H__
#include <linux/list.h>
#include <linux/mutex.h>
#include <media/media-device.h>
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
/**
* struct xvip_composite_device - Xilinx Video IP device structure
* @v4l2_dev: V4L2 device
* @media_dev: media device
* @dev: (OF) device
* @notifier: V4L2 asynchronous subdevs notifier
* @entities: entities in the graph as a list of xvip_graph_entity
* @num_subdevs: number of subdevs in the pipeline
* @dmas: list of DMA channels at the pipeline output and input
* @v4l2_caps: V4L2 capabilities of the whole device (see VIDIOC_QUERYCAP)
*/
struct xvip_composite_device {
struct v4l2_device v4l2_dev;
struct media_device media_dev;
struct device *dev;
struct v4l2_async_notifier notifier;
struct list_head entities;
unsigned int num_subdevs;
struct list_head dmas;
u32 v4l2_caps;
};
#endif /* __XILINX_VIPP_H__ */
/*
* Xilinx Video IP Core
*
* Copyright (C) 2013-2015 Ideas on Board
* Copyright (C) 2013-2015 Xilinx, Inc.
*
* Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
* Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __DT_BINDINGS_MEDIA_XILINX_VIP_H__
#define __DT_BINDINGS_MEDIA_XILINX_VIP_H__
/*
* Video format codes as defined in "AXI4-Stream Video IP and System Design
* Guide".
*/
#define XVIP_VF_YUV_422 0
#define XVIP_VF_YUV_444 1
#define XVIP_VF_RBG 2
#define XVIP_VF_YUV_420 3
#define XVIP_VF_YUVA_422 4
#define XVIP_VF_YUVA_444 5
#define XVIP_VF_RGBA 6
#define XVIP_VF_YUVA_420 7
#define XVIP_VF_YUVD_422 8
#define XVIP_VF_YUVD_444 9
#define XVIP_VF_RGBD 10
#define XVIP_VF_YUVD_420 11
#define XVIP_VF_MONO_SENSOR 12
#define XVIP_VF_CUSTOM2 13
#define XVIP_VF_CUSTOM3 14
#define XVIP_VF_CUSTOM4 15
#endif /* __DT_BINDINGS_MEDIA_XILINX_VIP_H__ */
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