linux/drivers/dma/tegra186-gpc-dma.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * DMA driver for NVIDIA Tegra GPC DMA controller.
 *
 * Copyright (c) 2014-2022, NVIDIA CORPORATION.  All rights reserved.
 */

#include <linux/bitfield.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/iommu.h>
#include <linux/iopoll.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <dt-bindings/memory/tegra186-mc.h>
#include "virt-dma.h"

/* CSR register */
#define TEGRA_GPCDMA_CHAN_CSR
#define TEGRA_GPCDMA_CSR_ENB
#define TEGRA_GPCDMA_CSR_IE_EOC
#define TEGRA_GPCDMA_CSR_ONCE

#define TEGRA_GPCDMA_CSR_FC_MODE
#define TEGRA_GPCDMA_CSR_FC_MODE_NO_MMIO
#define TEGRA_GPCDMA_CSR_FC_MODE_ONE_MMIO
#define TEGRA_GPCDMA_CSR_FC_MODE_TWO_MMIO
#define TEGRA_GPCDMA_CSR_FC_MODE_FOUR_MMIO

#define TEGRA_GPCDMA_CSR_DMA
#define TEGRA_GPCDMA_CSR_DMA_IO2MEM_NO_FC
#define TEGRA_GPCDMA_CSR_DMA_IO2MEM_FC
#define TEGRA_GPCDMA_CSR_DMA_MEM2IO_NO_FC
#define TEGRA_GPCDMA_CSR_DMA_MEM2IO_FC
#define TEGRA_GPCDMA_CSR_DMA_MEM2MEM
#define TEGRA_GPCDMA_CSR_DMA_FIXED_PAT

#define TEGRA_GPCDMA_CSR_REQ_SEL_MASK
#define TEGRA_GPCDMA_CSR_REQ_SEL_UNUSED
#define TEGRA_GPCDMA_CSR_IRQ_MASK
#define TEGRA_GPCDMA_CSR_WEIGHT

/* STATUS register */
#define TEGRA_GPCDMA_CHAN_STATUS
#define TEGRA_GPCDMA_STATUS_BUSY
#define TEGRA_GPCDMA_STATUS_ISE_EOC
#define TEGRA_GPCDMA_STATUS_PING_PONG
#define TEGRA_GPCDMA_STATUS_DMA_ACTIVITY
#define TEGRA_GPCDMA_STATUS_CHANNEL_PAUSE
#define TEGRA_GPCDMA_STATUS_CHANNEL_RX
#define TEGRA_GPCDMA_STATUS_CHANNEL_TX
#define TEGRA_GPCDMA_STATUS_IRQ_INTR_STA
#define TEGRA_GPCDMA_STATUS_IRQ_STA
#define TEGRA_GPCDMA_STATUS_IRQ_TRIG_STA

#define TEGRA_GPCDMA_CHAN_CSRE
#define TEGRA_GPCDMA_CHAN_CSRE_PAUSE

/* Source address */
#define TEGRA_GPCDMA_CHAN_SRC_PTR

/* Destination address */
#define TEGRA_GPCDMA_CHAN_DST_PTR

/* High address pointer */
#define TEGRA_GPCDMA_CHAN_HIGH_ADDR_PTR
#define TEGRA_GPCDMA_HIGH_ADDR_SRC_PTR
#define TEGRA_GPCDMA_HIGH_ADDR_DST_PTR

/* MC sequence register */
#define TEGRA_GPCDMA_CHAN_MCSEQ
#define TEGRA_GPCDMA_MCSEQ_DATA_SWAP
#define TEGRA_GPCDMA_MCSEQ_REQ_COUNT
#define TEGRA_GPCDMA_MCSEQ_BURST
#define TEGRA_GPCDMA_MCSEQ_BURST_2
#define TEGRA_GPCDMA_MCSEQ_BURST_16
#define TEGRA_GPCDMA_MCSEQ_WRAP1
#define TEGRA_GPCDMA_MCSEQ_WRAP0
#define TEGRA_GPCDMA_MCSEQ_WRAP_NONE

#define TEGRA_GPCDMA_MCSEQ_STREAM_ID1_MASK
#define TEGRA_GPCDMA_MCSEQ_STREAM_ID0_MASK

