linux/drivers/dma/tegra20-apb-dma.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * DMA driver for Nvidia's Tegra20 APB DMA controller.
 *
 * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/wait.h>

#include "dmaengine.h"

#define CREATE_TRACE_POINTS
#include <trace/events/tegra_apb_dma.h>

#define TEGRA_APBDMA_GENERAL
#define TEGRA_APBDMA_GENERAL_ENABLE

#define TEGRA_APBDMA_CONTROL
#define TEGRA_APBDMA_IRQ_MASK
#define TEGRA_APBDMA_IRQ_MASK_SET

/* CSR register */
#define TEGRA_APBDMA_CHAN_CSR
#define TEGRA_APBDMA_CSR_ENB
#define TEGRA_APBDMA_CSR_IE_EOC
#define TEGRA_APBDMA_CSR_HOLD
#define TEGRA_APBDMA_CSR_DIR
#define TEGRA_APBDMA_CSR_ONCE
#define TEGRA_APBDMA_CSR_FLOW
#define TEGRA_APBDMA_CSR_REQ_SEL_SHIFT
#define TEGRA_APBDMA_CSR_REQ_SEL_MASK
#define TEGRA_APBDMA_CSR_WCOUNT_MASK

/* STATUS register */
#define TEGRA_APBDMA_CHAN_STATUS
#define TEGRA_APBDMA_STATUS_BUSY
#define TEGRA_APBDMA_STATUS_ISE_EOC
#define TEGRA_APBDMA_STATUS_HALT
#define TEGRA_APBDMA_STATUS_PING_PONG
#define TEGRA_APBDMA_STATUS_COUNT_SHIFT
#define TEGRA_APBDMA_STATUS_COUNT_MASK

#define TEGRA_APBDMA_CHAN_CSRE
#define TEGRA_APBDMA_CHAN_CSRE_PAUSE

/* AHB memory address */
#define TEGRA_APBDMA_CHAN_AHBPTR

/* AHB sequence register */
#define TEGRA_APBDMA_CHAN_AHBSEQ
#define TEGRA_APBDMA_AHBSEQ_INTR_ENB
#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_8
#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_16
#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32
#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_64
#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_128
#define TEGRA_APBDMA_AHBSEQ_DATA_SWAP
#define TEGRA_APBDMA_AHBSEQ_BURST_1
#define TEGRA_APBDMA_AHBSEQ_BURST_4
#define TEGRA_APBDMA_AHBSEQ_BURST_8
#define TEGRA_APBDMA_AHBSEQ_DBL_BUF
#define TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT
#define TEGRA_APBDMA_AHBSEQ_WRAP_NONE

/* APB address */
#define TEGRA_APBDMA_CHAN_APBPTR

/* APB sequence register */
#define TEGRA_APBDMA_CHAN_APBSEQ
#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_8
#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_16
#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_32
#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_64
#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_128
#define TEGRA_APBDMA_APBSEQ_DATA_SWAP
#define TEGRA_APBDMA_APBSEQ_WRAP_WORD_1

/* Tegra148 specific registers */
#define TEGRA_APBDMA_CHAN_WCOUNT

#define TEGRA_APBDMA_CHAN_WORD_TRANSFER

/*
 * 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_APBDMA_BURST_COMPLETE_TIME

/* Channel base address offset from APBDMA base address */
#define TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET

#define TEGRA_APBDMA_SLAVE_ID_INVALID

struct tegra_dma;

/*
 * tegra_dma_chip_data Tegra chip specific DMA data
 * @nr_channels: Number of channels available in the controller.
 * @channel_reg_size: Channel register size/stride.
 * @max_dma_count: Maximum DMA transfer count supported by DMA controller.
 * @support_channel_pause: Support channel wise pause of dma.
 * @support_separate_wcount_reg: Support separate word count register.
 */
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 in the list of transfer and point to Tegra
 * DMA descriptor which manages the transfer details.
 */
struct tegra_dma_sg_req {};

