Commit 9ffc30a6 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'tegra-for-5.8-media' of...

Merge tag 'tegra-for-5.8-media' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into arm/drivers

media: tegra: Changes for v5.8-rc1

This contains a V4L2 video capture driver for Tegra210.

* tag 'tegra-for-5.8-media' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  media: tegra-video: Do not enable COMPILE_TEST
  MAINTAINERS: correct path in TEGRA VIDEO DRIVER
  media: tegra-video: Make tegra210_video_formats static
  MAINTAINERS: Add Tegra Video driver section
  media: tegra-video: Add Tegra210 Video input driver
  dt-bindings: i2c: tegra: Document Tegra210 VI I2C
  dt-bindings: tegra: Add VI and CSI bindings
  dt-bindings: cpufreq: Add binding for NVIDIA Tegra20/30
  dt-bindings: memory: tegra: Add external memory controller binding for Tegra210
  dt-bindings: clock: tegra: Remove PMC clock IDs
  dt-bindings: clock: tegra: Add clock ID for CSI TPG clock

Link: https://lore.kernel.org/r/20200515145311.1580134-7-thierry.reding@gmail.comSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 19207ea8 ba8f6682
Binding for NVIDIA Tegra20 CPUFreq
==================================
Required properties:
- clocks: Must contain an entry for the CPU clock.
See ../clocks/clock-bindings.txt for details.
- operating-points-v2: See ../bindings/opp/opp.txt for details.
- #cooling-cells: Should be 2. See ../thermal/thermal.txt for details.
For each opp entry in 'operating-points-v2' table:
- opp-supported-hw: Two bitfields indicating:
On Tegra20:
1. CPU process ID mask
2. SoC speedo ID mask
On Tegra30:
1. CPU process ID mask
2. CPU speedo ID mask
A bitwise AND is performed against these values and if any bit
matches, the OPP gets enabled.
- opp-microvolt: CPU voltage triplet.
Optional properties:
- cpu-supply: Phandle to the CPU power supply.
Example:
regulators {
cpu_reg: regulator0 {
regulator-name = "vdd_cpu";
};
};
cpu0_opp_table: opp_table0 {
compatible = "operating-points-v2";
opp@456000000 {
clock-latency-ns = <125000>;
opp-microvolt = <825000 825000 1125000>;
opp-supported-hw = <0x03 0x0001>;
opp-hz = /bits/ 64 <456000000>;
};
...
};
cpus {
cpu@0 {
compatible = "arm,cortex-a9";
clocks = <&tegra_car TEGRA20_CLK_CCLK>;
operating-points-v2 = <&cpu0_opp_table>;
cpu-supply = <&cpu_reg>;
#cooling-cells = <2>;
};
};
...@@ -40,14 +40,30 @@ of the following host1x client modules: ...@@ -40,14 +40,30 @@ of the following host1x client modules:
Required properties: Required properties:
- compatible: "nvidia,tegra<chip>-vi" - compatible: "nvidia,tegra<chip>-vi"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller registers.
- interrupts: The interrupt outputs from the controller. - interrupts: The interrupt outputs from the controller.
- clocks: Must contain one entry, for the module clock. - clocks: clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details. See ../clocks/clock-bindings.txt for details.
- resets: Must contain an entry for each entry in reset-names. - Tegra20/Tegra30/Tegra114/Tegra124:
See ../reset/reset.txt for details. - resets: Must contain an entry for each entry in reset-names.
- reset-names: Must include the following entries: See ../reset/reset.txt for details.
- vi - reset-names: Must include the following entries:
- vi
- Tegra210:
- power-domains: Must include venc powergate node as vi is in VE partition.
- Tegra210 has CSI part of VI sharing same host interface and register space.
So, VI device node should have CSI child node.
- csi: mipi csi interface to vi
Required properties:
- compatible: "nvidia,tegra210-csi"
- reg: Physical base address offset to parent and length of the controller
registers.
- clocks: Must contain entries csi, cilab, cilcd, cile, csi_tpg clocks.
See ../clocks/clock-bindings.txt for details.
- power-domains: Must include sor powergate node as csicil is in
SOR partition.
- epp: encoder pre-processor - epp: encoder pre-processor
...@@ -309,13 +325,44 @@ Example: ...@@ -309,13 +325,44 @@ Example:
reset-names = "mpe"; reset-names = "mpe";
}; };
vi { vi@54080000 {
compatible = "nvidia,tegra20-vi"; compatible = "nvidia,tegra210-vi";
reg = <0x54080000 0x00040000>; reg = <0x0 0x54080000 0x0 0x700>;
interrupts = <0 69 0x04>; interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA20_CLK_VI>; assigned-clocks = <&tegra_car TEGRA210_CLK_VI>;
resets = <&tegra_car 100>; assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
reset-names = "vi";
clocks = <&tegra_car TEGRA210_CLK_VI>;
power-domains = <&pd_venc>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x0 0x54080000 0x2000>;
csi@838 {
compatible = "nvidia,tegra210-csi";
reg = <0x838 0x1300>;
assigned-clocks = <&tegra_car TEGRA210_CLK_CILAB>,
<&tegra_car TEGRA210_CLK_CILCD>,
<&tegra_car TEGRA210_CLK_CILE>,
<&tegra_car TEGRA210_CLK_CSI_TPG>;
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_P>,
<&tegra_car TEGRA210_CLK_PLL_P>,
<&tegra_car TEGRA210_CLK_PLL_P>;
assigned-clock-rates = <102000000>,
<102000000>,
<102000000>,
<972000000>;
clocks = <&tegra_car TEGRA210_CLK_CSI>,
<&tegra_car TEGRA210_CLK_CILAB>,
<&tegra_car TEGRA210_CLK_CILCD>,
<&tegra_car TEGRA210_CLK_CILE>,
<&tegra_car TEGRA210_CLK_CSI_TPG>;
clock-names = "csi", "cilab", "cilcd", "cile", "csi_tpg";
power-domains = <&pd_sor>;
};
}; };
epp { epp {
......
...@@ -35,6 +35,12 @@ Required properties: ...@@ -35,6 +35,12 @@ Required properties:
Due to above changes, Tegra114 I2C driver makes incompatible with Due to above changes, Tegra114 I2C driver makes incompatible with
previous hardware driver. Hence, tegra114 I2C controller is compatible previous hardware driver. Hence, tegra114 I2C controller is compatible
with "nvidia,tegra114-i2c". with "nvidia,tegra114-i2c".
nvidia,tegra210-i2c-vi: Tegra210 has one I2C controller that is part of the
host1x domain and typically used for camera use-cases. This VI I2C
controller is mostly compatible with the programming model of the
regular I2C controllers with a few exceptions. The I2C registers start
at an offset of 0xc00 (instead of 0), registers are 16 bytes apart
(rather than 4) and the controller does not support slave mode.
- reg: Should contain I2C controller registers physical address and length. - reg: Should contain I2C controller registers physical address and length.
- interrupts: Should contain I2C controller interrupts. - interrupts: Should contain I2C controller interrupts.
- address-cells: Address cells for I2C device address. - address-cells: Address cells for I2C device address.
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra210-emc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVIDIA Tegra210 SoC External Memory Controller
maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
description: |
The EMC interfaces with the off-chip SDRAM to service the request stream
sent from the memory controller.
properties:
compatible:
const: nvidia,tegra210-emc
reg:
maxItems: 3
clocks:
items:
- description: external memory clock
clock-names:
items:
- const: emc
interrupts:
items:
- description: EMC general interrupt
memory-region:
$ref: /schemas/types.yaml#/definitions/phandle
description:
phandle to a reserved memory region describing the table of EMC
frequencies trained by the firmware
nvidia,memory-controller:
$ref: /schemas/types.yaml#/definitions/phandle
description:
phandle of the memory controller node
required:
- compatible
- reg
- clocks
- clock-names
- nvidia,memory-controller
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/tegra210-car.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
emc_table: emc-table@83400000 {
compatible = "nvidia,tegra210-emc-table";
reg = <0x83400000 0x10000>;
};
};
external-memory-controller@7001b000 {
compatible = "nvidia,tegra210-emc";
reg = <0x7001b000 0x1000>,
<0x7001e000 0x1000>,
<0x7001f000 0x1000>;
clocks = <&tegra_car TEGRA210_CLK_EMC>;
clock-names = "emc";
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&emc_table>;
nvidia,memory-controller = <&mc>;
};
...@@ -16598,6 +16598,16 @@ M: Laxman Dewangan <ldewangan@nvidia.com> ...@@ -16598,6 +16598,16 @@ M: Laxman Dewangan <ldewangan@nvidia.com>
S: Supported S: Supported
F: drivers/spi/spi-tegra* F: drivers/spi/spi-tegra*
TEGRA VIDEO DRIVER
M: Thierry Reding <thierry.reding@gmail.com>
M: Jonathan Hunter <jonathanh@nvidia.com>
M: Sowjanya Komatineni <skomatineni@nvidia.com>
L: linux-media@vger.kernel.org
L: linux-tegra@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
F: drivers/staging/media/tegra-video/
TEGRA XUSB PADCTL DRIVER TEGRA XUSB PADCTL DRIVER
M: JC Kuo <jckuo@nvidia.com> M: JC Kuo <jckuo@nvidia.com>
S: Supported S: Supported
......
...@@ -34,6 +34,8 @@ source "drivers/staging/media/sunxi/Kconfig" ...@@ -34,6 +34,8 @@ source "drivers/staging/media/sunxi/Kconfig"
source "drivers/staging/media/tegra-vde/Kconfig" source "drivers/staging/media/tegra-vde/Kconfig"
source "drivers/staging/media/tegra-video/Kconfig"
source "drivers/staging/media/ipu3/Kconfig" source "drivers/staging/media/ipu3/Kconfig"
source "drivers/staging/media/soc_camera/Kconfig" source "drivers/staging/media/soc_camera/Kconfig"
......
...@@ -4,6 +4,7 @@ obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/ ...@@ -4,6 +4,7 @@ obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/
obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/ obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/
obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ obj-$(CONFIG_VIDEO_SUNXI) += sunxi/
obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/
obj-$(CONFIG_TEGRA_VDE) += tegra-vde/ obj-$(CONFIG_TEGRA_VDE) += tegra-vde/
obj-$(CONFIG_VIDEO_HANTRO) += hantro/ obj-$(CONFIG_VIDEO_HANTRO) += hantro/
obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/
......
# SPDX-License-Identifier: GPL-2.0-only
config VIDEO_TEGRA
tristate "NVIDIA Tegra VI driver"
depends on TEGRA_HOST1X
select VIDEO_V4L2
select MEDIA_CONTROLLER
select VIDEOBUF2_DMA_CONTIG
help
Choose this option if you have an NVIDIA Tegra SoC.
To compile this driver as a module, choose M here: the module
will be called tegra-video.
# SPDX-License-Identifier: GPL-2.0
tegra-video-objs := \
video.o \
vi.o \
csi.o
tegra-video-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
obj-$(CONFIG_VIDEO_TEGRA) += tegra-video.o
TODO list
* Currently driver supports Tegra build-in TPG only with direct media links
from CSI to VI. Add kernel config CONFIG_VIDEO_TEGRA_TPG and update the
driver to do TPG Vs Sensor media links based on CONFIG_VIDEO_TEGRA_TPG.
* Add real camera sensor capture support.
* Add Tegra CSI MIPI pads calibration.
* Add MIPI clock Settle time computation based on the data rate.
* Add support for Ganged mode.
* Add RAW10 packed video format support to Tegra210 video formats.
* Add support for suspend and resume.
* Make sure v4l2-compliance tests pass with all of the above implementations.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 NVIDIA CORPORATION. All rights reserved.
*/
#ifndef __TEGRA_CSI_H__
#define __TEGRA_CSI_H__
#include <media/media-entity.h>
#include <media/v4l2-subdev.h>
/*
* Each CSI brick supports max of 4 lanes that can be used as either
* one x4 port using both CILA and CILB partitions of a CSI brick or can
* be used as two x2 ports with one x2 from CILA and the other x2 from
* CILB.
*/
#define CSI_PORTS_PER_BRICK 2
/* each CSI channel can have one sink and one source pads */
#define TEGRA_CSI_PADS_NUM 2
enum tegra_csi_cil_port {
PORT_A = 0,
PORT_B,
};
enum tegra_csi_block {
CSI_CIL_AB = 0,
CSI_CIL_CD,
CSI_CIL_EF,
};
struct tegra_csi;
/**
* struct tegra_csi_channel - Tegra CSI channel
*
* @list: list head for this entry
* @subdev: V4L2 subdevice associated with this channel
* @pads: media pads for the subdevice entity
* @numpads: number of pads.
* @csi: Tegra CSI device structure
* @of_node: csi device tree node
* @numlanes: number of lanes used per port/channel
* @csi_port_num: CSI channel port number
* @pg_mode: test pattern generator mode for channel
* @format: active format of the channel
* @framerate: active framerate for TPG
* @h_blank: horizontal blanking for TPG active format
* @v_blank: vertical blanking for TPG active format
*/
struct tegra_csi_channel {
struct list_head list;
struct v4l2_subdev subdev;
struct media_pad pads[TEGRA_CSI_PADS_NUM];
unsigned int numpads;
struct tegra_csi *csi;
struct device_node *of_node;
unsigned int numlanes;
u8 csi_port_num;
u8 pg_mode;
struct v4l2_mbus_framefmt format;
unsigned int framerate;
unsigned int h_blank;
unsigned int v_blank;
};
/**
* struct tpg_framerate - Tegra CSI TPG framerate configuration
*
* @frmsize: frame resolution
* @code: media bus format code
* @h_blank: horizontal blanking used for TPG
* @v_blank: vertical blanking interval used for TPG
* @framerate: framerate achieved with the corresponding blanking intervals,
* format and resolution.
*/
struct tpg_framerate {
struct v4l2_frmsize_discrete frmsize;
u32 code;
unsigned int h_blank;
unsigned int v_blank;
unsigned int framerate;
};
/**
* struct tegra_csi_ops - Tegra CSI operations
*
* @csi_start_streaming: programs csi hardware to enable streaming.
* @csi_stop_streaming: programs csi hardware to disable streaming.
* @csi_err_recover: csi hardware block recovery in case of any capture errors
* due to missing source stream or due to improper csi input from
* the external source.
*/
struct tegra_csi_ops {
int (*csi_start_streaming)(struct tegra_csi_channel *csi_chan);
void (*csi_stop_streaming)(struct tegra_csi_channel *csi_chan);
void (*csi_err_recover)(struct tegra_csi_channel *csi_chan);
};
/**
* struct tegra_csi_soc - NVIDIA Tegra CSI SoC structure
*
* @ops: csi hardware operations
* @csi_max_channels: supported max streaming channels
* @clk_names: csi and cil clock names
* @num_clks: total clocks count
* @tpg_frmrate_table: csi tpg frame rate table with blanking intervals
* @tpg_frmrate_table_size: size of frame rate table
*/
struct tegra_csi_soc {
const struct tegra_csi_ops *ops;
unsigned int csi_max_channels;
const char * const *clk_names;
unsigned int num_clks;
const struct tpg_framerate *tpg_frmrate_table;
unsigned int tpg_frmrate_table_size;
};
/**
* struct tegra_csi - NVIDIA Tegra CSI device structure
*
* @dev: device struct
* @client: host1x_client struct
* @iomem: register base
* @clks: clock for CSI and CIL
* @soc: pointer to SoC data structure
* @ops: csi operations
* @channels: list head for CSI channels
*/
struct tegra_csi {
struct device *dev;
struct host1x_client client;
void __iomem *iomem;
struct clk_bulk_data *clks;
const struct tegra_csi_soc *soc;
const struct tegra_csi_ops *ops;
struct list_head csi_chans;
};
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
extern const struct tegra_csi_soc tegra210_csi_soc;
#endif
void tegra_csi_error_recover(struct v4l2_subdev *subdev);
#endif
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 NVIDIA CORPORATION. All rights reserved.
*/
#ifndef __TEGRA_VI_H__
#define __TEGRA_VI_H__
#include <linux/host1x.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <media/media-entity.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-subdev.h>
#include <media/videobuf2-v4l2.h>
#define TEGRA_MIN_WIDTH 32U
#define TEGRA_MAX_WIDTH 32768U
#define TEGRA_MIN_HEIGHT 32U
#define TEGRA_MAX_HEIGHT 32768U
#define TEGRA_DEF_WIDTH 1920
#define TEGRA_DEF_HEIGHT 1080
#define TEGRA_IMAGE_FORMAT_DEF 32
#define MAX_FORMAT_NUM 64
enum tegra_vi_pg_mode {
TEGRA_VI_PG_DISABLED = 0,
TEGRA_VI_PG_DIRECT,
TEGRA_VI_PG_PATCH,
};
/**
* struct tegra_vi_ops - Tegra VI operations
* @vi_start_streaming: starts media pipeline, subdevice streaming, sets up
* VI for capture and runs capture start and capture finish
* kthreads for capturing frames to buffer and returns them back.
* @vi_stop_streaming: stops media pipeline and subdevice streaming and returns
* back any queued buffers.
*/
struct tegra_vi_ops {
int (*vi_start_streaming)(struct vb2_queue *vq, u32 count);
void (*vi_stop_streaming)(struct vb2_queue *vq);
};
/**
* struct tegra_vi_soc - NVIDIA Tegra Video Input SoC structure
*
* @video_formats: supported video formats
* @nformats: total video formats
* @ops: vi operations
* @hw_revision: VI hw_revision
* @vi_max_channels: supported max streaming channels
* @vi_max_clk_hz: VI clock max frequency
*/
struct tegra_vi_soc {
const struct tegra_video_format *video_formats;
const unsigned int nformats;
const struct tegra_vi_ops *ops;
u32 hw_revision;
unsigned int vi_max_channels;
unsigned int vi_max_clk_hz;
};
/**
* struct tegra_vi - NVIDIA Tegra Video Input device structure
*
* @dev: device struct
* @client: host1x_client struct
* @iomem: register base
* @clk: main clock for VI block
* @vdd: vdd regulator for VI hardware, normally it is avdd_dsi_csi
* @soc: pointer to SoC data structure
* @ops: vi operations
* @vi_chans: list head for VI channels
*/
struct tegra_vi {
struct device *dev;
struct host1x_client client;
void __iomem *iomem;
struct clk *clk;
struct regulator *vdd;
const struct tegra_vi_soc *soc;
const struct tegra_vi_ops *ops;
struct list_head vi_chans;
};
/**
* struct tegra_vi_channel - Tegra video channel
*
* @list: list head for this entry
* @video: V4L2 video device associated with the video channel
* @video_lock: protects the @format and @queue fields
* @pad: media pad for the video device entity
*
* @vi: Tegra video input device structure
* @frame_start_sp: host1x syncpoint pointer to synchronize programmed capture
* start condition with hardware frame start events through host1x
* syncpoint counters.
* @mw_ack_sp: host1x syncpoint pointer to synchronize programmed memory write
* ack trigger condition with hardware memory write done at end of
* frame through host1x syncpoint counters.
* @sp_incr_lock: protects cpu syncpoint increment.
*
* @kthread_start_capture: kthread to start capture of single frame when
* vb buffer is available. This thread programs VI CSI hardware
* for single frame capture and waits for frame start event from
* the hardware. On receiving frame start event, it wakes up
* kthread_finish_capture thread to wait for finishing frame data
* write to the memory. In case of missing frame start event, this
* thread returns buffer back to vb with VB2_BUF_STATE_ERROR.
* @start_wait: waitqueue for starting frame capture when buffer is available.
* @kthread_finish_capture: kthread to finish the buffer capture and return to.
* This thread is woken up by kthread_start_capture on receiving
* frame start event from the hardware and this thread waits for
* MW_ACK_DONE event which indicates completion of writing frame
* data to the memory. On receiving MW_ACK_DONE event, buffer is
* returned back to vb with VB2_BUF_STATE_DONE and in case of
* missing MW_ACK_DONE event, buffer is returned back to vb with
* VB2_BUF_STATE_ERROR.
* @done_wait: waitqueue for finishing capture data writes to memory.
*
* @format: active V4L2 pixel format
* @fmtinfo: format information corresponding to the active @format
* @queue: vb2 buffers queue
* @sequence: V4L2 buffers sequence number
*
* @capture: list of queued buffers for capture
* @start_lock: protects the capture queued list
* @done: list of capture done queued buffers
* @done_lock: protects the capture done queue list
*
* @portno: VI channel port number
*
* @ctrl_handler: V4L2 control handler of this video channel
* @tpg_fmts_bitmap: a bitmap for supported TPG formats
* @pg_mode: test pattern generator mode (disabled/direct/patch)
*/
struct tegra_vi_channel {
struct list_head list;
struct video_device video;
/* protects the @format and @queue fields */
struct mutex video_lock;
struct media_pad pad;
struct tegra_vi *vi;
struct host1x_syncpt *frame_start_sp;
struct host1x_syncpt *mw_ack_sp;
/* protects the cpu syncpoint increment */
spinlock_t sp_incr_lock;
struct task_struct *kthread_start_capture;
wait_queue_head_t start_wait;
struct task_struct *kthread_finish_capture;
wait_queue_head_t done_wait;
struct v4l2_pix_format format;
const struct tegra_video_format *fmtinfo;
struct vb2_queue queue;
u32 sequence;
struct list_head capture;
/* protects the capture queued list */
spinlock_t start_lock;
struct list_head done;
/* protects the capture done queue list */
spinlock_t done_lock;
unsigned char portno;
struct v4l2_ctrl_handler ctrl_handler;
DECLARE_BITMAP(tpg_fmts_bitmap, MAX_FORMAT_NUM);
enum tegra_vi_pg_mode pg_mode;
};
/**
* struct tegra_channel_buffer - video channel buffer
*
* @buf: vb2 buffer base object
* @queue: buffer list entry in the channel queued buffers list
* @chan: channel that uses the buffer
* @addr: Tegra IOVA buffer address for VI output
* @mw_ack_sp_thresh: MW_ACK_DONE syncpoint threshold corresponding
* to the capture buffer.
*/
struct tegra_channel_buffer {
struct vb2_v4l2_buffer buf;
struct list_head queue;
struct tegra_vi_channel *chan;
dma_addr_t addr;
u32 mw_ack_sp_thresh;
};
/*
* VI channel input data type enum.
* These data type enum value gets programmed into corresponding Tegra VI
* channel register bits.
*/
enum tegra_image_dt {
TEGRA_IMAGE_DT_YUV420_8 = 24,
TEGRA_IMAGE_DT_YUV420_10,
TEGRA_IMAGE_DT_YUV420CSPS_8 = 28,
TEGRA_IMAGE_DT_YUV420CSPS_10,
TEGRA_IMAGE_DT_YUV422_8,
TEGRA_IMAGE_DT_YUV422_10,
TEGRA_IMAGE_DT_RGB444,
TEGRA_IMAGE_DT_RGB555,
TEGRA_IMAGE_DT_RGB565,
TEGRA_IMAGE_DT_RGB666,
TEGRA_IMAGE_DT_RGB888,
TEGRA_IMAGE_DT_RAW6 = 40,
TEGRA_IMAGE_DT_RAW7,
TEGRA_IMAGE_DT_RAW8,
TEGRA_IMAGE_DT_RAW10,
TEGRA_IMAGE_DT_RAW12,
TEGRA_IMAGE_DT_RAW14,
};
/**
* struct tegra_video_format - Tegra video format description
*
* @img_dt: image data type
* @bit_width: format width in bits per component
* @code: media bus format code
* @bpp: bytes per pixel (when stored in memory)
* @img_fmt: image format
* @fourcc: V4L2 pixel format FCC identifier
*/
struct tegra_video_format {
enum tegra_image_dt img_dt;
unsigned int bit_width;
unsigned int code;
unsigned int bpp;
u32 img_fmt;
u32 fourcc;
};
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
extern const struct tegra_vi_soc tegra210_vi_soc;
#endif
struct v4l2_subdev *
tegra_channel_get_remote_subdev(struct tegra_vi_channel *chan);
int tegra_channel_set_stream(struct tegra_vi_channel *chan, bool on);
void tegra_channel_release_buffers(struct tegra_vi_channel *chan,
enum vb2_buffer_state state);
void tegra_channels_cleanup(struct tegra_vi *vi);
#endif
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/host1x.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include "video.h"
static void tegra_v4l2_dev_release(struct v4l2_device *v4l2_dev)
{
struct tegra_video_device *vid;
vid = container_of(v4l2_dev, struct tegra_video_device, v4l2_dev);
/* cleanup channels here as all video device nodes are released */
tegra_channels_cleanup(vid->vi);
v4l2_device_unregister(v4l2_dev);
media_device_unregister(&vid->media_dev);
media_device_cleanup(&vid->media_dev);
kfree(vid);
}
static int host1x_video_probe(struct host1x_device *dev)
{
struct tegra_video_device *vid;
int ret;
vid = kzalloc(sizeof(*vid), GFP_KERNEL);
if (!vid)
return -ENOMEM;
dev_set_drvdata(&dev->dev, vid);
vid->media_dev.dev = &dev->dev;
strscpy(vid->media_dev.model, "NVIDIA Tegra Video Input Device",
sizeof(vid->media_dev.model));
media_device_init(&vid->media_dev);
ret = media_device_register(&vid->media_dev);
if (ret < 0) {
dev_err(&dev->dev,
"failed to register media device: %d\n", ret);
goto cleanup;
}
vid->v4l2_dev.mdev = &vid->media_dev;
vid->v4l2_dev.release = tegra_v4l2_dev_release;
ret = v4l2_device_register(&dev->dev, &vid->v4l2_dev);
if (ret < 0) {
dev_err(&dev->dev,
"V4L2 device registration failed: %d\n", ret);
goto unregister_media;
}
ret = host1x_device_init(dev);
if (ret < 0)
goto unregister_v4l2;
/*
* Both vi and csi channels are available now.
* Register v4l2 nodes and create media links for TPG.
*/
ret = tegra_v4l2_nodes_setup_tpg(vid);
if (ret < 0) {
dev_err(&dev->dev,
"failed to setup tpg graph: %d\n", ret);
goto device_exit;
}
return 0;
device_exit:
host1x_device_exit(dev);
/* vi exit ops does not clean channels, so clean them here */
tegra_channels_cleanup(vid->vi);
unregister_v4l2:
v4l2_device_unregister(&vid->v4l2_dev);
unregister_media:
media_device_unregister(&vid->media_dev);
cleanup:
media_device_cleanup(&vid->media_dev);
kfree(vid);
return ret;
}
static int host1x_video_remove(struct host1x_device *dev)
{
struct tegra_video_device *vid = dev_get_drvdata(&dev->dev);
tegra_v4l2_nodes_cleanup_tpg(vid);
host1x_device_exit(dev);
/* This calls v4l2_dev release callback on last reference */
v4l2_device_put(&vid->v4l2_dev);
return 0;
}
static const struct of_device_id host1x_video_subdevs[] = {
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
{ .compatible = "nvidia,tegra210-csi", },
{ .compatible = "nvidia,tegra210-vi", },
#endif
{ }
};
static struct host1x_driver host1x_video_driver = {
.driver = {
.name = "tegra-video",
},
.probe = host1x_video_probe,
.remove = host1x_video_remove,
.subdevs = host1x_video_subdevs,
};
static struct platform_driver * const drivers[] = {
&tegra_csi_driver,
&tegra_vi_driver,
};
static int __init host1x_video_init(void)
{
int err;
err = host1x_driver_register(&host1x_video_driver);
if (err < 0)
return err;
err = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
if (err < 0)
goto unregister_host1x;
return 0;
unregister_host1x:
host1x_driver_unregister(&host1x_video_driver);
return err;
}
module_init(host1x_video_init);
static void __exit host1x_video_exit(void)
{
platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
host1x_driver_unregister(&host1x_video_driver);
}
module_exit(host1x_video_exit);
MODULE_AUTHOR("Sowjanya Komatineni <skomatineni@nvidia.com>");
MODULE_DESCRIPTION("NVIDIA Tegra Host1x Video driver");
MODULE_LICENSE("GPL v2");
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 NVIDIA CORPORATION. All rights reserved.
*/
#ifndef __TEGRA_VIDEO_H__
#define __TEGRA_VIDEO_H__
#include <linux/host1x.h>
#include <media/media-device.h>
#include <media/v4l2-device.h>
#include "vi.h"
#include "csi.h"
struct tegra_video_device {
struct v4l2_device v4l2_dev;
struct media_device media_dev;
struct tegra_vi *vi;
struct tegra_csi *csi;
};
int tegra_v4l2_nodes_setup_tpg(struct tegra_video_device *vid);
void tegra_v4l2_nodes_cleanup_tpg(struct tegra_video_device *vid);
extern struct platform_driver tegra_vi_driver;
extern struct platform_driver tegra_csi_driver;
#endif
...@@ -272,10 +272,10 @@ ...@@ -272,10 +272,10 @@
#define TEGRA114_CLK_AUDIO3 242 #define TEGRA114_CLK_AUDIO3 242
#define TEGRA114_CLK_AUDIO4 243 #define TEGRA114_CLK_AUDIO4 243
#define TEGRA114_CLK_SPDIF 244 #define TEGRA114_CLK_SPDIF 244
#define TEGRA114_CLK_CLK_OUT_1 245 /* 245 */
#define TEGRA114_CLK_CLK_OUT_2 246 /* 246 */
#define TEGRA114_CLK_CLK_OUT_3 247 /* 247 */
#define TEGRA114_CLK_BLINK 248 /* 248 */
#define TEGRA114_CLK_OSC 249 #define TEGRA114_CLK_OSC 249
/* 250 */ /* 250 */
/* 251 */ /* 251 */
...@@ -335,9 +335,9 @@ ...@@ -335,9 +335,9 @@
#define TEGRA114_CLK_AUDIO3_MUX 303 #define TEGRA114_CLK_AUDIO3_MUX 303
#define TEGRA114_CLK_AUDIO4_MUX 304 #define TEGRA114_CLK_AUDIO4_MUX 304
#define TEGRA114_CLK_SPDIF_MUX 305 #define TEGRA114_CLK_SPDIF_MUX 305
#define TEGRA114_CLK_CLK_OUT_1_MUX 306 /* 306 */
#define TEGRA114_CLK_CLK_OUT_2_MUX 307 /* 307 */
#define TEGRA114_CLK_CLK_OUT_3_MUX 308 /* 308 */
#define TEGRA114_CLK_DSIA_MUX 309 #define TEGRA114_CLK_DSIA_MUX 309
#define TEGRA114_CLK_DSIB_MUX 310 #define TEGRA114_CLK_DSIB_MUX 310
#define TEGRA114_CLK_XUSB_SS_DIV2 311 #define TEGRA114_CLK_XUSB_SS_DIV2 311
......
...@@ -271,10 +271,10 @@ ...@@ -271,10 +271,10 @@
#define TEGRA124_CLK_AUDIO3 242 #define TEGRA124_CLK_AUDIO3 242
#define TEGRA124_CLK_AUDIO4 243 #define TEGRA124_CLK_AUDIO4 243
#define TEGRA124_CLK_SPDIF 244 #define TEGRA124_CLK_SPDIF 244
#define TEGRA124_CLK_CLK_OUT_1 245 /* 245 */
#define TEGRA124_CLK_CLK_OUT_2 246 /* 246 */
#define TEGRA124_CLK_CLK_OUT_3 247 /* 247 */
#define TEGRA124_CLK_BLINK 248 /* 248 */
#define TEGRA124_CLK_OSC 249 #define TEGRA124_CLK_OSC 249
/* 250 */ /* 250 */
/* 251 */ /* 251 */
...@@ -334,9 +334,9 @@ ...@@ -334,9 +334,9 @@
#define TEGRA124_CLK_AUDIO3_MUX 303 #define TEGRA124_CLK_AUDIO3_MUX 303
#define TEGRA124_CLK_AUDIO4_MUX 304 #define TEGRA124_CLK_AUDIO4_MUX 304
#define TEGRA124_CLK_SPDIF_MUX 305 #define TEGRA124_CLK_SPDIF_MUX 305
#define TEGRA124_CLK_CLK_OUT_1_MUX 306 /* 306 */
#define TEGRA124_CLK_CLK_OUT_2_MUX 307 /* 307 */
#define TEGRA124_CLK_CLK_OUT_3_MUX 308 /* 308 */
/* 309 */ /* 309 */
/* 310 */ /* 310 */
#define TEGRA124_CLK_SOR0_LVDS 311 /* deprecated */ #define TEGRA124_CLK_SOR0_LVDS 311 /* deprecated */
......
...@@ -131,7 +131,7 @@ ...@@ -131,7 +131,7 @@
#define TEGRA20_CLK_CCLK 108 #define TEGRA20_CLK_CCLK 108
#define TEGRA20_CLK_HCLK 109 #define TEGRA20_CLK_HCLK 109
#define TEGRA20_CLK_PCLK 110 #define TEGRA20_CLK_PCLK 110
#define TEGRA20_CLK_BLINK 111 /* 111 */
#define TEGRA20_CLK_PLL_A 112 #define TEGRA20_CLK_PLL_A 112
#define TEGRA20_CLK_PLL_A_OUT0 113 #define TEGRA20_CLK_PLL_A_OUT0 113
#define TEGRA20_CLK_PLL_C 114 #define TEGRA20_CLK_PLL_C 114
......
...@@ -306,10 +306,10 @@ ...@@ -306,10 +306,10 @@
#define TEGRA210_CLK_AUDIO3 274 #define TEGRA210_CLK_AUDIO3 274
#define TEGRA210_CLK_AUDIO4 275 #define TEGRA210_CLK_AUDIO4 275
#define TEGRA210_CLK_SPDIF 276 #define TEGRA210_CLK_SPDIF 276
#define TEGRA210_CLK_CLK_OUT_1 277 /* 277 */
#define TEGRA210_CLK_CLK_OUT_2 278 /* 278 */
#define TEGRA210_CLK_CLK_OUT_3 279 /* 279 */
#define TEGRA210_CLK_BLINK 280 /* 280 */
#define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */ #define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */
#define TEGRA210_CLK_SOR0_OUT 281 #define TEGRA210_CLK_SOR0_OUT 281
#define TEGRA210_CLK_SOR1_OUT 282 #define TEGRA210_CLK_SOR1_OUT 282
...@@ -358,7 +358,7 @@ ...@@ -358,7 +358,7 @@
#define TEGRA210_CLK_PLL_A_OUT0_OUT_ADSP 324 #define TEGRA210_CLK_PLL_A_OUT0_OUT_ADSP 324
/* 325 */ /* 325 */
#define TEGRA210_CLK_OSC 326 #define TEGRA210_CLK_OSC 326
/* 327 */ #define TEGRA210_CLK_CSI_TPG 327
/* 328 */ /* 328 */
/* 329 */ /* 329 */
/* 330 */ /* 330 */
...@@ -388,9 +388,9 @@ ...@@ -388,9 +388,9 @@
#define TEGRA210_CLK_AUDIO3_MUX 353 #define TEGRA210_CLK_AUDIO3_MUX 353
#define TEGRA210_CLK_AUDIO4_MUX 354 #define TEGRA210_CLK_AUDIO4_MUX 354
#define TEGRA210_CLK_SPDIF_MUX 355 #define TEGRA210_CLK_SPDIF_MUX 355
#define TEGRA210_CLK_CLK_OUT_1_MUX 356 /* 356 */
#define TEGRA210_CLK_CLK_OUT_2_MUX 357 /* 357 */
#define TEGRA210_CLK_CLK_OUT_3_MUX 358 /* 358 */
#define TEGRA210_CLK_DSIA_MUX 359 #define TEGRA210_CLK_DSIA_MUX 359
#define TEGRA210_CLK_DSIB_MUX 360 #define TEGRA210_CLK_DSIB_MUX 360
/* 361 */ /* 361 */
......
...@@ -232,11 +232,11 @@ ...@@ -232,11 +232,11 @@
#define TEGRA30_CLK_AUDIO3 204 #define TEGRA30_CLK_AUDIO3 204
#define TEGRA30_CLK_AUDIO4 205 #define TEGRA30_CLK_AUDIO4 205
#define TEGRA30_CLK_SPDIF 206 #define TEGRA30_CLK_SPDIF 206
#define TEGRA30_CLK_CLK_OUT_1 207 /* (extern1) */ /* 207 */
#define TEGRA30_CLK_CLK_OUT_2 208 /* (extern2) */ /* 208 */
#define TEGRA30_CLK_CLK_OUT_3 209 /* (extern3) */ /* 209 */
#define TEGRA30_CLK_SCLK 210 #define TEGRA30_CLK_SCLK 210
#define TEGRA30_CLK_BLINK 211 /* 211 */
#define TEGRA30_CLK_CCLK_G 212 #define TEGRA30_CLK_CCLK_G 212
#define TEGRA30_CLK_CCLK_LP 213 #define TEGRA30_CLK_CCLK_LP 213
#define TEGRA30_CLK_TWD 214 #define TEGRA30_CLK_TWD 214
...@@ -262,9 +262,9 @@ ...@@ -262,9 +262,9 @@
/* 297 */ /* 297 */
/* 298 */ /* 298 */
/* 299 */ /* 299 */
#define TEGRA30_CLK_CLK_OUT_1_MUX 300 /* 300 */
#define TEGRA30_CLK_CLK_OUT_2_MUX 301 /* 301 */
#define TEGRA30_CLK_CLK_OUT_3_MUX 302 /* 302 */
#define TEGRA30_CLK_AUDIO0_MUX 303 #define TEGRA30_CLK_AUDIO0_MUX 303
#define TEGRA30_CLK_AUDIO1_MUX 304 #define TEGRA30_CLK_AUDIO1_MUX 304
#define TEGRA30_CLK_AUDIO2_MUX 305 #define TEGRA30_CLK_AUDIO2_MUX 305
......
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