// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
* Copyright (C) Semihalf 2009
* Copyright (C) Ilya Yanok, Emcraft Systems 2010
* Copyright (C) Alexander Popov, Promcontroller 2014
* Copyright (C) Mario Six, Guntermann & Drunck GmbH, 2016
*
* Written by Piotr Ziecik <kosmo@semihalf.com>. Hardware description
* (defines, structures and comments) was taken from MPC5121 DMA driver
* written by Hongjun Chen <hong-jun.chen@freescale.com>.
*
* Approved as OSADL project by a majority of OSADL members and funded
* by OSADL membership fees in 2009; for details see www.osadl.org.
*/
/*
* MPC512x and MPC8308 DMA driver. It supports memory to memory data transfers
* (tested using dmatest module) and data transfers between memory and
* peripheral I/O memory by means of slave scatter/gather with these
* limitations:
* - chunked transfers (described by s/g lists with more than one item) are
* refused as long as proper support for scatter/gather is missing
* - transfers on MPC8308 always start from software as this SoC does not have
* external request lines for peripheral flow control
* - memory <-> I/O memory transfer chunks of sizes of 1, 2, 4, 16 (for
* MPC512x), and 32 bytes are supported, and, consequently, source
* addresses and destination addresses must be aligned accordingly;
* furthermore, for MPC512x SoCs, the transfer size must be aligned on
* (chunk size * maxburst)
*/
#include <linux/module.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/of_dma.h>
#include <linux/of_platform.h>
#include <linux/random.h>
#include "dmaengine.h"
/* Number of DMA Transfer descriptors allocated per channel */
#define MPC_DMA_DESCRIPTORS 64
/* Macro definitions */
#define MPC_DMA_TCD_OFFSET 0x1000
/*
* Maximum channel counts for individual hardware variants
* and the maximum channel count over all supported controllers,
* used for data structure size
*/
#define MPC8308_DMACHAN_MAX 16
#define MPC512x_DMACHAN_MAX 64
#define MPC_DMA_CHANNELS 64
/* Arbitration mode of group and channel */
#define MPC_DMA_DMACR_EDCG (1 << 31)
#define MPC_DMA_DMACR_ERGA (1 << 3)
#define MPC_DMA_DMACR_ERCA (1 << 2)
/* Error codes */
#define MPC_DMA_DMAES_VLD (1 << 31)
#define MPC_DMA_DMAES_GPE (1 << 15)
#define MPC_DMA_DMAES_CPE (1 << 14)
#define MPC_DMA_DMAES_ERRCHN(err) \
(((err) >> 8) & 0x3f)
#define MPC_DMA_DMAES_SAE (1 << 7)
#define MPC_DMA_DMAES_SOE (1 << 6)
#define MPC_DMA_DMAES_DAE (1 << 5)
#define MPC_DMA_DMAES_DOE (1 << 4)
#define MPC_DMA_DMAES_NCE (1 << 3)
#define MPC_DMA_DMAES_SGE (1 << 2)
#define MPC_DMA_DMAES_SBE (1 << 1)
#define MPC_DMA_DMAES_DBE (1 << 0)
#define MPC_DMA_DMAGPOR_SNOOP_ENABLE (1 << 6)
#define MPC_DMA_TSIZE_1 0x00
#define MPC_DMA_TSIZE_2 0x01
#define MPC_DMA_TSIZE_4 0x02
#define MPC_DMA_TSIZE_16 0x04
#define MPC_DMA_TSIZE_32 0x05
/* MPC5121 DMA engine registers */
struct __attribute__ ((__packed__)) mpc_dma_regs {
/* 0x00 */
u32 dmacr; /* DMA control register */
u32 dmaes; /* DMA error status */
/* 0x08 */
u32 dmaerqh; /* DMA enable request high(channels 63~32) */
u32 dmaerql; /* DMA enable request low(channels 31~0) */
u32 dmaeeih; /* DMA enable error interrupt high(ch63~32) */
u32 dmaeeil; /* DMA enable error interrupt low(ch31~0) */
/* 0x18 */
u8 dmaserq; /* DMA set enable request */
u8 dmacerq; /* DMA clear enable request */
u8 dmaseei; /* DMA set enable error interrupt */
u8 dmaceei; /* DMA clear enable error interrupt */
/* 0x1c */
u8 dmacint; /* DMA clear interrupt request */
u8 dmacerr; /* DMA clear error */
u8 dmassrt; /* DMA set start bit */
u8 dmacdne; /* DMA clear DONE status bit */
/* 0x20 */
u32 dmainth; /* DMA interrupt request high(ch63~32) */
u32 dmaintl; /* DMA interrupt request low(ch31~0) */
u32 dmaerrh; /* DMA error high(ch63~32) */
u32 dmaerrl; /* DMA error low(ch31~0) */
/* 0x30 */
u32 dmahrsh; /* DMA hw request status high(ch63~32) */
u32 dmahrsl; /* DMA hardware request status low(ch31~0) */
union {
u32 dmaihsa; /* DMA interrupt high select AXE(ch63~32) */
u32 dmagpor; /* (General purpose register on MPC8308) */
};
u32 dmailsa; /* DMA interrupt low select AXE(ch31~0) */
/* 0x40 ~ 0xff */
u32 reserve0[48]; /* Reserved */
/* 0x100 */
u8 dchpri[MPC_DMA_CHANNELS];
/* DMA channels(0~63) priority */
};
struct __attribute__ ((__packed__)) mpc_dma_tcd {
/* 0x00 */
u32 saddr; /* Source address */
u32 smod:5; /* Source address modulo */
u32 ssize:3; /* Source data transfer size */
u32 dmod:5; /* Destination address modulo */
u32 dsize:3; /* Destination data transfer size */
u32 soff:16; /* Signed source address offset */
/* 0x08 */
u32 nbytes; /* Inner "minor" byte count */
u32 slast; /* Last source address adjustment */
u32 daddr; /* Destination address */
/* 0x14 */
u32 citer_elink:1; /* Enable channel-to-channel linking on
* minor loop complete
*/
u32 citer_linkch:6; /* Link channel for minor loop complete */
u32 citer:9; /* Current "major" iteration count */
u32 doff:16; /* Signed destination address offset */
/* 0x18 */
u32 dlast_sga; /* Last Destination address adjustment/scatter
* gather address
*/
/* 0x1c */
u32 biter_elink:1; /* Enable channel-to-channel linking on major
* loop complete
*/
u32 biter_linkch:6;
u32 biter:9; /* Beginning "major" iteration count */
u32 bwc:2; /* Bandwidth control */
u32 major_linkch:6; /* Link channel number */
u32 done:1; /* Channel done */
u32 active:1; /* Channel active */
u32 major_elink:1; /* Enable cha