/*
 * tegra_dma_desc: Tegra DMA descriptors which manages the client requests.
 * This descriptor keep track of transfer status, callbacks and request
 * counts etc.
 */
struct tegra_dma_desc {};

struct tegra_dma_channel;

dma_isr_handler;

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

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

static inline void tdma_write(struct tegra_dma *tdma, u32 reg, u32 val)
{}

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 *
txd_to_tegra_dma_desc(struct dma_async_tx_descriptor *td)
{}

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

static dma_cookie_t tegra_dma_tx_submit(struct dma_async_tx_descriptor *tx);

/* Get DMA desc from free list, if not there then allocate it.  */
static struct tegra_dma_desc *tegra_dma_desc_get(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_desc_put(struct tegra_dma_channel *tdc,
			       struct tegra_dma_desc *dma_desc)
{}

static struct tegra_dma_sg_req *
tegra_dma_sg_req_get(struct tegra_dma_channel *tdc)
{}

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

static void tegra_dma_global_pause(struct tegra_dma_channel *tdc,
				   bool wait_for_burst_complete)
{}

static void tegra_dma_global_resume(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_pause(struct tegra_dma_channel *tdc,
			    bool wait_for_burst_complete)
{}

static void tegra_dma_resume(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_stop(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_start(struct tegra_dma_channel *tdc,
			    struct tegra_dma_sg_req *sg_req)
{}

static void tegra_dma_configure_for_next(struct tegra_dma_channel *tdc,
					 struct tegra_dma_sg_req *nsg_req)
{}

static void tdc_start_head_req(struct tegra_dma_channel *tdc)
{}

static void tdc_configure_next_head_desc(struct tegra_dma_channel *tdc)
{}

static inline unsigned int
get_current_xferred_count(struct tegra_dma_channel *tdc,
			  struct tegra_dma_sg_req *sg_req,
			  unsigned long status)
{}

static void tegra_dma_abort_all(struct tegra_dma_channel *tdc)
{}

static bool handle_continuous_head_request(struct tegra_dma_channel *tdc,
					   bool to_terminate)
{}

static void handle_once_dma_done(struct tegra_dma_channel *tdc,
				 bool to_terminate)
{}

static void handle_cont_sngl_cycle_dma_done(struct tegra_dma_channel *tdc,
					    bool to_terminate)
{}

static void tegra_dma_tasklet(struct tasklet_struct *t)
{}

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

static dma_cookie_t tegra_dma_tx_submit(struct dma_async_tx_descriptor *txd)
{}

static void tegra_dma_issue_pending(struct dma_chan *dc)
{}

static int tegra_dma_terminate_all(struct dma_chan *dc)
{}

static bool tegra_dma_eoc_interrupt_deasserted(struct tegra_dma_channel *tdc)
{}

static void tegra_dma_synchronize(struct dma_chan *dc)
{}

static unsigned int tegra_dma_sg_bytes_xferred(struct tegra_dma_channel *tdc,
					       struct tegra_dma_sg_req *sg_req)
{}

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

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

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

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

static void tegra_dma_prep_wcount(struct tegra_dma_channel *tdc,
				  struct tegra_dma_channel_regs *ch_regs,
				  u32 len)
{}

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_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)
{}

/* Tegra20 specific DMA controller information */
static const struct tegra_dma_chip_data tegra20_dma_chip_data =;

/* Tegra30 specific DMA controller information */
static const struct tegra_dma_chip_data tegra30_dma_chip_data =;

/* Tegra114 specific DMA controller information */
static const struct tegra_dma_chip_data tegra114_dma_chip_data =;

/* Tegra148 specific DMA controller information */
static const struct tegra_dma_chip_data tegra148_dma_chip_data =;

static int tegra_dma_init_hw(struct tegra_dma *tdma)
{}

static int tegra_dma_probe(struct platform_device *pdev)
{}

static void tegra_dma_remove(struct platform_device *pdev)
{}

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

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

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

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

static const struct dev_pm_ops tegra_dma_dev_pm_ops =;

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

static struct platform_driver tegra_dmac_driver =;

module_platform_driver();

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