Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
79074168
Commit
79074168
authored
Mar 12, 2019
by
Vinod Koul
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/fsl' into for-linus
parents
278489c2
6175f6a7
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1456 additions
and
35 deletions
+1456
-35
Documentation/devicetree/bindings/dma/fsl-qdma.txt
Documentation/devicetree/bindings/dma/fsl-qdma.txt
+57
-0
drivers/dma/Kconfig
drivers/dma/Kconfig
+14
-0
drivers/dma/Makefile
drivers/dma/Makefile
+1
-0
drivers/dma/fsl-edma-common.c
drivers/dma/fsl-edma-common.c
+63
-7
drivers/dma/fsl-edma-common.h
drivers/dma/fsl-edma-common.h
+4
-0
drivers/dma/fsl-edma.c
drivers/dma/fsl-edma.c
+1
-0
drivers/dma/fsl-qdma.c
drivers/dma/fsl-qdma.c
+1259
-0
drivers/dma/fsldma.c
drivers/dma/fsldma.c
+8
-8
drivers/dma/fsldma.h
drivers/dma/fsldma.h
+48
-20
drivers/dma/mcf-edma.c
drivers/dma/mcf-edma.c
+1
-0
No files found.
Documentation/devicetree/bindings/dma/fsl-qdma.txt
0 → 100644
View file @
79074168
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.
drivers/dma/Kconfig
View file @
79074168
...
...
@@ -218,6 +218,20 @@ config FSL_EDMA
multiplexing capability for DMA request sources(slot).
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
tristate "Freescale RAID engine Support"
depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH
...
...
drivers/dma/Makefile
View file @
79074168
...
...
@@ -33,6 +33,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
obj-$(CONFIG_FSL_DMA)
+=
fsldma.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_FSL_QDMA)
+=
fsl-qdma.o
obj-$(CONFIG_FSL_RAID)
+=
fsl_raid.o
obj-$(CONFIG_HSU_DMA)
+=
hsu/
obj-$(CONFIG_IMG_MDC_DMA)
+=
img-mdc-dma.o
...
...
drivers/dma/fsl-edma-common.c
View file @
79074168
...
...
@@ -6,6 +6,7 @@
#include <linux/dmapool.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include "fsl-edma-common.h"
...
...
@@ -173,12 +174,62 @@ int fsl_edma_resume(struct dma_chan *chan)
}
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
,
struct
dma_slave_config
*
cfg
)
{
struct
fsl_edma_chan
*
fsl_chan
=
to_fsl_edma_chan
(
chan
);
memcpy
(
&
fsl_chan
->
cfg
,
cfg
,
sizeof
(
*
cfg
));
fsl_edma_unprep_slave_dma
(
fsl_chan
);
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
;
int
i
;
fsl_desc
=
kzalloc
(
sizeof
(
*
fsl_desc
)
+
sizeof
(
struct
fsl_edma_sw_tcd
)
*
sg_len
,
GFP_NOWAIT
);
fsl_desc
=
kzalloc
(
struct_size
(
fsl_desc
,
tcd
,
sg_len
),
GFP_NOWAIT
);
if
(
!
fsl_desc
)
return
NULL
;
...
...
@@ -378,6 +427,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
if
(
!
is_slave_direction
(
direction
))
return
NULL
;
if
(
!
fsl_edma_prep_slave_dma
(
fsl_chan
,
direction
))
return
NULL
;
sg_len
=
buf_len
/
period_len
;
fsl_desc
=
fsl_edma_alloc_desc
(
fsl_chan
,
sg_len
);
if
(
!
fsl_desc
)
...
...
@@ -409,11 +461,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
if
(
direction
==
DMA_MEM_TO_DEV
)
{
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
;
doff
=
0
;
}
else
{
src_addr
=
fsl_chan
->
cfg
.
src
_addr
;
src_addr
=
fsl_chan
->
dma_dev
_addr
;
dst_addr
=
dma_buf_next
;
soff
=
0
;
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
))
return
NULL
;
if
(
!
fsl_edma_prep_slave_dma
(
fsl_chan
,
direction
))
return
NULL
;
fsl_desc
=
fsl_edma_alloc_desc
(
fsl_chan
,
sg_len
);
if
(
!
fsl_desc
)
return
NULL
;
...
...
@@ -468,11 +523,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
if
(
direction
==
DMA_MEM_TO_DEV
)
{
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
;
doff
=
0
;
}
else
{
src_addr
=
fsl_chan
->
cfg
.
src
_addr
;
src_addr
=
fsl_chan
->
dma_dev
_addr
;
dst_addr
=
sg_dma_address
(
sg
);
soff
=
0
;
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_chan
->
edesc
=
NULL
;
vchan_get_all_descriptors
(
&
fsl_chan
->
vchan
,
&
head
);
fsl_edma_unprep_slave_dma
(
fsl_chan
);
spin_unlock_irqrestore
(
&
fsl_chan
->
vchan
.
lock
,
flags
);
vchan_dma_desc_free_list
(
&
fsl_chan
->
vchan
,
&
head
);
...
...
drivers/dma/fsl-edma-common.h
View file @
79074168
...
...
@@ -6,6 +6,7 @@
#ifndef _FSL_EDMA_COMMON_H_
#define _FSL_EDMA_COMMON_H_
#include <linux/dma-direction.h>
#include "virt-dma.h"
#define EDMA_CR_EDBG BIT(1)
...
...
@@ -120,6 +121,9 @@ struct fsl_edma_chan {
struct
dma_slave_config
cfg
;
u32
attr
;
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
{
...
...
drivers/dma/fsl-edma.c
View file @
79074168
...
...
@@ -254,6 +254,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
fsl_chan
->
pm_state
=
RUNNING
;
fsl_chan
->
slave_id
=
0
;
fsl_chan
->
idle
=
true
;
fsl_chan
->
dma_dir
=
DMA_NONE
;
fsl_chan
->
vchan
.
desc_free
=
fsl_edma_free_desc
;
vchan_init
(
&
fsl_chan
->
vchan
,
&
fsl_edma
->
dma_dev
);
...
...
drivers/dma/fsl-qdma.c
0 → 100644
View file @
79074168
This diff is collapsed.
Click to expand it.
drivers/dma/fsldma.c
View file @
79074168
...
...
@@ -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
)
{
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
)
{
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
)
{
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
)
{
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
)
{
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
)
{
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
)
{
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
)
{
return
DMA_IN
(
chan
,
&
chan
->
regs
->
bcr
,
32
);
return
FSL_
DMA_IN
(
chan
,
&
chan
->
regs
->
bcr
,
32
);
}
/*
...
...
drivers/dma/fsldma.h
View file @
79074168
...
...
@@ -196,39 +196,67 @@ struct fsldma_chan {
#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)
#ifndef __powerpc64__
static
u64
in_be64
(
const
u64
__iomem
*
addr
)
#ifdef CONFIG_PPC
#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
)
|
(
in_be32
((
u32
__iomem
*
)
addr
+
1
));
u32
fsl_addr
=
lower_32_bits
(
addr
);
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
);
out_
le32
((
u32
__iomem
*
)
addr
+
1
,
val
>>
32
);
out_
le32
((
u32
__iomem
*
)
addr
,
(
u32
)
val
);
}
/* There is no asm instructions for 64 bits reverse loads and stores */
static
u64
in_le64
(
const
u64
__iomem
*
addr
)
static
u64
fsl_ioread64be
(
const
u64
__iomem
*
addr
)
{
return
((
u64
)
in_le32
((
u32
__iomem
*
)
addr
+
1
)
<<
32
)
|
(
in_le32
((
u32
__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
out_le64
(
u64
__iomem
*
addr
,
u64
val
)
static
void
fsl_iowrite64be
(
u64
val
,
u64
__iomem
*
addr
)
{
out_
le32
((
u32
__iomem
*
)
addr
+
1
,
val
>>
32
);
out_
le32
((
u32
__iomem
*
)
addr
,
(
u32
)
val
);
out_
be32
((
u32
__iomem
*
)
addr
,
val
>>
32
);
out_
be32
((
u32
__iomem
*
)
addr
+
1
,
(
u32
)
val
);
}
#endif
#endif
#define DMA_IN(fsl_chan, addr, width) \
(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
in_be##width(addr) : in_le##width(addr))
#define DMA_OUT(fsl_chan, addr, val, width) \
(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
out_be##width(addr, val) : out_le##width(addr, val))
#if defined(CONFIG_ARM64) || defined(CONFIG_ARM)
#define fsl_ioread32(p) ioread32(p)
#define fsl_ioread32be(p) ioread32be(p)
#define fsl_iowrite32(v, p) iowrite32(v, p)
#define fsl_iowrite32be(v, p) iowrite32be(v, p)
#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) \
(((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
...
...
drivers/dma/mcf-edma.c
View file @
79074168
...
...
@@ -214,6 +214,7 @@ static int mcf_edma_probe(struct platform_device *pdev)
mcf_chan
->
edma
=
mcf_edma
;
mcf_chan
->
slave_id
=
i
;
mcf_chan
->
idle
=
true
;
mcf_chan
->
dma_dir
=
DMA_NONE
;
mcf_chan
->
vchan
.
desc_free
=
fsl_edma_free_desc
;
vchan_init
(
&
mcf_chan
->
vchan
,
&
mcf_edma
->
dma_dev
);
iowrite32
(
0x0
,
&
regs
->
tcd
[
i
].
csr
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment