linux/drivers/dma/stm32/stm32-dma.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for STM32 DMA controller
 *
 * Inspired by dma-jz4740.c and tegra20-apb-dma.c
 *
 * Copyright (C) M'boumba Cedric Madianga 2015
 * Author: M'boumba Cedric Madianga <[email protected]>
 *         Pierre-Yves Mordret <[email protected]>
 */

#include <linux/bitfield.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/iopoll.h>
#include <linux/jiffies.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/sched.h>
#include <linux/slab.h>

#include "../virt-dma.h"

#define STM32_DMA_LISR
#define STM32_DMA_HISR
#define STM32_DMA_ISR(n)
#define STM32_DMA_LIFCR
#define STM32_DMA_HIFCR
#define STM32_DMA_IFCR(n)
#define STM32_DMA_TCI
#define STM32_DMA_HTI
#define STM32_DMA_TEI
#define STM32_DMA_DMEI
#define STM32_DMA_FEI
#define STM32_DMA_MASKI
/*
 * If (chan->id % 4) is 2 or 3, left shift the mask by 16 bits;
 * if (ch % 4) is 1 or 3, additionally left shift the mask by 6 bits.
 */
#define STM32_DMA_FLAGS_SHIFT(n)

/* DMA Stream x Configuration Register */
#define STM32_DMA_SCR(x)
#define STM32_DMA_SCR_REQ_MASK
#define STM32_DMA_SCR_MBURST_MASK
#define STM32_DMA_SCR_PBURST_MASK
#define STM32_DMA_SCR_PL_MASK
#define STM32_DMA_SCR_MSIZE_MASK
#define STM32_DMA_SCR_PSIZE_MASK
#define STM32_DMA_SCR_DIR_MASK
#define STM32_DMA_SCR_TRBUFF
#define STM32_DMA_SCR_CT
#define STM32_DMA_SCR_DBM
#define STM32_DMA_SCR_PINCOS
#define STM32_DMA_SCR_MINC
#define STM32_DMA_SCR_PINC
#define STM32_DMA_SCR_CIRC
#define STM32_DMA_SCR_PFCTRL
#define STM32_DMA_SCR_TCIE
#define STM32_DMA_SCR_TEIE
#define STM32_DMA_SCR_DMEIE
#define STM32_DMA_SCR_EN
#define STM32_DMA_SCR_CFG_MASK
#define STM32_DMA_SCR_IRQ_MASK

/* DMA Stream x number of data register */
#define STM32_DMA_SNDTR(x)

/* DMA stream peripheral address register */
#define STM32_DMA_SPAR(x)

/* DMA stream x memory 0 address register */
#define STM32_DMA_SM0AR(x)

/* DMA stream x memory 1 address register */
#define STM32_DMA_SM1AR(x)

/* DMA stream x FIFO control register */
#define STM32_DMA_SFCR(x)
#define STM32_DMA_SFCR_FTH_MASK
#define STM32_DMA_SFCR_FEIE
#define STM32_DMA_SFCR_DMDIS
#define STM32_DMA_SFCR_MASK

/* DMA direction */
#define STM32_DMA_DEV_TO_MEM
#define STM32_DMA_MEM_TO_DEV
#define STM32_DMA_MEM_TO_MEM

/* DMA priority level */
#define STM32_DMA_PRIORITY_LOW
#define STM32_DMA_PRIORITY_MEDIUM
#define STM32_DMA_PRIORITY_HIGH
#define STM32_DMA_PRIORITY_VERY_HIGH

/* DMA FIFO threshold selection */
#define STM32_DMA_FIFO_THRESHOLD_1QUARTERFULL
#define STM32_DMA_FIFO_THRESHOLD_HALFFULL
#define STM32_DMA_FIFO_THRESHOLD_3QUARTERSFULL
#define STM32_DMA_FIFO_THRESHOLD_FULL
#define STM32_DMA_FIFO_THRESHOLD_NONE

#define STM32_DMA_MAX_DATA_ITEMS
/*
 * Valid transfer starts from @0 to @0xFFFE leading to unaligned scatter
 * gather at boundary. Thus it's safer to round down this value on FIFO
 * size (16 Bytes)
 */
#define STM32_DMA_ALIGNED_MAX_DATA_ITEMS
#define STM32_DMA_MAX_CHANNELS
#define STM32_DMA_MAX_REQUEST_ID
#define STM32_DMA_MAX_DATA_PARAM
#define STM32_DMA_FIFO_SIZE
#define STM32_DMA_MIN_BURST
#define STM32_DMA_MAX_BURST

/* DMA Features */
#define STM32_DMA_THRESHOLD_FTR_MASK
#define STM32_DMA_DIRECT_MODE_MASK
#define STM32_DMA_ALT_ACK_MODE_MASK
#define STM32_DMA_MDMA_STREAM_ID_MASK

enum stm32_dma_width {};

enum stm32_dma_burst_size {};

/**
 * struct stm32_dma_cfg - STM32 DMA custom configuration
 * @channel_id: channel ID
 * @request_line: DMA request
 * @stream_config: 32bit mask specifying the DMA channel configuration
 * @features: 32bit mask specifying the DMA Feature list
 */
struct stm32_dma_cfg {};

struct stm32_dma_chan_reg {};

struct stm32_dma_sg_req {};

struct stm32_dma_desc {};

/**
 * struct stm32_dma_mdma_config - STM32 DMA MDMA configuration
 * @stream_id: DMA request to trigger STM32 MDMA transfer
 * @ifcr: DMA interrupt flag clear register address,
 *        used by STM32 MDMA to clear DMA Transfer Complete flag
 * @tcf: DMA Transfer Complete flag
 */
struct stm32_dma_mdma_config {};

struct stm32_dma_chan {};

struct stm32_dma_device {};

static struct stm32_dma_device *stm32_dma_get_dev(struct stm32_dma_chan *chan)
{}

static struct stm32_dma_chan *to_stm32_dma_chan(struct dma_chan *c)
{}

static struct stm32_dma_desc *to_stm32_dma_desc(struct virt_dma_desc *vdesc)
{}

static struct device *chan2dev(struct stm32_dma_chan *chan)
{}

static u32 stm32_dma_read(struct stm32_dma_device *dmadev, u32 reg)
{}

static void stm32_dma_write(struct stm32_dma_device *dmadev, u32 reg, u32 val)
{}

static int stm32_dma_get_width(struct stm32_dma_chan *chan,
			       enum dma_slave_buswidth width)
{}

static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len,
						       dma_addr_t buf_addr,
						       u32 threshold)
{}

static bool stm32_dma_fifo_threshold_is_allowed(u32 burst, u32 threshold,
						enum dma_slave_buswidth width)
{}

static bool stm32_dma_is_burst_possible(u32 buf_len, u32 threshold)
{}

static u32 stm32_dma_get_best_burst(u32 buf_len, u32 max_burst, u32 threshold,
				    enum dma_slave_buswidth width)
{}

static int stm32_dma_get_burst(struct stm32_dma_chan *chan, u32 maxburst)
{}

static void stm32_dma_set_fifo_config(struct stm32_dma_chan *chan,
				      u32 src_burst, u32 dst_burst)
{}

static int stm32_dma_slave_config(struct dma_chan *c,
				  struct dma_slave_config *config)
{}

static u32 stm32_dma_irq_status(struct stm32_dma_chan *chan)
{}

static void stm32_dma_irq_clear(struct stm32_dma_chan *chan, u32 flags)
{}

static int stm32_dma_disable_chan(struct stm32_dma_chan *chan)
{}

static void stm32_dma_stop(struct stm32_dma_chan *chan)
{}

static int stm32_dma_terminate_all(struct dma_chan *c)
{}

static void stm32_dma_synchronize(struct dma_chan *c)
{}

static void stm32_dma_dump_reg(struct stm32_dma_chan *chan)
{}

static void stm32_dma_sg_inc(struct stm32_dma_chan *chan)
{}

static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan);

static void stm32_dma_start_transfer(struct stm32_dma_chan *chan)
{}

static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan)
{}

static void stm32_dma_handle_chan_paused(struct stm32_dma_chan *chan)
{}

static void stm32_dma_post_resume_reconfigure(struct stm32_dma_chan *chan)
{}

static void stm32_dma_handle_chan_done(struct stm32_dma_chan *chan, u32 scr)
{}

static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
{}

static void stm32_dma_issue_pending(struct dma_chan *c)
{}

static int stm32_dma_pause(struct dma_chan *c)
{}

static int stm32_dma_resume(struct dma_chan *c)
{}

static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
				    enum dma_transfer_direction direction,
				    enum dma_slave_buswidth *buswidth,
				    u32 buf_len, dma_addr_t buf_addr)
{}

static void stm32_dma_clear_reg(struct stm32_dma_chan_reg *regs)
{}

static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg(
	struct dma_chan *c, struct scatterlist *sgl,
	u32 sg_len, enum dma_transfer_direction direction,
	unsigned long flags, void *context)
{}

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

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

static u32 stm32_dma_get_remaining_bytes(struct stm32_dma_chan *chan)
{}

/**
 * stm32_dma_is_current_sg - check that expected sg_req is currently transferred
 * @chan: dma channel
 *
 * This function called when IRQ are disable, checks that the hardware has not
 * switched on the next transfer in double buffer mode. The test is done by
 * comparing the next_sg memory address with the hardware related register
 * (based on CT bit value).
 *
 * Returns true if expected current transfer is still running or double
 * buffer mode is not activated.
 */
static bool stm32_dma_is_current_sg(struct stm32_dma_chan *chan)
{}

static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan,
				     struct stm32_dma_desc *desc,
				     u32 next_sg)
{}

static enum dma_status stm32_dma_tx_status(struct dma_chan *c,
					   dma_cookie_t cookie,
					   struct dma_tx_state *state)
{}

static int stm32_dma_alloc_chan_resources(struct dma_chan *c)
{}

static void stm32_dma_free_chan_resources(struct dma_chan *c)
{}

static void stm32_dma_desc_free(struct virt_dma_desc *vdesc)
{}

static void stm32_dma_set_config(struct stm32_dma_chan *chan,
				 struct stm32_dma_cfg *cfg)
{}

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

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

static int stm32_dma_probe(struct platform_device *pdev)
{}

#ifdef CONFIG_PM
static int stm32_dma_runtime_suspend(struct device *dev)
{}

static int stm32_dma_runtime_resume(struct device *dev)
{}
#endif

#ifdef CONFIG_PM_SLEEP
static int stm32_dma_pm_suspend(struct device *dev)
{}

static int stm32_dma_pm_resume(struct device *dev)
{}
#endif

static const struct dev_pm_ops stm32_dma_pm_ops =;

static struct platform_driver stm32_dma_driver =;

static int __init stm32_dma_init(void)
{}
subsys_initcall(stm32_dma_init);