Merge branch 'topic/fsl' into for-linus
This commit is contained in:
commit
79074168de
57
Documentation/devicetree/bindings/dma/fsl-qdma.txt
Normal file
57
Documentation/devicetree/bindings/dma/fsl-qdma.txt
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
NXP Layerscape SoC qDMA Controller
|
||||||
|
==================================
|
||||||
|
|
||||||
|
This device follows the generic DMA bindings defined in dma/dma.txt.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible: Must be one of
|
||||||
|
"fsl,ls1021a-qdma": for LS1021A Board
|
||||||
|
"fsl,ls1043a-qdma": for ls1043A Board
|
||||||
|
"fsl,ls1046a-qdma": for ls1046A Board
|
||||||
|
- reg: Should contain the register's base address and length.
|
||||||
|
- interrupts: Should contain a reference to the interrupt used by this
|
||||||
|
device.
|
||||||
|
- interrupt-names: Should contain interrupt names:
|
||||||
|
"qdma-queue0": the block0 interrupt
|
||||||
|
"qdma-queue1": the block1 interrupt
|
||||||
|
"qdma-queue2": the block2 interrupt
|
||||||
|
"qdma-queue3": the block3 interrupt
|
||||||
|
"qdma-error": the error interrupt
|
||||||
|
- fsl,dma-queues: Should contain number of queues supported.
|
||||||
|
- dma-channels: Number of DMA channels supported
|
||||||
|
- block-number: the virtual block number
|
||||||
|
- block-offset: the offset of different virtual block
|
||||||
|
- status-sizes: status queue size of per virtual block
|
||||||
|
- queue-sizes: command queue size of per virtual block, the size number
|
||||||
|
based on queues
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
|
||||||
|
- dma-channels: Number of DMA channels supported by the controller.
|
||||||
|
- big-endian: If present registers and hardware scatter/gather descriptors
|
||||||
|
of the qDMA are implemented in big endian mode, otherwise in little
|
||||||
|
mode.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
qdma: dma-controller@8390000 {
|
||||||
|
compatible = "fsl,ls1021a-qdma";
|
||||||
|
reg = <0x0 0x8388000 0x0 0x1000>, /* Controller regs */
|
||||||
|
<0x0 0x8389000 0x0 0x1000>, /* Status regs */
|
||||||
|
<0x0 0x838a000 0x0 0x2000>; /* Block regs */
|
||||||
|
interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-names = "qdma-error",
|
||||||
|
"qdma-queue0", "qdma-queue1";
|
||||||
|
dma-channels = <8>;
|
||||||
|
block-number = <2>;
|
||||||
|
block-offset = <0x1000>;
|
||||||
|
fsl,dma-queues = <2>;
|
||||||
|
status-sizes = <64>;
|
||||||
|
queue-sizes = <64 64>;
|
||||||
|
big-endian;
|
||||||
|
};
|
||||||
|
|
||||||
|
DMA clients must use the format described in dma/dma.txt file.
|
@ -218,6 +218,20 @@ config FSL_EDMA
|
|||||||
multiplexing capability for DMA request sources(slot).
|
multiplexing capability for DMA request sources(slot).
|
||||||
This module can be found on Freescale Vybrid and LS-1 SoCs.
|
This module can be found on Freescale Vybrid and LS-1 SoCs.
|
||||||
|
|
||||||
|
config FSL_QDMA
|
||||||
|
tristate "NXP Layerscape qDMA engine support"
|
||||||
|
depends on ARM || ARM64
|
||||||
|
select DMA_ENGINE
|
||||||
|
select DMA_VIRTUAL_CHANNELS
|
||||||
|
select DMA_ENGINE_RAID
|
||||||
|
select ASYNC_TX_ENABLE_CHANNEL_SWITCH
|
||||||
|
help
|
||||||
|
Support the NXP Layerscape qDMA engine with command queue and legacy mode.
|
||||||
|
Channel virtualization is supported through enqueuing of DMA jobs to,
|
||||||
|
or dequeuing DMA jobs from, different work queues.
|
||||||
|
This module can be found on NXP Layerscape SoCs.
|
||||||
|
The qdma driver only work on SoCs with a DPAA hardware block.
|
||||||
|
|
||||||
config FSL_RAID
|
config FSL_RAID
|
||||||
tristate "Freescale RAID engine Support"
|
tristate "Freescale RAID engine Support"
|
||||||
depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH
|
depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH
|
||||||
|
@ -33,6 +33,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
|
|||||||
obj-$(CONFIG_FSL_DMA) += fsldma.o
|
obj-$(CONFIG_FSL_DMA) += fsldma.o
|
||||||
obj-$(CONFIG_FSL_EDMA) += fsl-edma.o fsl-edma-common.o
|
obj-$(CONFIG_FSL_EDMA) += fsl-edma.o fsl-edma-common.o
|
||||||
obj-$(CONFIG_MCF_EDMA) += mcf-edma.o fsl-edma-common.o
|
obj-$(CONFIG_MCF_EDMA) += mcf-edma.o fsl-edma-common.o
|
||||||
|
obj-$(CONFIG_FSL_QDMA) += fsl-qdma.o
|
||||||
obj-$(CONFIG_FSL_RAID) += fsl_raid.o
|
obj-$(CONFIG_FSL_RAID) += fsl_raid.o
|
||||||
obj-$(CONFIG_HSU_DMA) += hsu/
|
obj-$(CONFIG_HSU_DMA) += hsu/
|
||||||
obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o
|
obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <linux/dmapool.h>
|
#include <linux/dmapool.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
#include "fsl-edma-common.h"
|
#include "fsl-edma-common.h"
|
||||||
|
|
||||||
@ -173,12 +174,62 @@ int fsl_edma_resume(struct dma_chan *chan)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(fsl_edma_resume);
|
EXPORT_SYMBOL_GPL(fsl_edma_resume);
|
||||||
|
|
||||||
|
static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_chan)
|
||||||
|
{
|
||||||
|
if (fsl_chan->dma_dir != DMA_NONE)
|
||||||
|
dma_unmap_resource(fsl_chan->vchan.chan.device->dev,
|
||||||
|
fsl_chan->dma_dev_addr,
|
||||||
|
fsl_chan->dma_dev_size,
|
||||||
|
fsl_chan->dma_dir, 0);
|
||||||
|
fsl_chan->dma_dir = DMA_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fsl_edma_prep_slave_dma(struct fsl_edma_chan *fsl_chan,
|
||||||
|
enum dma_transfer_direction dir)
|
||||||
|
{
|
||||||
|
struct device *dev = fsl_chan->vchan.chan.device->dev;
|
||||||
|
enum dma_data_direction dma_dir;
|
||||||
|
phys_addr_t addr = 0;
|
||||||
|
u32 size = 0;
|
||||||
|
|
||||||
|
switch (dir) {
|
||||||
|
case DMA_MEM_TO_DEV:
|
||||||
|
dma_dir = DMA_FROM_DEVICE;
|
||||||
|
addr = fsl_chan->cfg.dst_addr;
|
||||||
|
size = fsl_chan->cfg.dst_maxburst;
|
||||||
|
break;
|
||||||
|
case DMA_DEV_TO_MEM:
|
||||||
|
dma_dir = DMA_TO_DEVICE;
|
||||||
|
addr = fsl_chan->cfg.src_addr;
|
||||||
|
size = fsl_chan->cfg.src_maxburst;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dma_dir = DMA_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Already mapped for this config? */
|
||||||
|
if (fsl_chan->dma_dir == dma_dir)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fsl_edma_unprep_slave_dma(fsl_chan);
|
||||||
|
|
||||||
|
fsl_chan->dma_dev_addr = dma_map_resource(dev, addr, size, dma_dir, 0);
|
||||||
|
if (dma_mapping_error(dev, fsl_chan->dma_dev_addr))
|
||||||
|
return false;
|
||||||
|
fsl_chan->dma_dev_size = size;
|
||||||
|
fsl_chan->dma_dir = dma_dir;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int fsl_edma_slave_config(struct dma_chan *chan,
|
int fsl_edma_slave_config(struct dma_chan *chan,
|
||||||
struct dma_slave_config *cfg)
|
struct dma_slave_config *cfg)
|
||||||
{
|
{
|
||||||
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
|
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
|
||||||
|
|
||||||
memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg));
|
memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg));
|
||||||
|
fsl_edma_unprep_slave_dma(fsl_chan);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -339,9 +390,7 @@ static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan,
|
|||||||
struct fsl_edma_desc *fsl_desc;
|
struct fsl_edma_desc *fsl_desc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fsl_desc = kzalloc(sizeof(*fsl_desc) +
|
fsl_desc = kzalloc(struct_size(fsl_desc, tcd, sg_len), GFP_NOWAIT);
|
||||||
sizeof(struct fsl_edma_sw_tcd) *
|
|
||||||
sg_len, GFP_NOWAIT);
|
|
||||||
if (!fsl_desc)
|
if (!fsl_desc)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -378,6 +427,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
|
|||||||
if (!is_slave_direction(direction))
|
if (!is_slave_direction(direction))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
sg_len = buf_len / period_len;
|
sg_len = buf_len / period_len;
|
||||||
fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
|
fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
|
||||||
if (!fsl_desc)
|
if (!fsl_desc)
|
||||||
@ -409,11 +461,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
|
|||||||
|
|
||||||
if (direction == DMA_MEM_TO_DEV) {
|
if (direction == DMA_MEM_TO_DEV) {
|
||||||
src_addr = dma_buf_next;
|
src_addr = dma_buf_next;
|
||||||
dst_addr = fsl_chan->cfg.dst_addr;
|
dst_addr = fsl_chan->dma_dev_addr;
|
||||||
soff = fsl_chan->cfg.dst_addr_width;
|
soff = fsl_chan->cfg.dst_addr_width;
|
||||||
doff = 0;
|
doff = 0;
|
||||||
} else {
|
} else {
|
||||||
src_addr = fsl_chan->cfg.src_addr;
|
src_addr = fsl_chan->dma_dev_addr;
|
||||||
dst_addr = dma_buf_next;
|
dst_addr = dma_buf_next;
|
||||||
soff = 0;
|
soff = 0;
|
||||||
doff = fsl_chan->cfg.src_addr_width;
|
doff = fsl_chan->cfg.src_addr_width;
|
||||||
@ -444,6 +496,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
|
|||||||
if (!is_slave_direction(direction))
|
if (!is_slave_direction(direction))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
|
fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
|
||||||
if (!fsl_desc)
|
if (!fsl_desc)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -468,11 +523,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
|
|||||||
|
|
||||||
if (direction == DMA_MEM_TO_DEV) {
|
if (direction == DMA_MEM_TO_DEV) {
|
||||||
src_addr = sg_dma_address(sg);
|
src_addr = sg_dma_address(sg);
|
||||||
dst_addr = fsl_chan->cfg.dst_addr;
|
dst_addr = fsl_chan->dma_dev_addr;
|
||||||
soff = fsl_chan->cfg.dst_addr_width;
|
soff = fsl_chan->cfg.dst_addr_width;
|
||||||
doff = 0;
|
doff = 0;
|
||||||
} else {
|
} else {
|
||||||
src_addr = fsl_chan->cfg.src_addr;
|
src_addr = fsl_chan->dma_dev_addr;
|
||||||
dst_addr = sg_dma_address(sg);
|
dst_addr = sg_dma_address(sg);
|
||||||
soff = 0;
|
soff = 0;
|
||||||
doff = fsl_chan->cfg.src_addr_width;
|
doff = fsl_chan->cfg.src_addr_width;
|
||||||
@ -555,6 +610,7 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan)
|
|||||||
fsl_edma_chan_mux(fsl_chan, 0, false);
|
fsl_edma_chan_mux(fsl_chan, 0, false);
|
||||||
fsl_chan->edesc = NULL;
|
fsl_chan->edesc = NULL;
|
||||||
vchan_get_all_descriptors(&fsl_chan->vchan, &head);
|
vchan_get_all_descriptors(&fsl_chan->vchan, &head);
|
||||||
|
fsl_edma_unprep_slave_dma(fsl_chan);
|
||||||
spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
|
spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
|
||||||
|
|
||||||
vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
|
vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#ifndef _FSL_EDMA_COMMON_H_
|
#ifndef _FSL_EDMA_COMMON_H_
|
||||||
#define _FSL_EDMA_COMMON_H_
|
#define _FSL_EDMA_COMMON_H_
|
||||||
|
|
||||||
|
#include <linux/dma-direction.h>
|
||||||
#include "virt-dma.h"
|
#include "virt-dma.h"
|
||||||
|
|
||||||
#define EDMA_CR_EDBG BIT(1)
|
#define EDMA_CR_EDBG BIT(1)
|
||||||
@ -120,6 +121,9 @@ struct fsl_edma_chan {
|
|||||||
struct dma_slave_config cfg;
|
struct dma_slave_config cfg;
|
||||||
u32 attr;
|
u32 attr;
|
||||||
struct dma_pool *tcd_pool;
|
struct dma_pool *tcd_pool;
|
||||||
|
dma_addr_t dma_dev_addr;
|
||||||
|
u32 dma_dev_size;
|
||||||
|
enum dma_data_direction dma_dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fsl_edma_desc {
|
struct fsl_edma_desc {
|
||||||
|
@ -254,6 +254,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
|||||||
fsl_chan->pm_state = RUNNING;
|
fsl_chan->pm_state = RUNNING;
|
||||||
fsl_chan->slave_id = 0;
|
fsl_chan->slave_id = 0;
|
||||||
fsl_chan->idle = true;
|
fsl_chan->idle = true;
|
||||||
|
fsl_chan->dma_dir = DMA_NONE;
|
||||||
fsl_chan->vchan.desc_free = fsl_edma_free_desc;
|
fsl_chan->vchan.desc_free = fsl_edma_free_desc;
|
||||||
vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);
|
vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);
|
||||||
|
|
||||||
|
1259
drivers/dma/fsl-qdma.c
Normal file
1259
drivers/dma/fsl-qdma.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -53,42 +53,42 @@ static const char msg_ld_oom[] = "No free memory for link descriptor";
|
|||||||
|
|
||||||
static void set_sr(struct fsldma_chan *chan, u32 val)
|
static void set_sr(struct fsldma_chan *chan, u32 val)
|
||||||
{
|
{
|
||||||
DMA_OUT(chan, &chan->regs->sr, val, 32);
|
FSL_DMA_OUT(chan, &chan->regs->sr, val, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 get_sr(struct fsldma_chan *chan)
|
static u32 get_sr(struct fsldma_chan *chan)
|
||||||
{
|
{
|
||||||
return DMA_IN(chan, &chan->regs->sr, 32);
|
return FSL_DMA_IN(chan, &chan->regs->sr, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_mr(struct fsldma_chan *chan, u32 val)
|
static void set_mr(struct fsldma_chan *chan, u32 val)
|
||||||
{
|
{
|
||||||
DMA_OUT(chan, &chan->regs->mr, val, 32);
|
FSL_DMA_OUT(chan, &chan->regs->mr, val, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 get_mr(struct fsldma_chan *chan)
|
static u32 get_mr(struct fsldma_chan *chan)
|
||||||
{
|
{
|
||||||
return DMA_IN(chan, &chan->regs->mr, 32);
|
return FSL_DMA_IN(chan, &chan->regs->mr, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_cdar(struct fsldma_chan *chan, dma_addr_t addr)
|
static void set_cdar(struct fsldma_chan *chan, dma_addr_t addr)
|
||||||
{
|
{
|
||||||
DMA_OUT(chan, &chan->regs->cdar, addr | FSL_DMA_SNEN, 64);
|
FSL_DMA_OUT(chan, &chan->regs->cdar, addr | FSL_DMA_SNEN, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dma_addr_t get_cdar(struct fsldma_chan *chan)
|
static dma_addr_t get_cdar(struct fsldma_chan *chan)
|
||||||
{
|
{
|
||||||
return DMA_IN(chan, &chan->regs->cdar, 64) & ~FSL_DMA_SNEN;
|
return FSL_DMA_IN(chan, &chan->regs->cdar, 64) & ~FSL_DMA_SNEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_bcr(struct fsldma_chan *chan, u32 val)
|
static void set_bcr(struct fsldma_chan *chan, u32 val)
|
||||||
{
|
{
|
||||||
DMA_OUT(chan, &chan->regs->bcr, val, 32);
|
FSL_DMA_OUT(chan, &chan->regs->bcr, val, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 get_bcr(struct fsldma_chan *chan)
|
static u32 get_bcr(struct fsldma_chan *chan)
|
||||||
{
|
{
|
||||||
return DMA_IN(chan, &chan->regs->bcr, 32);
|
return FSL_DMA_IN(chan, &chan->regs->bcr, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -196,39 +196,67 @@ struct fsldma_chan {
|
|||||||
#define to_fsl_desc(lh) container_of(lh, struct fsl_desc_sw, node)
|
#define to_fsl_desc(lh) container_of(lh, struct fsl_desc_sw, node)
|
||||||
#define tx_to_fsl_desc(tx) container_of(tx, struct fsl_desc_sw, async_tx)
|
#define tx_to_fsl_desc(tx) container_of(tx, struct fsl_desc_sw, async_tx)
|
||||||
|
|
||||||
#ifndef __powerpc64__
|
#ifdef CONFIG_PPC
|
||||||
static u64 in_be64(const u64 __iomem *addr)
|
#define fsl_ioread32(p) in_le32(p)
|
||||||
|
#define fsl_ioread32be(p) in_be32(p)
|
||||||
|
#define fsl_iowrite32(v, p) out_le32(p, v)
|
||||||
|
#define fsl_iowrite32be(v, p) out_be32(p, v)
|
||||||
|
|
||||||
|
#ifdef __powerpc64__
|
||||||
|
#define fsl_ioread64(p) in_le64(p)
|
||||||
|
#define fsl_ioread64be(p) in_be64(p)
|
||||||
|
#define fsl_iowrite64(v, p) out_le64(p, v)
|
||||||
|
#define fsl_iowrite64be(v, p) out_be64(p, v)
|
||||||
|
#else
|
||||||
|
static u64 fsl_ioread64(const u64 __iomem *addr)
|
||||||
{
|
{
|
||||||
return ((u64)in_be32((u32 __iomem *)addr) << 32) |
|
u32 fsl_addr = lower_32_bits(addr);
|
||||||
(in_be32((u32 __iomem *)addr + 1));
|
u64 fsl_addr_hi = (u64)in_le32((u32 *)(fsl_addr + 1)) << 32;
|
||||||
|
|
||||||
|
return fsl_addr_hi | in_le32((u32 *)fsl_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void out_be64(u64 __iomem *addr, u64 val)
|
static void fsl_iowrite64(u64 val, u64 __iomem *addr)
|
||||||
{
|
|
||||||
out_be32((u32 __iomem *)addr, val >> 32);
|
|
||||||
out_be32((u32 __iomem *)addr + 1, (u32)val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* There is no asm instructions for 64 bits reverse loads and stores */
|
|
||||||
static u64 in_le64(const u64 __iomem *addr)
|
|
||||||
{
|
|
||||||
return ((u64)in_le32((u32 __iomem *)addr + 1) << 32) |
|
|
||||||
(in_le32((u32 __iomem *)addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void out_le64(u64 __iomem *addr, u64 val)
|
|
||||||
{
|
{
|
||||||
out_le32((u32 __iomem *)addr + 1, val >> 32);
|
out_le32((u32 __iomem *)addr + 1, val >> 32);
|
||||||
out_le32((u32 __iomem *)addr, (u32)val);
|
out_le32((u32 __iomem *)addr, (u32)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 fsl_ioread64be(const u64 __iomem *addr)
|
||||||
|
{
|
||||||
|
u32 fsl_addr = lower_32_bits(addr);
|
||||||
|
u64 fsl_addr_hi = (u64)in_be32((u32 *)fsl_addr) << 32;
|
||||||
|
|
||||||
|
return fsl_addr_hi | in_be32((u32 *)(fsl_addr + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fsl_iowrite64be(u64 val, u64 __iomem *addr)
|
||||||
|
{
|
||||||
|
out_be32((u32 __iomem *)addr, val >> 32);
|
||||||
|
out_be32((u32 __iomem *)addr + 1, (u32)val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DMA_IN(fsl_chan, addr, width) \
|
#if defined(CONFIG_ARM64) || defined(CONFIG_ARM)
|
||||||
(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
|
#define fsl_ioread32(p) ioread32(p)
|
||||||
in_be##width(addr) : in_le##width(addr))
|
#define fsl_ioread32be(p) ioread32be(p)
|
||||||
#define DMA_OUT(fsl_chan, addr, val, width) \
|
#define fsl_iowrite32(v, p) iowrite32(v, p)
|
||||||
(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
|
#define fsl_iowrite32be(v, p) iowrite32be(v, p)
|
||||||
out_be##width(addr, val) : out_le##width(addr, val))
|
#define fsl_ioread64(p) ioread64(p)
|
||||||
|
#define fsl_ioread64be(p) ioread64be(p)
|
||||||
|
#define fsl_iowrite64(v, p) iowrite64(v, p)
|
||||||
|
#define fsl_iowrite64be(v, p) iowrite64be(v, p)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FSL_DMA_IN(fsl_dma, addr, width) \
|
||||||
|
(((fsl_dma)->feature & FSL_DMA_BIG_ENDIAN) ? \
|
||||||
|
fsl_ioread##width##be(addr) : fsl_ioread##width(addr))
|
||||||
|
|
||||||
|
#define FSL_DMA_OUT(fsl_dma, addr, val, width) \
|
||||||
|
(((fsl_dma)->feature & FSL_DMA_BIG_ENDIAN) ? \
|
||||||
|
fsl_iowrite##width##be(val, addr) : fsl_iowrite \
|
||||||
|
##width(val, addr))
|
||||||
|
|
||||||
#define DMA_TO_CPU(fsl_chan, d, width) \
|
#define DMA_TO_CPU(fsl_chan, d, width) \
|
||||||
(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
|
(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
|
||||||
|
@ -214,6 +214,7 @@ static int mcf_edma_probe(struct platform_device *pdev)
|
|||||||
mcf_chan->edma = mcf_edma;
|
mcf_chan->edma = mcf_edma;
|
||||||
mcf_chan->slave_id = i;
|
mcf_chan->slave_id = i;
|
||||||
mcf_chan->idle = true;
|
mcf_chan->idle = true;
|
||||||
|
mcf_chan->dma_dir = DMA_NONE;
|
||||||
mcf_chan->vchan.desc_free = fsl_edma_free_desc;
|
mcf_chan->vchan.desc_free = fsl_edma_free_desc;
|
||||||
vchan_init(&mcf_chan->vchan, &mcf_edma->dma_dev);
|
vchan_init(&mcf_chan->vchan, &mcf_edma->dma_dev);
|
||||||
iowrite32(0x0, ®s->tcd[i].csr);
|
iowrite32(0x0, ®s->tcd[i].csr);
|
||||||
|
Loading…
Reference in New Issue
Block a user