/* MMIO sequence register */
#define TEGRA_GPCDMA_CHAN_MMIOSEQ
#define TEGRA_GPCDMA_MMIOSEQ_DBL_BUF
#define TEGRA_GPCDMA_MMIOSEQ_BUS_WIDTH
#define TEGRA_GPCDMA_MMIOSEQ_BUS_WIDTH_8
#define TEGRA_GPCDMA_MMIOSEQ_BUS_WIDTH_16
#define TEGRA_GPCDMA_MMIOSEQ_BUS_WIDTH_32
#define TEGRA_GPCDMA_MMIOSEQ_DATA_SWAP
#define TEGRA_GPCDMA_MMIOSEQ_BURST_SHIFT
#define TEGRA_GPCDMA_MMIOSEQ_BURST_MIN
#define TEGRA_GPCDMA_MMIOSEQ_BURST_MAX
#define TEGRA_GPCDMA_MMIOSEQ_BURST(bs)
#define TEGRA_GPCDMA_MMIOSEQ_MASTER_ID
#define TEGRA_GPCDMA_MMIOSEQ_WRAP_WORD
#define TEGRA_GPCDMA_MMIOSEQ_MMIO_PROT

/* Channel WCOUNT */
#define TEGRA_GPCDMA_CHAN_WCOUNT

/* Transfer count */
#define TEGRA_GPCDMA_CHAN_XFER_COUNT

/* DMA byte count status */
#define TEGRA_GPCDMA_CHAN_DMA_BYTE_STATUS

/* Error Status Register */
#define TEGRA_GPCDMA_CHAN_ERR_STATUS
#define TEGRA_GPCDMA_CHAN_ERR_TYPE_SHIFT
#define TEGRA_GPCDMA_CHAN_ERR_TYPE_MASK
#define TEGRA_GPCDMA_CHAN_ERR_TYPE(err)
#define TEGRA_DMA_BM_FIFO_FULL_ERR
#define TEGRA_DMA_PERIPH_FIFO_FULL_ERR
#define TEGRA_DMA_PERIPH_ID_ERR
#define TEGRA_DMA_STREAM_ID_ERR
#define TEGRA_DMA_MC_SLAVE_ERR
#define TEGRA_DMA_MMIO_SLAVE_ERR

/* Fixed Pattern */
#define TEGRA_GPCDMA_CHAN_FIXED_PATTERN

#define TEGRA_GPCDMA_CHAN_TZ
#define TEGRA_GPCDMA_CHAN_TZ_MMIO_PROT_1
#define TEGRA_GPCDMA_CHAN_TZ_MC_PROT_1

#define TEGRA_GPCDMA_CHAN_SPARE
#define TEGRA_GPCDMA_CHAN_SPARE_EN_LEGACY_FC

/*
 * If any burst is in flight and DMA paused then this is the time to complete
 * on-flight burst and update DMA status register.
 */
#define TEGRA_GPCDMA_BURST_COMPLETE_TIME
#define TEGRA_GPCDMA_BURST_COMPLETION_TIMEOUT

/* Channel base address offset from GPCDMA base address */
#define TEGRA_GPCDMA_CHANNEL_BASE_ADDR_OFFSET

/* Default channel mask reserving channel0 */
#define TEGRA_GPCDMA_DEFAULT_CHANNEL_MASK

struct tegra_dma;
struct tegra_dma_channel;

/*
 * tegra_dma_chip_data Tegra chip specific DMA data
 * @nr_channels: Number of channels available in the controller.
 * @channel_reg_size: Channel register size.
 * @max_dma_count: Maximum DMA transfer count supported by DMA controller.
 * @hw_support_pause: DMA HW engine support pause of the channel.
 */
struct tegra_dma_chip_data {};

/* DMA channel registers */
struct tegra_dma_channel_regs {};

/*
 * tegra_dma_sg_req: DMA request details to configure hardware. This
 * contains the details for one transfer to configure DMA hw.
 * The client's request for data transfer can be broken into multiple
 * sub-transfer as per requester details and hw support. This sub transfer
 * get added as an array in Tegra DMA desc which manages the transfer details.
 */
struct tegra_dma_sg_req {};

/*
 * tegra_dma_desc: Tegra DMA descriptors which uses virt_dma_desc to
 * manage client request and keep track of transfer status, callbacks
 * and request counts etc.
 */
struct tegra_dma_desc {};

/*
 * tegra_dma_channel: Channel specific information
 */
struct tegra_dma_channel {};

/*
 * tegra_dma: Tegra DMA specific information
 */
struct tegra_dma {};

static inline void tdc_write(struct tegra_dma_channel *tdc,
			     u32 reg, u32 val)
{}

