Commit a033a74e authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Vinod Koul

dmaengine: remove coh901318 driver

The ST-Ericsson U300 platform is getting removed, so this driver is no
longer needed.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20210120131859.2056308-4-arnd@kernel.orgSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 1c8963f8
ST-Ericsson COH 901 318 DMA Controller
This is a DMA controller which has begun as a fork of the
ARM PL08x PrimeCell VHDL code.
Required properties:
- compatible: should be "stericsson,coh901318"
- reg: register locations and length
- interrupts: the single DMA IRQ
- #dma-cells: must be set to <1>, as the channels on the
COH 901 318 are simple and identified by a single number
- dma-channels: the number of DMA channels handled
Example:
dmac: dma-controller@c00020000 {
compatible = "stericsson,coh901318";
reg = <0xc0020000 0x1000>;
interrupt-parent = <&vica>;
interrupts = <2>;
#dma-cells = <1>;
dma-channels = <40>;
};
Consumers example:
uart0: serial@c0013000 {
compatible = "...";
(...)
dmas = <&dmac 17 &dmac 18>;
dma-names = "tx", "rx";
};
......@@ -124,13 +124,6 @@ config BCM_SBA_RAID
has the capability to offload memcpy, xor and pq computation
for raid5/6.
config COH901318
bool "ST-Ericsson COH901318 DMA support"
select DMA_ENGINE
depends on ARCH_U300 || COMPILE_TEST
help
Enable support for ST-Ericsson COH 901 318 DMA.
config DMA_BCM2835
tristate "BCM2835 DMA engine support"
depends on ARCH_BCM2835
......
......@@ -20,7 +20,6 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
obj-$(CONFIG_AT_XDMAC) += at_xdmac.o
obj-$(CONFIG_AXI_DMAC) += dma-axi-dmac.o
obj-$(CONFIG_BCM_SBA_RAID) += bcm-sba-raid.o
obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o
obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2007-2013 ST-Ericsson
* DMA driver for COH 901 318
* Author: Per Friden <per.friden@stericsson.com>
*/
#ifndef COH901318_H
#define COH901318_H
#define MAX_DMA_PACKET_SIZE_SHIFT 11
#define MAX_DMA_PACKET_SIZE (1 << MAX_DMA_PACKET_SIZE_SHIFT)
struct device;
struct coh901318_pool {
spinlock_t lock;
struct dma_pool *dmapool;
struct device *dev;
#ifdef CONFIG_DEBUG_FS
int debugfs_pool_counter;
#endif
};
/**
* struct coh901318_lli - linked list item for DMAC
* @control: control settings for DMAC
* @src_addr: transfer source address
* @dst_addr: transfer destination address
* @link_addr: physical address to next lli
* @virt_link_addr: virtual address of next lli (only used by pool_free)
* @phy_this: physical address of current lli (only used by pool_free)
*/
struct coh901318_lli {
u32 control;
dma_addr_t src_addr;
dma_addr_t dst_addr;
dma_addr_t link_addr;
void *virt_link_addr;
dma_addr_t phy_this;
};
/**
* coh901318_pool_create() - Creates an dma pool for lli:s
* @pool: pool handle
* @dev: dma device
* @lli_nbr: number of lli:s in the pool
* @algin: address alignemtn of lli:s
* returns 0 on success otherwise none zero
*/
int coh901318_pool_create(struct coh901318_pool *pool,
struct device *dev,
size_t lli_nbr, size_t align);
/**
* coh901318_pool_destroy() - Destroys the dma pool
* @pool: pool handle
* returns 0 on success otherwise none zero
*/
int coh901318_pool_destroy(struct coh901318_pool *pool);
/**
* coh901318_lli_alloc() - Allocates a linked list
*
* @pool: pool handle
* @len: length to list
* return: none NULL if success otherwise NULL
*/
struct coh901318_lli *
coh901318_lli_alloc(struct coh901318_pool *pool,
unsigned int len);
/**
* coh901318_lli_free() - Returns the linked list items to the pool
* @pool: pool handle
* @lli: reference to lli pointer to be freed
*/
void coh901318_lli_free(struct coh901318_pool *pool,
struct coh901318_lli **lli);
/**
* coh901318_lli_fill_memcpy() - Prepares the lli:s for dma memcpy
* @pool: pool handle
* @lli: allocated lli
* @src: src address
* @size: transfer size
* @dst: destination address
* @ctrl_chained: ctrl for chained lli
* @ctrl_last: ctrl for the last lli
* returns number of CPU interrupts for the lli, negative on error.
*/
int
coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
struct coh901318_lli *lli,
dma_addr_t src, unsigned int size,
dma_addr_t dst, u32 ctrl_chained, u32 ctrl_last);
/**
* coh901318_lli_fill_single() - Prepares the lli:s for dma single transfer
* @pool: pool handle
* @lli: allocated lli
* @buf: transfer buffer
* @size: transfer size
* @dev_addr: address of periphal
* @ctrl_chained: ctrl for chained lli
* @ctrl_last: ctrl for the last lli
* @dir: direction of transfer (to or from device)
* returns number of CPU interrupts for the lli, negative on error.
*/
int
coh901318_lli_fill_single(struct coh901318_pool *pool,
struct coh901318_lli *lli,
dma_addr_t buf, unsigned int size,
dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_last,
enum dma_transfer_direction dir);
/**
* coh901318_lli_fill_single() - Prepares the lli:s for dma scatter list transfer
* @pool: pool handle
* @lli: allocated lli
* @sg: scatter gather list
* @nents: number of entries in sg
* @dev_addr: address of periphal
* @ctrl_chained: ctrl for chained lli
* @ctrl: ctrl of middle lli
* @ctrl_last: ctrl for the last lli
* @dir: direction of transfer (to or from device)
* @ctrl_irq_mask: ctrl mask for CPU interrupt
* returns number of CPU interrupts for the lli, negative on error.
*/
int
coh901318_lli_fill_sg(struct coh901318_pool *pool,
struct coh901318_lli *lli,
struct scatterlist *sg, unsigned int nents,
dma_addr_t dev_addr, u32 ctrl_chained,
u32 ctrl, u32 ctrl_last,
enum dma_transfer_direction dir, u32 ctrl_irq_mask);
#endif /* COH901318_H */
// SPDX-License-Identifier: GPL-2.0-only
/*
* driver/dma/coh901318_lli.c
*
* Copyright (C) 2007-2009 ST-Ericsson
* Support functions for handling lli for dma
* Author: Per Friden <per.friden@stericsson.com>
*/
#include <linux/spinlock.h>
#include <linux/memory.h>
#include <linux/gfp.h>
#include <linux/dmapool.h>
#include <linux/dmaengine.h>
#include "coh901318.h"
#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
#define DEBUGFS_POOL_COUNTER_RESET(pool) (pool->debugfs_pool_counter = 0)
#define DEBUGFS_POOL_COUNTER_ADD(pool, add) (pool->debugfs_pool_counter += add)
#else
#define DEBUGFS_POOL_COUNTER_RESET(pool)
#define DEBUGFS_POOL_COUNTER_ADD(pool, add)
#endif
static struct coh901318_lli *
coh901318_lli_next(struct coh901318_lli *data)
{
if (data == NULL || data->link_addr == 0)
return NULL;
return (struct coh901318_lli *) data->virt_link_addr;
}
int coh901318_pool_create(struct coh901318_pool *pool,
struct device *dev,
size_t size, size_t align)
{
spin_lock_init(&pool->lock);
pool->dev = dev;
pool->dmapool = dma_pool_create("lli_pool", dev, size, align, 0);
DEBUGFS_POOL_COUNTER_RESET(pool);
return 0;
}
int coh901318_pool_destroy(struct coh901318_pool *pool)
{
dma_pool_destroy(pool->dmapool);
return 0;
}
struct coh901318_lli *
coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
{
int i;
struct coh901318_lli *head;
struct coh901318_lli *lli;
struct coh901318_lli *lli_prev;
dma_addr_t phy;
if (len == 0)
return NULL;
spin_lock(&pool->lock);
head = dma_pool_alloc(pool->dmapool, GFP_NOWAIT, &phy);
if (head == NULL)
goto err;
DEBUGFS_POOL_COUNTER_ADD(pool, 1);
lli = head;
lli->phy_this = phy;
lli->link_addr = 0x00000000;
lli->virt_link_addr = NULL;
for (i = 1; i < len; i++) {
lli_prev = lli;
lli = dma_pool_alloc(pool->dmapool, GFP_NOWAIT, &phy);
if (lli == NULL)
goto err_clean_up;
DEBUGFS_POOL_COUNTER_ADD(pool, 1);
lli->phy_this = phy;
lli->link_addr = 0x00000000;
lli->virt_link_addr = NULL;
lli_prev->link_addr = phy;
lli_prev->virt_link_addr = lli;
}
spin_unlock(&pool->lock);
return head;
err:
spin_unlock(&pool->lock);
return NULL;
err_clean_up:
lli_prev->link_addr = 0x00000000U;
spin_unlock(&pool->lock);
coh901318_lli_free(pool, &head);
return NULL;
}
void coh901318_lli_free(struct coh901318_pool *pool,
struct coh901318_lli **lli)
{
struct coh901318_lli *l;
struct coh901318_lli *next;
if (lli == NULL)
return;
l = *lli;
if (l == NULL)
return;
spin_lock(&pool->lock);
while (l->link_addr) {
next = l->virt_link_addr;
dma_pool_free(pool->dmapool, l, l->phy_this);
DEBUGFS_POOL_COUNTER_ADD(pool, -1);
l = next;
}
dma_pool_free(pool->dmapool, l, l->phy_this);
DEBUGFS_POOL_COUNTER_ADD(pool, -1);
spin_unlock(&pool->lock);
*lli = NULL;
}
int
coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
struct coh901318_lli *lli,
dma_addr_t source, unsigned int size,
dma_addr_t destination, u32 ctrl_chained,
u32 ctrl_eom)
{
int s = size;
dma_addr_t src = source;
dma_addr_t dst = destination;
lli->src_addr = src;
lli->dst_addr = dst;
while (lli->link_addr) {
lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE;
lli->src_addr = src;
lli->dst_addr = dst;
s -= MAX_DMA_PACKET_SIZE;
lli = coh901318_lli_next(lli);
src += MAX_DMA_PACKET_SIZE;
dst += MAX_DMA_PACKET_SIZE;
}
lli->control = ctrl_eom | s;
lli->src_addr = src;
lli->dst_addr = dst;
return 0;
}
int
coh901318_lli_fill_single(struct coh901318_pool *pool,
struct coh901318_lli *lli,
dma_addr_t buf, unsigned int size,
dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_eom,
enum dma_transfer_direction dir)
{
int s = size;
dma_addr_t src;
dma_addr_t dst;
if (dir == DMA_MEM_TO_DEV) {
src = buf;
dst = dev_addr;
} else if (dir == DMA_DEV_TO_MEM) {
src = dev_addr;
dst = buf;
} else {
return -EINVAL;
}
while (lli->link_addr) {
size_t block_size = MAX_DMA_PACKET_SIZE;
lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE;
/* If we are on the next-to-final block and there will
* be less than half a DMA packet left for the last
* block, then we want to make this block a little
* smaller to balance the sizes. This is meant to
* avoid too small transfers if the buffer size is
* (MAX_DMA_PACKET_SIZE*N + 1) */
if (s < (MAX_DMA_PACKET_SIZE + MAX_DMA_PACKET_SIZE/2))
block_size = MAX_DMA_PACKET_SIZE/2;
s -= block_size;
lli->src_addr = src;
lli->dst_addr = dst;
lli = coh901318_lli_next(lli);
if (dir == DMA_MEM_TO_DEV)
src += block_size;
else if (dir == DMA_DEV_TO_MEM)
dst += block_size;
}
lli->control = ctrl_eom | s;
lli->src_addr = src;
lli->dst_addr = dst;
return 0;
}
int
coh901318_lli_fill_sg(struct coh901318_pool *pool,
struct coh901318_lli *lli,
struct scatterlist *sgl, unsigned int nents,
dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl,
u32 ctrl_last,
enum dma_transfer_direction dir, u32 ctrl_irq_mask)
{
int i;
struct scatterlist *sg;
u32 ctrl_sg;
dma_addr_t src = 0;
dma_addr_t dst = 0;
u32 bytes_to_transfer;
u32 elem_size;
if (lli == NULL)
goto err;
spin_lock(&pool->lock);
if (dir == DMA_MEM_TO_DEV)
dst = dev_addr;
else if (dir == DMA_DEV_TO_MEM)
src = dev_addr;
else
goto err;
for_each_sg(sgl, sg, nents, i) {
if (sg_is_chain(sg)) {
/* sg continues to the next sg-element don't
* send ctrl_finish until the last
* sg-element in the chain
*/
ctrl_sg = ctrl_chained;
} else if (i == nents - 1)
ctrl_sg = ctrl_last;
else
ctrl_sg = ctrl ? ctrl : ctrl_last;
if (dir == DMA_MEM_TO_DEV)
/* increment source address */
src = sg_dma_address(sg);
else
/* increment destination address */
dst = sg_dma_address(sg);
bytes_to_transfer = sg_dma_len(sg);
while (bytes_to_transfer) {
u32 val;
if (bytes_to_transfer > MAX_DMA_PACKET_SIZE) {
elem_size = MAX_DMA_PACKET_SIZE;
val = ctrl_chained;
} else {
elem_size = bytes_to_transfer;
val = ctrl_sg;
}
lli->control = val | elem_size;
lli->src_addr = src;
lli->dst_addr = dst;
if (dir == DMA_DEV_TO_MEM)
dst += elem_size;
else
src += elem_size;
BUG_ON(lli->link_addr & 3);
bytes_to_transfer -= elem_size;
lli = coh901318_lli_next(lli);
}
}
spin_unlock(&pool->lock);
return 0;
err:
spin_unlock(&pool->lock);
return -EINVAL;
}
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Platform data for the COH901318 DMA controller
* Copyright (C) 2007-2013 ST-Ericsson
*/
#ifndef PLAT_COH901318_H
#define PLAT_COH901318_H
#ifdef CONFIG_COH901318
/* We only support the U300 DMA channels */
#define U300_DMA_MSL_TX_0 0
#define U300_DMA_MSL_TX_1 1
#define U300_DMA_MSL_TX_2 2
#define U300_DMA_MSL_TX_3 3
#define U300_DMA_MSL_TX_4 4
#define U300_DMA_MSL_TX_5 5
#define U300_DMA_MSL_TX_6 6
#define U300_DMA_MSL_RX_0 7
#define U300_DMA_MSL_RX_1 8
#define U300_DMA_MSL_RX_2 9
#define U300_DMA_MSL_RX_3 10
#define U300_DMA_MSL_RX_4 11
#define U300_DMA_MSL_RX_5 12
#define U300_DMA_MSL_RX_6 13
#define U300_DMA_MMCSD_RX_TX 14
#define U300_DMA_MSPRO_TX 15
#define U300_DMA_MSPRO_RX 16
#define U300_DMA_UART0_TX 17
#define U300_DMA_UART0_RX 18
#define U300_DMA_APEX_TX 19
#define U300_DMA_APEX_RX 20
#define U300_DMA_PCM_I2S0_TX 21
#define U300_DMA_PCM_I2S0_RX 22
#define U300_DMA_PCM_I2S1_TX 23
#define U300_DMA_PCM_I2S1_RX 24
#define U300_DMA_XGAM_CDI 25
#define U300_DMA_XGAM_PDI 26
#define U300_DMA_SPI_TX 27
#define U300_DMA_SPI_RX 28
#define U300_DMA_GENERAL_PURPOSE_0 29
#define U300_DMA_GENERAL_PURPOSE_1 30
#define U300_DMA_GENERAL_PURPOSE_2 31
#define U300_DMA_GENERAL_PURPOSE_3 32
#define U300_DMA_GENERAL_PURPOSE_4 33
#define U300_DMA_GENERAL_PURPOSE_5 34
#define U300_DMA_GENERAL_PURPOSE_6 35
#define U300_DMA_GENERAL_PURPOSE_7 36
#define U300_DMA_GENERAL_PURPOSE_8 37
#define U300_DMA_UART1_TX 38
#define U300_DMA_UART1_RX 39
#define U300_DMA_DEVICE_CHANNELS 32
#define U300_DMA_CHANNELS 40
/**
* coh901318_filter_id() - DMA channel filter function
* @chan: dma channel handle
* @chan_id: id of dma channel to be filter out
*
* In dma_request_channel() it specifies what channel id to be requested
*/
bool coh901318_filter_id(struct dma_chan *chan, void *chan_id);
#else
static inline bool coh901318_filter_id(struct dma_chan *chan, void *chan_id)
{
return false;
}
#endif
#endif /* PLAT_COH901318_H */
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