static inline u32 tdc_read(struct tegra_dma_channel *tdc, u32 reg)
{}

static inline struct tegra_dma_channel *to_tegra_dma_chan(struct dma_chan *dc)
{}

static inline struct tegra_dma_desc *vd_to_tegra_dma_desc(struct virt_dma_desc *vd)
{}

static inline struct device *tdc2dev(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_dump_chan_regs(struct tegra_dma_channel *tdc)
{}

static int tegra_dma_sid_reserve(struct tegra_dma_channel *tdc,
				 enum dma_transfer_direction direction)
{}

static void tegra_dma_sid_free(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_desc_free(struct virt_dma_desc *vd)
{}

static int tegra_dma_slave_config(struct dma_chan *dc,
				  struct dma_slave_config *sconfig)
{}

static int tegra_dma_pause(struct tegra_dma_channel *tdc)
{}

static int tegra_dma_device_pause(struct dma_chan *dc)
{}

static void tegra_dma_resume(struct tegra_dma_channel *tdc)
{}

static int tegra_dma_device_resume(struct dma_chan *dc)
{}

static inline int tegra_dma_pause_noerr(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_disable(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_configure_next_sg(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_start(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_xfer_complete(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_chan_decode_error(struct tegra_dma_channel *tdc,
					unsigned int err_status)
{}

static irqreturn_t tegra_dma_isr(int irq, void *dev_id)
{}

static void tegra_dma_issue_pending(struct dma_chan *dc)
{}

static int tegra_dma_stop_client(struct tegra_dma_channel *tdc)
{}

static int tegra_dma_terminate_all(struct dma_chan *dc)
{}

static int tegra_dma_get_residual(struct tegra_dma_channel *tdc)
{}

static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
					   dma_cookie_t cookie,
					   struct dma_tx_state *txstate)
{}

static inline int get_bus_width(struct tegra_dma_channel *tdc,
				enum dma_slave_buswidth slave_bw)
{}

static unsigned int get_burst_size(struct tegra_dma_channel *tdc,
				   u32 burst_size, enum dma_slave_buswidth slave_bw,
				   int len)
{}

static int get_transfer_param(struct tegra_dma_channel *tdc,
			      enum dma_transfer_direction direction,
			      u32 *apb_addr,
			      u32 *mmio_seq,
			      u32 *csr,
			      unsigned int *burst_size,
			      enum dma_slave_buswidth *slave_bw)
{}

static struct dma_async_tx_descriptor *
tegra_dma_prep_dma_memset(struct dma_chan *dc, dma_addr_t dest, int value,
			  size_t len, unsigned long flags)
{}

static struct dma_async_tx_descriptor *
tegra_dma_prep_dma_memcpy(struct dma_chan *dc, dma_addr_t dest,
			  dma_addr_t src, size_t len, unsigned long flags)
{}

static struct dma_async_tx_descriptor *
tegra_dma_prep_slave_sg(struct dma_chan *dc, struct scatterlist *sgl,
			unsigned int sg_len, enum dma_transfer_direction direction,
			unsigned long flags, void *context)
{}

static struct dma_async_tx_descriptor *
tegra_dma_prep_dma_cyclic(struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_len,
			  size_t period_len, enum dma_transfer_direction direction,
			  unsigned long flags)
{}

static int tegra_dma_alloc_chan_resources(struct dma_chan *dc)
{}

static void tegra_dma_chan_synchronize(struct dma_chan *dc)
{}

static void tegra_dma_free_chan_resources(struct dma_chan *dc)
{}

static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
					   struct of_dma *ofdma)
{}

static const struct tegra_dma_chip_data tegra186_dma_chip_data =;

static const struct tegra_dma_chip_data tegra194_dma_chip_data =;

static const struct tegra_dma_chip_data tegra234_dma_chip_data =;

static const struct of_device_id tegra_dma_of_match[] =;
MODULE_DEVICE_TABLE(of, tegra_dma_of_match);

static int tegra_dma_program_sid(struct tegra_dma_channel *tdc, int stream_id)
{}

static int tegra_dma_probe(struct platform_device *pdev)
{}

static void tegra_dma_remove(struct platform_device *pdev)
{}

static int __maybe_unused tegra_dma_pm_suspend(struct device *dev)
{}

static int __maybe_unused tegra_dma_pm_resume(struct device *dev)
{}

static const struct dev_pm_ops tegra_dma_dev_pm_ops =;

static struct platform_driver tegra_dma_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_LICENSE();