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
278489c2
Commit
278489c2
authored
5 years ago
by
Vinod Koul
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/dw' into for-linus
parents
5c196f5e
bdcb2c5d
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
426 additions
and
266 deletions
+426
-266
Documentation/devicetree/bindings/dma/snps-dma.txt
Documentation/devicetree/bindings/dma/snps-dma.txt
+0
-2
drivers/dma/dw-axi-dmac/dw-axi-dmac.h
drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+1
-1
drivers/dma/dw/Kconfig
drivers/dma/dw/Kconfig
+2
-0
drivers/dma/dw/Makefile
drivers/dma/dw/Makefile
+1
-1
drivers/dma/dw/core.c
drivers/dma/dw/core.c
+47
-197
drivers/dma/dw/dw.c
drivers/dma/dw/dw.c
+138
-0
drivers/dma/dw/idma32.c
drivers/dma/dw/idma32.c
+160
-0
drivers/dma/dw/internal.h
drivers/dma/dw/internal.h
+9
-6
drivers/dma/dw/pci.c
drivers/dma/dw/pci.c
+31
-22
drivers/dma/dw/platform.c
drivers/dma/dw/platform.c
+5
-17
drivers/dma/dw/regs.h
drivers/dma/dw/regs.h
+26
-4
drivers/tty/serial/8250/8250_lpss.c
drivers/tty/serial/8250/8250_lpss.c
+0
-1
include/linux/dma/dw.h
include/linux/dma/dw.h
+5
-4
include/linux/platform_data/dma-dw.h
include/linux/platform_data/dma-dw.h
+1
-11
No files found.
Documentation/devicetree/bindings/dma/snps-dma.txt
View file @
278489c2
...
...
@@ -23,8 +23,6 @@ Deprecated properties:
Optional properties:
- is_private: The device channels should be marked as private and not for by the
general purpose DMA channel allocator. False if not passed.
- multi-block: Multi block transfers supported by hardware. Array property with
one cell per channel. 0: not supported, 1 (default): supported.
- snps,dma-protection-control: AHB HPROT[3:1] protection setting.
...
...
This diff is collapsed.
Click to expand it.
drivers/dma/dw-axi-dmac/dw-axi-dmac.h
View file @
278489c2
...
...
@@ -75,7 +75,7 @@ struct __packed axi_dma_lli {
__le32
sstat
;
__le32
dstat
;
__le32
status_lo
;
__le32
st
s
tus_hi
;
__le32
st
a
tus_hi
;
__le32
reserved_lo
;
__le32
reserved_hi
;
};
...
...
This diff is collapsed.
Click to expand it.
drivers/dma/dw/Kconfig
View file @
278489c2
# SPDX-License-Identifier: GPL-2.0
#
# DMA engine configuration for dw
#
...
...
This diff is collapsed.
Click to expand it.
drivers/dma/dw/Makefile
View file @
278489c2
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_DW_DMAC_CORE)
+=
dw_dmac_core.o
dw_dmac_core-objs
:=
core.o
dw_dmac_core-objs
:=
core.o
dw.o idma32.o
obj-$(CONFIG_DW_DMAC)
+=
dw_dmac.o
dw_dmac-objs
:=
platform.o
...
...
This diff is collapsed.
Click to expand it.
drivers/dma/dw/core.c
View file @
278489c2
// SPDX-License-Identifier: GPL-2.0
/*
* Core driver for the Synopsys DesignWare DMA Controller
*
* Copyright (C) 2007-2008 Atmel Corporation
* Copyright (C) 2010-2011 ST Microelectronics
* Copyright (C) 2013 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/bitops.h>
...
...
@@ -37,27 +34,6 @@
* support descriptor writeback.
*/
#define DWC_DEFAULT_CTLLO(_chan) ({ \
struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \
struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \
bool _is_slave = is_slave_direction(_dwc->direction); \
u8 _smsize = _is_slave ? _sconfig->src_maxburst : \
DW_DMA_MSIZE_16; \
u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \
DW_DMA_MSIZE_16; \
u8 _dms = (_dwc->direction == DMA_MEM_TO_DEV) ? \
_dwc->dws.p_master : _dwc->dws.m_master; \
u8 _sms = (_dwc->direction == DMA_DEV_TO_MEM) ? \
_dwc->dws.p_master : _dwc->dws.m_master; \
\
(DWC_CTLL_DST_MSIZE(_dmsize) \
| DWC_CTLL_SRC_MSIZE(_smsize) \
| DWC_CTLL_LLP_D_EN \
| DWC_CTLL_LLP_S_EN \
| DWC_CTLL_DMS(_dms) \
| DWC_CTLL_SMS(_sms)); \
})
/* The set of bus widths supported by the DMA controller */
#define DW_DMA_BUSWIDTHS \
BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \
...
...
@@ -138,44 +114,6 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
dwc
->
descs_allocated
--
;
}
static
void
dwc_initialize_chan_idma32
(
struct
dw_dma_chan
*
dwc
)
{
u32
cfghi
=
0
;
u32
cfglo
=
0
;
/* Set default burst alignment */
cfglo
|=
IDMA32C_CFGL_DST_BURST_ALIGN
|
IDMA32C_CFGL_SRC_BURST_ALIGN
;
/* Low 4 bits of the request lines */
cfghi
|=
IDMA32C_CFGH_DST_PER
(
dwc
->
dws
.
dst_id
&
0xf
);
cfghi
|=
IDMA32C_CFGH_SRC_PER
(
dwc
->
dws
.
src_id
&
0xf
);
/* Request line extension (2 bits) */
cfghi
|=
IDMA32C_CFGH_DST_PER_EXT
(
dwc
->
dws
.
dst_id
>>
4
&
0x3
);
cfghi
|=
IDMA32C_CFGH_SRC_PER_EXT
(
dwc
->
dws
.
src_id
>>
4
&
0x3
);
channel_writel
(
dwc
,
CFG_LO
,
cfglo
);
channel_writel
(
dwc
,
CFG_HI
,
cfghi
);
}
static
void
dwc_initialize_chan_dw
(
struct
dw_dma_chan
*
dwc
)
{
struct
dw_dma
*
dw
=
to_dw_dma
(
dwc
->
chan
.
device
);
u32
cfghi
=
DWC_CFGH_FIFO_MODE
;
u32
cfglo
=
DWC_CFGL_CH_PRIOR
(
dwc
->
priority
);
bool
hs_polarity
=
dwc
->
dws
.
hs_polarity
;
cfghi
|=
DWC_CFGH_DST_PER
(
dwc
->
dws
.
dst_id
);
cfghi
|=
DWC_CFGH_SRC_PER
(
dwc
->
dws
.
src_id
);
cfghi
|=
DWC_CFGH_PROTCTL
(
dw
->
pdata
->
protctl
);
/* Set polarity of handshake interface */
cfglo
|=
hs_polarity
?
DWC_CFGL_HS_DST_POL
|
DWC_CFGL_HS_SRC_POL
:
0
;
channel_writel
(
dwc
,
CFG_LO
,
cfglo
);
channel_writel
(
dwc
,
CFG_HI
,
cfghi
);
}
static
void
dwc_initialize
(
struct
dw_dma_chan
*
dwc
)
{
struct
dw_dma
*
dw
=
to_dw_dma
(
dwc
->
chan
.
device
);
...
...
@@ -183,10 +121,7 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
if
(
test_bit
(
DW_DMA_IS_INITIALIZED
,
&
dwc
->
flags
))
return
;
if
(
dw
->
pdata
->
is_idma32
)
dwc_initialize_chan_idma32
(
dwc
);
else
dwc_initialize_chan_dw
(
dwc
);
dw
->
initialize_chan
(
dwc
);
/* Enable interrupts */
channel_set_bit
(
dw
,
MASK
.
XFER
,
dwc
->
mask
);
...
...
@@ -215,37 +150,6 @@ static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc)
cpu_relax
();
}
static
u32
bytes2block
(
struct
dw_dma_chan
*
dwc
,
size_t
bytes
,
unsigned
int
width
,
size_t
*
len
)
{
struct
dw_dma
*
dw
=
to_dw_dma
(
dwc
->
chan
.
device
);
u32
block
;
/* Always in bytes for iDMA 32-bit */
if
(
dw
->
pdata
->
is_idma32
)
width
=
0
;
if
((
bytes
>>
width
)
>
dwc
->
block_size
)
{
block
=
dwc
->
block_size
;
*
len
=
block
<<
width
;
}
else
{
block
=
bytes
>>
width
;
*
len
=
bytes
;
}
return
block
;
}
static
size_t
block2bytes
(
struct
dw_dma_chan
*
dwc
,
u32
block
,
u32
width
)
{
struct
dw_dma
*
dw
=
to_dw_dma
(
dwc
->
chan
.
device
);
if
(
dw
->
pdata
->
is_idma32
)
return
IDMA32C_CTLH_BLOCK_TS
(
block
);
return
DWC_CTLH_BLOCK_TS
(
block
)
<<
width
;
}
/*----------------------------------------------------------------------*/
/* Perform single block transfer */
...
...
@@ -391,10 +295,11 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
/* Returns how many bytes were already received from source */
static
inline
u32
dwc_get_sent
(
struct
dw_dma_chan
*
dwc
)
{
struct
dw_dma
*
dw
=
to_dw_dma
(
dwc
->
chan
.
device
);
u32
ctlhi
=
channel_readl
(
dwc
,
CTL_HI
);
u32
ctllo
=
channel_readl
(
dwc
,
CTL_LO
);
return
block2bytes
(
dwc
,
ctlhi
,
ctllo
>>
4
&
7
);
return
dw
->
block2bytes
(
dwc
,
ctlhi
,
ctllo
>>
4
&
7
);
}
static
void
dwc_scan_descriptors
(
struct
dw_dma
*
dw
,
struct
dw_dma_chan
*
dwc
)
...
...
@@ -651,7 +556,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
unsigned
int
src_width
;
unsigned
int
dst_width
;
unsigned
int
data_width
=
dw
->
pdata
->
data_width
[
m_master
];
u32
ctllo
;
u32
ctllo
,
ctlhi
;
u8
lms
=
DWC_LLP_LMS
(
m_master
);
dev_vdbg
(
chan2dev
(
chan
),
...
...
@@ -667,7 +572,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
src_width
=
dst_width
=
__ffs
(
data_width
|
src
|
dest
|
len
);
ctllo
=
DWC_DEFAULT_CTLLO
(
chan
)
ctllo
=
dw
->
prepare_ctllo
(
dwc
)
|
DWC_CTLL_DST_WIDTH
(
dst_width
)
|
DWC_CTLL_SRC_WIDTH
(
src_width
)
|
DWC_CTLL_DST_INC
...
...
@@ -680,10 +585,12 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
if
(
!
desc
)
goto
err_desc_get
;
ctlhi
=
dw
->
bytes2block
(
dwc
,
len
-
offset
,
src_width
,
&
xfer_count
);
lli_write
(
desc
,
sar
,
src
+
offset
);
lli_write
(
desc
,
dar
,
dest
+
offset
);
lli_write
(
desc
,
ctllo
,
ctllo
);
lli_write
(
desc
,
ctlhi
,
bytes2block
(
dwc
,
len
-
offset
,
src_width
,
&
xfer_count
)
);
lli_write
(
desc
,
ctlhi
,
ctlhi
);
desc
->
len
=
xfer_count
;
if
(
!
first
)
{
...
...
@@ -721,7 +628,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
struct
dma_slave_config
*
sconfig
=
&
dwc
->
dma_sconfig
;
struct
dw_desc
*
prev
;
struct
dw_desc
*
first
;
u32
ctllo
;
u32
ctllo
,
ctlhi
;
u8
m_master
=
dwc
->
dws
.
m_master
;
u8
lms
=
DWC_LLP_LMS
(
m_master
);
dma_addr_t
reg
;
...
...
@@ -745,10 +652,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
case
DMA_MEM_TO_DEV
:
reg_width
=
__ffs
(
sconfig
->
dst_addr_width
);
reg
=
sconfig
->
dst_addr
;
ctllo
=
(
DWC_DEFAULT_CTLLO
(
chan
)
ctllo
=
dw
->
prepare_ctllo
(
dwc
)
|
DWC_CTLL_DST_WIDTH
(
reg_width
)
|
DWC_CTLL_DST_FIX
|
DWC_CTLL_SRC_INC
)
;
|
DWC_CTLL_SRC_INC
;
ctllo
|=
sconfig
->
device_fc
?
DWC_CTLL_FC
(
DW_DMA_FC_P_M2P
)
:
DWC_CTLL_FC
(
DW_DMA_FC_D_M2P
);
...
...
@@ -768,9 +675,11 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
if
(
!
desc
)
goto
err_desc_get
;
ctlhi
=
dw
->
bytes2block
(
dwc
,
len
,
mem_width
,
&
dlen
);
lli_write
(
desc
,
sar
,
mem
);
lli_write
(
desc
,
dar
,
reg
);
lli_write
(
desc
,
ctlhi
,
bytes2block
(
dwc
,
len
,
mem_width
,
&
dlen
)
);
lli_write
(
desc
,
ctlhi
,
ctlhi
);
lli_write
(
desc
,
ctllo
,
ctllo
|
DWC_CTLL_SRC_WIDTH
(
mem_width
));
desc
->
len
=
dlen
;
...
...
@@ -793,10 +702,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
case
DMA_DEV_TO_MEM
:
reg_width
=
__ffs
(
sconfig
->
src_addr_width
);
reg
=
sconfig
->
src_addr
;
ctllo
=
(
DWC_DEFAULT_CTLLO
(
chan
)
ctllo
=
dw
->
prepare_ctllo
(
dwc
)
|
DWC_CTLL_SRC_WIDTH
(
reg_width
)
|
DWC_CTLL_DST_INC
|
DWC_CTLL_SRC_FIX
)
;
|
DWC_CTLL_SRC_FIX
;
ctllo
|=
sconfig
->
device_fc
?
DWC_CTLL_FC
(
DW_DMA_FC_P_P2M
)
:
DWC_CTLL_FC
(
DW_DMA_FC_D_P2M
);
...
...
@@ -814,9 +723,11 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
if
(
!
desc
)
goto
err_desc_get
;
ctlhi
=
dw
->
bytes2block
(
dwc
,
len
,
reg_width
,
&
dlen
);
lli_write
(
desc
,
sar
,
reg
);
lli_write
(
desc
,
dar
,
mem
);
lli_write
(
desc
,
ctlhi
,
bytes2block
(
dwc
,
len
,
reg_width
,
&
dlen
)
);
lli_write
(
desc
,
ctlhi
,
ctlhi
);
mem_width
=
__ffs
(
data_width
|
mem
|
dlen
);
lli_write
(
desc
,
ctllo
,
ctllo
|
DWC_CTLL_DST_WIDTH
(
mem_width
));
desc
->
len
=
dlen
;
...
...
@@ -876,22 +787,12 @@ EXPORT_SYMBOL_GPL(dw_dma_filter);
static
int
dwc_config
(
struct
dma_chan
*
chan
,
struct
dma_slave_config
*
sconfig
)
{
struct
dw_dma_chan
*
dwc
=
to_dw_dma_chan
(
chan
);
struct
dma_slave_config
*
sc
=
&
dwc
->
dma_sconfig
;
struct
dw_dma
*
dw
=
to_dw_dma
(
chan
->
device
);
/*
* Fix sconfig's burst size according to dw_dmac. We need to convert
* them as:
* 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
*
* NOTE: burst size 2 is not supported by DesignWare controller.
* iDMA 32-bit supports it.
*/
u32
s
=
dw
->
pdata
->
is_idma32
?
1
:
2
;
memcpy
(
&
dwc
->
dma_sconfig
,
sconfig
,
sizeof
(
*
sconfig
));
sc
->
src_maxburst
=
sc
->
src_maxburst
>
1
?
fls
(
sc
->
src_maxburst
)
-
s
:
0
;
sc
->
dst_maxburst
=
sc
->
dst_maxburst
>
1
?
fls
(
sc
->
dst_maxburst
)
-
s
:
0
;
dw
->
encode_maxburst
(
dwc
,
&
dwc
->
dma_sconfig
.
src_maxburst
)
;
dw
->
encode_maxburst
(
dwc
,
&
dwc
->
dma_sconfig
.
dst_maxburst
)
;
return
0
;
}
...
...
@@ -900,16 +801,9 @@ static void dwc_chan_pause(struct dw_dma_chan *dwc, bool drain)
{
struct
dw_dma
*
dw
=
to_dw_dma
(
dwc
->
chan
.
device
);
unsigned
int
count
=
20
;
/* timeout iterations */
u32
cfglo
;
cfglo
=
channel_readl
(
dwc
,
CFG_LO
);
if
(
dw
->
pdata
->
is_idma32
)
{
if
(
drain
)
cfglo
|=
IDMA32C_CFGL_CH_DRAIN
;
else
cfglo
&=
~
IDMA32C_CFGL_CH_DRAIN
;
}
channel_writel
(
dwc
,
CFG_LO
,
cfglo
|
DWC_CFGL_CH_SUSP
);
dw
->
suspend_chan
(
dwc
,
drain
);
while
(
!
(
channel_readl
(
dwc
,
CFG_LO
)
&
DWC_CFGL_FIFO_EMPTY
)
&&
count
--
)
udelay
(
2
);
...
...
@@ -928,11 +822,11 @@ static int dwc_pause(struct dma_chan *chan)
return
0
;
}
static
inline
void
dwc_chan_resume
(
struct
dw_dma_chan
*
dwc
)
static
inline
void
dwc_chan_resume
(
struct
dw_dma_chan
*
dwc
,
bool
drain
)
{
u32
cfglo
=
channel_readl
(
dwc
,
CFG_LO
);
struct
dw_dma
*
dw
=
to_dw_dma
(
dwc
->
chan
.
device
);
channel_writel
(
dwc
,
CFG_LO
,
cfglo
&
~
DWC_CFGL_CH_SUSP
);
dw
->
resume_chan
(
dwc
,
drain
);
clear_bit
(
DW_DMA_IS_PAUSED
,
&
dwc
->
flags
);
}
...
...
@@ -945,7 +839,7 @@ static int dwc_resume(struct dma_chan *chan)
spin_lock_irqsave
(
&
dwc
->
lock
,
flags
);
if
(
test_bit
(
DW_DMA_IS_PAUSED
,
&
dwc
->
flags
))
dwc_chan_resume
(
dwc
);
dwc_chan_resume
(
dwc
,
false
);
spin_unlock_irqrestore
(
&
dwc
->
lock
,
flags
);
...
...
@@ -968,7 +862,7 @@ static int dwc_terminate_all(struct dma_chan *chan)
dwc_chan_disable
(
dw
,
dwc
);
dwc_chan_resume
(
dwc
);
dwc_chan_resume
(
dwc
,
true
);
/* active_list entries will end up before queued entries */
list_splice_init
(
&
dwc
->
queue
,
&
list
);
...
...
@@ -1058,33 +952,7 @@ static void dwc_issue_pending(struct dma_chan *chan)
/*----------------------------------------------------------------------*/
/*
* Program FIFO size of channels.
*
* By default full FIFO (512 bytes) is assigned to channel 0. Here we
* slice FIFO on equal parts between channels.
*/
static
void
idma32_fifo_partition
(
struct
dw_dma
*
dw
)
{
u64
value
=
IDMA32C_FP_PSIZE_CH0
(
64
)
|
IDMA32C_FP_PSIZE_CH1
(
64
)
|
IDMA32C_FP_UPDATE
;
u64
fifo_partition
=
0
;
if
(
!
dw
->
pdata
->
is_idma32
)
return
;
/* Fill FIFO_PARTITION low bits (Channels 0..1, 4..5) */
fifo_partition
|=
value
<<
0
;
/* Fill FIFO_PARTITION high bits (Channels 2..3, 6..7) */
fifo_partition
|=
value
<<
32
;
/* Program FIFO Partition registers - 64 bytes per channel */
idma32_writeq
(
dw
,
FIFO_PARTITION1
,
fifo_partition
);
idma32_writeq
(
dw
,
FIFO_PARTITION0
,
fifo_partition
);
}
static
void
dw_dma_off
(
struct
dw_dma
*
dw
)
void
do_dw_dma_off
(
struct
dw_dma
*
dw
)
{
unsigned
int
i
;
...
...
@@ -1103,7 +971,7 @@ static void dw_dma_off(struct dw_dma *dw)
clear_bit
(
DW_DMA_IS_INITIALIZED
,
&
dw
->
chan
[
i
].
flags
);
}
static
void
dw_dma_on
(
struct
dw_dma
*
dw
)
void
do_
dw_dma_on
(
struct
dw_dma
*
dw
)
{
dma_writel
(
dw
,
CFG
,
DW_CFG_DMA_EN
);
}
...
...
@@ -1139,7 +1007,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
/* Enable controller here if needed */
if
(
!
dw
->
in_use
)
dw_dma_on
(
dw
);
d
o_d
w_dma_on
(
dw
);
dw
->
in_use
|=
dwc
->
mask
;
return
0
;
...
...
@@ -1176,30 +1044,25 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
/* Disable controller in case it was a last user */
dw
->
in_use
&=
~
dwc
->
mask
;
if
(
!
dw
->
in_use
)
dw_dma_off
(
dw
);
d
o_d
w_dma_off
(
dw
);
dev_vdbg
(
chan2dev
(
chan
),
"%s: done
\n
"
,
__func__
);
}
int
d
w
_dma_probe
(
struct
dw_dma_chip
*
chip
)
int
d
o
_dma_probe
(
struct
dw_dma_chip
*
chip
)
{
struct
dw_dma
*
dw
=
chip
->
dw
;
struct
dw_dma_platform_data
*
pdata
;
struct
dw_dma
*
dw
;
bool
autocfg
=
false
;
unsigned
int
dw_params
;
unsigned
int
i
;
int
err
;
dw
=
devm_kzalloc
(
chip
->
dev
,
sizeof
(
*
dw
),
GFP_KERNEL
);
if
(
!
dw
)
return
-
ENOMEM
;
dw
->
pdata
=
devm_kzalloc
(
chip
->
dev
,
sizeof
(
*
dw
->
pdata
),
GFP_KERNEL
);
if
(
!
dw
->
pdata
)
return
-
ENOMEM
;
dw
->
regs
=
chip
->
regs
;
chip
->
dw
=
dw
;
pm_runtime_get_sync
(
chip
->
dev
);
...
...
@@ -1226,8 +1089,6 @@ int dw_dma_probe(struct dw_dma_chip *chip)
pdata
->
block_size
=
dma_readl
(
dw
,
MAX_BLK_SIZE
);
/* Fill platform data with the default values */
pdata
->
is_private
=
true
;
pdata
->
is_memcpy
=
true
;
pdata
->
chan_allocation_order
=
CHAN_ALLOCATION_ASCENDING
;
pdata
->
chan_priority
=
CHAN_PRIORITY_ASCENDING
;
}
else
if
(
chip
->
pdata
->
nr_channels
>
DW_DMA_MAX_NR_CHANNELS
)
{
...
...
@@ -1251,15 +1112,10 @@ int dw_dma_probe(struct dw_dma_chip *chip)
dw
->
all_chan_mask
=
(
1
<<
pdata
->
nr_channels
)
-
1
;
/* Force dma off, just in case */
dw_dma_off
(
dw
);
idma32_fifo_partition
(
dw
);
dw
->
disable
(
dw
);
/* Device and instance ID for IRQ and DMA pool */
if
(
pdata
->
is_idma32
)
snprintf
(
dw
->
name
,
sizeof
(
dw
->
name
),
"idma32:dmac%d"
,
chip
->
id
);
else
snprintf
(
dw
->
name
,
sizeof
(
dw
->
name
),
"dw:dmac%d"
,
chip
->
id
);
dw
->
set_device_name
(
dw
,
chip
->
id
);
/* Create a pool of consistent memory blocks for hardware descriptors */
dw
->
desc_pool
=
dmam_pool_create
(
dw
->
name
,
chip
->
dev
,
...
...
@@ -1339,9 +1195,7 @@ int dw_dma_probe(struct dw_dma_chip *chip)
/* Set capabilities */
dma_cap_set
(
DMA_SLAVE
,
dw
->
dma
.
cap_mask
);
if
(
pdata
->
is_private
)
dma_cap_set
(
DMA_PRIVATE
,
dw
->
dma
.
cap_mask
);
if
(
pdata
->
is_memcpy
)
dma_cap_set
(
DMA_MEMCPY
,
dw
->
dma
.
cap_mask
);
dw
->
dma
.
dev
=
chip
->
dev
;
...
...
@@ -1383,16 +1237,15 @@ int dw_dma_probe(struct dw_dma_chip *chip)
pm_runtime_put_sync_suspend
(
chip
->
dev
);
return
err
;
}
EXPORT_SYMBOL_GPL
(
dw_dma_probe
);
int
d
w
_dma_remove
(
struct
dw_dma_chip
*
chip
)
int
d
o
_dma_remove
(
struct
dw_dma_chip
*
chip
)
{
struct
dw_dma
*
dw
=
chip
->
dw
;
struct
dw_dma_chan
*
dwc
,
*
_dwc
;
pm_runtime_get_sync
(
chip
->
dev
);
dw_dma_off
(
dw
);
d
o_d
w_dma_off
(
dw
);
dma_async_device_unregister
(
&
dw
->
dma
);
free_irq
(
chip
->
irq
,
dw
);
...
...
@@ -1407,27 +1260,24 @@ int dw_dma_remove(struct dw_dma_chip *chip)
pm_runtime_put_sync_suspend
(
chip
->
dev
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
dw_dma_remove
);
int
dw_dma_disable
(
struct
dw_dma_chip
*
chip
)
int
d
o_d
w_dma_disable
(
struct
dw_dma_chip
*
chip
)
{
struct
dw_dma
*
dw
=
chip
->
dw
;
dw
_dma_off
(
dw
);
dw
->
disable
(
dw
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
dw_dma_disable
);
EXPORT_SYMBOL_GPL
(
d
o_d
w_dma_disable
);
int
dw_dma_enable
(
struct
dw_dma_chip
*
chip
)
int
d
o_d
w_dma_enable
(
struct
dw_dma_chip
*
chip
)
{
struct
dw_dma
*
dw
=
chip
->
dw
;
idma32_fifo_partition
(
dw
);
dw_dma_on
(
dw
);
dw
->
enable
(
dw
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
dw_dma_enable
);
EXPORT_SYMBOL_GPL
(
d
o_d
w_dma_enable
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_DESCRIPTION
(
"Synopsys DesignWare DMA Controller core driver"
);
...
...
This diff is collapsed.
Click to expand it.
drivers/dma/dw/dw.c
0 → 100644
View file @
278489c2
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2007-2008 Atmel Corporation
// Copyright (C) 2010-2011 ST Microelectronics
// Copyright (C) 2013,2018 Intel Corporation
#include <linux/bitops.h>
#include <linux/dmaengine.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/types.h>
#include "internal.h"
static
void
dw_dma_initialize_chan
(
struct
dw_dma_chan
*
dwc
)
{
struct
dw_dma
*
dw
=
to_dw_dma
(
dwc
->
chan
.
device
);
u32
cfghi
=
DWC_CFGH_FIFO_MODE
;
u32
cfglo
=
DWC_CFGL_CH_PRIOR
(
dwc
->
priority
);
bool
hs_polarity
=
dwc
->
dws
.
hs_polarity
;
cfghi
|=
DWC_CFGH_DST_PER
(
dwc
->
dws
.
dst_id
);
cfghi
|=
DWC_CFGH_SRC_PER
(
dwc
->
dws
.
src_id
);
cfghi
|=
DWC_CFGH_PROTCTL
(
dw
->
pdata
->
protctl
);
/* Set polarity of handshake interface */
cfglo
|=
hs_polarity
?
DWC_CFGL_HS_DST_POL
|
DWC_CFGL_HS_SRC_POL
:
0
;
channel_writel
(
dwc
,
CFG_LO
,
cfglo
);
channel_writel
(
dwc
,
CFG_HI
,
cfghi
);
}
static
void
dw_dma_suspend_chan
(
struct
dw_dma_chan
*
dwc
,
bool
drain
)
{
u32
cfglo
=
channel_readl
(
dwc
,
CFG_LO
);
channel_writel
(
dwc
,
CFG_LO
,
cfglo
|
DWC_CFGL_CH_SUSP
);
}
static
void
dw_dma_resume_chan
(
struct
dw_dma_chan
*
dwc
,
bool
drain
)
{
u32
cfglo
=
channel_readl
(
dwc
,
CFG_LO
);
channel_writel
(
dwc
,
CFG_LO
,
cfglo
&
~
DWC_CFGL_CH_SUSP
);
}
static
u32
dw_dma_bytes2block
(
struct
dw_dma_chan
*
dwc
,
size_t
bytes
,
unsigned
int
width
,
size_t
*
len
)
{
u32
block
;
if
((
bytes
>>
width
)
>
dwc
->
block_size
)
{
block
=
dwc
->
block_size
;
*
len
=
dwc
->
block_size
<<
width
;
}
else
{
block
=
bytes
>>
width
;
*
len
=
bytes
;
}
return
block
;
}
static
size_t
dw_dma_block2bytes
(
struct
dw_dma_chan
*
dwc
,
u32
block
,
u32
width
)
{
return
DWC_CTLH_BLOCK_TS
(
block
)
<<
width
;
}
static
u32
dw_dma_prepare_ctllo
(
struct
dw_dma_chan
*
dwc
)
{
struct
dma_slave_config
*
sconfig
=
&
dwc
->
dma_sconfig
;
bool
is_slave
=
is_slave_direction
(
dwc
->
direction
);
u8
smsize
=
is_slave
?
sconfig
->
src_maxburst
:
DW_DMA_MSIZE_16
;
u8
dmsize
=
is_slave
?
sconfig
->
dst_maxburst
:
DW_DMA_MSIZE_16
;
u8
p_master
=
dwc
->
dws
.
p_master
;
u8
m_master
=
dwc
->
dws
.
m_master
;
u8
dms
=
(
dwc
->
direction
==
DMA_MEM_TO_DEV
)
?
p_master
:
m_master
;
u8
sms
=
(
dwc
->
direction
==
DMA_DEV_TO_MEM
)
?
p_master
:
m_master
;
return
DWC_CTLL_LLP_D_EN
|
DWC_CTLL_LLP_S_EN
|
DWC_CTLL_DST_MSIZE
(
dmsize
)
|
DWC_CTLL_SRC_MSIZE
(
smsize
)
|
DWC_CTLL_DMS
(
dms
)
|
DWC_CTLL_SMS
(
sms
);
}
static
void
dw_dma_encode_maxburst
(
struct
dw_dma_chan
*
dwc
,
u32
*
maxburst
)
{
/*
* Fix burst size according to dw_dmac. We need to convert them as:
* 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
*/
*
maxburst
=
*
maxburst
>
1
?
fls
(
*
maxburst
)
-
2
:
0
;
}
static
void
dw_dma_set_device_name
(
struct
dw_dma
*
dw
,
int
id
)
{
snprintf
(
dw
->
name
,
sizeof
(
dw
->
name
),
"dw:dmac%d"
,
id
);
}
static
void
dw_dma_disable
(
struct
dw_dma
*
dw
)
{
do_dw_dma_off
(
dw
);
}
static
void
dw_dma_enable
(
struct
dw_dma
*
dw
)
{
do_dw_dma_on
(
dw
);
}
int
dw_dma_probe
(
struct
dw_dma_chip
*
chip
)
{
struct
dw_dma
*
dw
;
dw
=
devm_kzalloc
(
chip
->
dev
,
sizeof
(
*
dw
),
GFP_KERNEL
);
if
(
!
dw
)
return
-
ENOMEM
;
/* Channel operations */
dw
->
initialize_chan
=
dw_dma_initialize_chan
;
dw
->
suspend_chan
=
dw_dma_suspend_chan
;
dw
->
resume_chan
=
dw_dma_resume_chan
;
dw
->
prepare_ctllo
=
dw_dma_prepare_ctllo
;
dw
->
encode_maxburst
=
dw_dma_encode_maxburst
;
dw
->
bytes2block
=
dw_dma_bytes2block
;
dw
->
block2bytes
=
dw_dma_block2bytes
;
/* Device operations */
dw
->
set_device_name
=
dw_dma_set_device_name
;
dw
->
disable
=
dw_dma_disable
;
dw
->
enable
=
dw_dma_enable
;
chip
->
dw
=
dw
;
return
do_dma_probe
(
chip
);
}
EXPORT_SYMBOL_GPL
(
dw_dma_probe
);
int
dw_dma_remove
(
struct
dw_dma_chip
*
chip
)
{
return
do_dma_remove
(
chip
);
}
EXPORT_SYMBOL_GPL
(
dw_dma_remove
);
This diff is collapsed.
Click to expand it.
drivers/dma/dw/idma32.c
0 → 100644
View file @
278489c2
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2013,2018 Intel Corporation
#include <linux/bitops.h>
#include <linux/dmaengine.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/types.h>
#include "internal.h"
static
void
idma32_initialize_chan
(
struct
dw_dma_chan
*
dwc
)
{
u32
cfghi
=
0
;
u32
cfglo
=
0
;
/* Set default burst alignment */
cfglo
|=
IDMA32C_CFGL_DST_BURST_ALIGN
|
IDMA32C_CFGL_SRC_BURST_ALIGN
;
/* Low 4 bits of the request lines */
cfghi
|=
IDMA32C_CFGH_DST_PER
(
dwc
->
dws
.
dst_id
&
0xf
);
cfghi
|=
IDMA32C_CFGH_SRC_PER
(
dwc
->
dws
.
src_id
&
0xf
);
/* Request line extension (2 bits) */
cfghi
|=
IDMA32C_CFGH_DST_PER_EXT
(
dwc
->
dws
.
dst_id
>>
4
&
0x3
);
cfghi
|=
IDMA32C_CFGH_SRC_PER_EXT
(
dwc
->
dws
.
src_id
>>
4
&
0x3
);
channel_writel
(
dwc
,
CFG_LO
,
cfglo
);
channel_writel
(
dwc
,
CFG_HI
,
cfghi
);
}
static
void
idma32_suspend_chan
(
struct
dw_dma_chan
*
dwc
,
bool
drain
)
{
u32
cfglo
=
channel_readl
(
dwc
,
CFG_LO
);
if
(
drain
)
cfglo
|=
IDMA32C_CFGL_CH_DRAIN
;
channel_writel
(
dwc
,
CFG_LO
,
cfglo
|
DWC_CFGL_CH_SUSP
);
}
static
void
idma32_resume_chan
(
struct
dw_dma_chan
*
dwc
,
bool
drain
)
{
u32
cfglo
=
channel_readl
(
dwc
,
CFG_LO
);
if
(
drain
)
cfglo
&=
~
IDMA32C_CFGL_CH_DRAIN
;
channel_writel
(
dwc
,
CFG_LO
,
cfglo
&
~
DWC_CFGL_CH_SUSP
);
}
static
u32
idma32_bytes2block
(
struct
dw_dma_chan
*
dwc
,
size_t
bytes
,
unsigned
int
width
,
size_t
*
len
)
{
u32
block
;
if
(
bytes
>
dwc
->
block_size
)
{
block
=
dwc
->
block_size
;
*
len
=
dwc
->
block_size
;
}
else
{
block
=
bytes
;
*
len
=
bytes
;
}
return
block
;
}
static
size_t
idma32_block2bytes
(
struct
dw_dma_chan
*
dwc
,
u32
block
,
u32
width
)
{
return
IDMA32C_CTLH_BLOCK_TS
(
block
);
}
static
u32
idma32_prepare_ctllo
(
struct
dw_dma_chan
*
dwc
)
{
struct
dma_slave_config
*
sconfig
=
&
dwc
->
dma_sconfig
;
bool
is_slave
=
is_slave_direction
(
dwc
->
direction
);
u8
smsize
=
is_slave
?
sconfig
->
src_maxburst
:
IDMA32_MSIZE_8
;
u8
dmsize
=
is_slave
?
sconfig
->
dst_maxburst
:
IDMA32_MSIZE_8
;
return
DWC_CTLL_LLP_D_EN
|
DWC_CTLL_LLP_S_EN
|
DWC_CTLL_DST_MSIZE
(
dmsize
)
|
DWC_CTLL_SRC_MSIZE
(
smsize
);
}
static
void
idma32_encode_maxburst
(
struct
dw_dma_chan
*
dwc
,
u32
*
maxburst
)
{
*
maxburst
=
*
maxburst
>
1
?
fls
(
*
maxburst
)
-
1
:
0
;
}
static
void
idma32_set_device_name
(
struct
dw_dma
*
dw
,
int
id
)
{
snprintf
(
dw
->
name
,
sizeof
(
dw
->
name
),
"idma32:dmac%d"
,
id
);
}
/*
* Program FIFO size of channels.
*
* By default full FIFO (512 bytes) is assigned to channel 0. Here we
* slice FIFO on equal parts between channels.
*/
static
void
idma32_fifo_partition
(
struct
dw_dma
*
dw
)
{
u64
value
=
IDMA32C_FP_PSIZE_CH0
(
64
)
|
IDMA32C_FP_PSIZE_CH1
(
64
)
|
IDMA32C_FP_UPDATE
;
u64
fifo_partition
=
0
;
/* Fill FIFO_PARTITION low bits (Channels 0..1, 4..5) */
fifo_partition
|=
value
<<
0
;
/* Fill FIFO_PARTITION high bits (Channels 2..3, 6..7) */
fifo_partition
|=
value
<<
32
;
/* Program FIFO Partition registers - 64 bytes per channel */
idma32_writeq
(
dw
,
FIFO_PARTITION1
,
fifo_partition
);
idma32_writeq
(
dw
,
FIFO_PARTITION0
,
fifo_partition
);
}
static
void
idma32_disable
(
struct
dw_dma
*
dw
)
{
do_dw_dma_off
(
dw
);
idma32_fifo_partition
(
dw
);
}
static
void
idma32_enable
(
struct
dw_dma
*
dw
)
{
idma32_fifo_partition
(
dw
);
do_dw_dma_on
(
dw
);
}
int
idma32_dma_probe
(
struct
dw_dma_chip
*
chip
)
{
struct
dw_dma
*
dw
;
dw
=
devm_kzalloc
(
chip
->
dev
,
sizeof
(
*
dw
),
GFP_KERNEL
);
if
(
!
dw
)
return
-
ENOMEM
;
/* Channel operations */
dw
->
initialize_chan
=
idma32_initialize_chan
;
dw
->
suspend_chan
=
idma32_suspend_chan
;
dw
->
resume_chan
=
idma32_resume_chan
;
dw
->
prepare_ctllo
=
idma32_prepare_ctllo
;
dw
->
encode_maxburst
=
idma32_encode_maxburst
;
dw
->
bytes2block
=
idma32_bytes2block
;
dw
->
block2bytes
=
idma32_block2bytes
;
/* Device operations */
dw
->
set_device_name
=
idma32_set_device_name
;
dw
->
disable
=
idma32_disable
;
dw
->
enable
=
idma32_enable
;
chip
->
dw
=
dw
;
return
do_dma_probe
(
chip
);
}
EXPORT_SYMBOL_GPL
(
idma32_dma_probe
);
int
idma32_dma_remove
(
struct
dw_dma_chip
*
chip
)
{
return
do_dma_remove
(
chip
);
}
EXPORT_SYMBOL_GPL
(
idma32_dma_remove
);
This diff is collapsed.
Click to expand it.
drivers/dma/dw/internal.h
View file @
278489c2
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Driver for the Synopsys DesignWare DMA Controller
*
* Copyright (C) 2013 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _DMA_DW_INTERNAL_H
...
...
@@ -15,8 +12,14 @@
#include "regs.h"
int
dw_dma_disable
(
struct
dw_dma_chip
*
chip
);
int
dw_dma_enable
(
struct
dw_dma_chip
*
chip
);
int
do_dma_probe
(
struct
dw_dma_chip
*
chip
);
int
do_dma_remove
(
struct
dw_dma_chip
*
chip
);
void
do_dw_dma_on
(
struct
dw_dma
*
dw
);
void
do_dw_dma_off
(
struct
dw_dma
*
dw
);
int
do_dw_dma_disable
(
struct
dw_dma_chip
*
chip
);
int
do_dw_dma_enable
(
struct
dw_dma_chip
*
chip
);
extern
bool
dw_dma_filter
(
struct
dma_chan
*
chan
,
void
*
param
);
...
...
This diff is collapsed.
Click to expand it.
drivers/dma/dw/pci.c
View file @
278489c2
// SPDX-License-Identifier: GPL-2.0
/*
* PCI driver for the Synopsys DesignWare DMA Controller
*
* Copyright (C) 2013 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
...
...
@@ -15,21 +12,33 @@
#include "internal.h"
static
struct
dw_dma_platform_data
mrfld_pdata
=
{
struct
dw_dma_pci_data
{
const
struct
dw_dma_platform_data
*
pdata
;
int
(
*
probe
)(
struct
dw_dma_chip
*
chip
);
};
static
const
struct
dw_dma_pci_data
dw_pci_data
=
{
.
probe
=
dw_dma_probe
,
};
static
const
struct
dw_dma_platform_data
idma32_pdata
=
{
.
nr_channels
=
8
,
.
is_private
=
true
,
.
is_memcpy
=
true
,
.
is_idma32
=
true
,
.
chan_allocation_order
=
CHAN_ALLOCATION_ASCENDING
,
.
chan_priority
=
CHAN_PRIORITY_ASCENDING
,
.
block_size
=
131071
,
.
nr_masters
=
1
,
.
data_width
=
{
4
},
.
multi_block
=
{
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
},
};
static
const
struct
dw_dma_pci_data
idma32_pci_data
=
{
.
pdata
=
&
idma32_pdata
,
.
probe
=
idma32_dma_probe
,
};
static
int
dw_pci_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
pid
)
{
const
struct
dw_dma_p
latform_data
*
p
data
=
(
void
*
)
pid
->
driver_data
;
const
struct
dw_dma_p
ci_data
*
data
=
(
void
*
)
pid
->
driver_data
;
struct
dw_dma_chip
*
chip
;
int
ret
;
...
...
@@ -62,9 +71,9 @@ static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
chip
->
id
=
pdev
->
devfn
;
chip
->
regs
=
pcim_iomap_table
(
pdev
)[
0
];
chip
->
irq
=
pdev
->
irq
;
chip
->
pdata
=
pdata
;
chip
->
pdata
=
data
->
pdata
;
ret
=
d
w_dma_
probe
(
chip
);
ret
=
d
ata
->
probe
(
chip
);
if
(
ret
)
return
ret
;
...
...
@@ -90,7 +99,7 @@ static int dw_pci_suspend_late(struct device *dev)
struct
pci_dev
*
pci
=
to_pci_dev
(
dev
);
struct
dw_dma_chip
*
chip
=
pci_get_drvdata
(
pci
);
return
dw_dma_disable
(
chip
);
return
d
o_d
w_dma_disable
(
chip
);
};
static
int
dw_pci_resume_early
(
struct
device
*
dev
)
...
...
@@ -98,7 +107,7 @@ static int dw_pci_resume_early(struct device *dev)
struct
pci_dev
*
pci
=
to_pci_dev
(
dev
);
struct
dw_dma_chip
*
chip
=
pci_get_drvdata
(
pci
);
return
dw_dma_enable
(
chip
);
return
d
o_d
w_dma_enable
(
chip
);
};
#endif
/* CONFIG_PM_SLEEP */
...
...
@@ -109,24 +118,24 @@ static const struct dev_pm_ops dw_pci_dev_pm_ops = {
static
const
struct
pci_device_id
dw_pci_id_table
[]
=
{
/* Medfield (GPDMA) */
{
PCI_VDEVICE
(
INTEL
,
0x0827
)
},
{
PCI_VDEVICE
(
INTEL
,
0x0827
)
,
(
kernel_ulong_t
)
&
dw_pci_data
},
/* BayTrail */
{
PCI_VDEVICE
(
INTEL
,
0x0f06
)
},
{
PCI_VDEVICE
(
INTEL
,
0x0f40
)
},
{
PCI_VDEVICE
(
INTEL
,
0x0f06
)
,
(
kernel_ulong_t
)
&
dw_pci_data
},
{
PCI_VDEVICE
(
INTEL
,
0x0f40
)
,
(
kernel_ulong_t
)
&
dw_pci_data
},
/* Merrifield
iDMA 32-bit (GPDMA)
*/
{
PCI_VDEVICE
(
INTEL
,
0x11a2
),
(
kernel_ulong_t
)
&
mrfld_p
data
},
/* Merrifield */
{
PCI_VDEVICE
(
INTEL
,
0x11a2
),
(
kernel_ulong_t
)
&
idma32_pci_
data
},
/* Braswell */
{
PCI_VDEVICE
(
INTEL
,
0x2286
)
},
{
PCI_VDEVICE
(
INTEL
,
0x22c0
)
},
{
PCI_VDEVICE
(
INTEL
,
0x2286
)
,
(
kernel_ulong_t
)
&
dw_pci_data
},
{
PCI_VDEVICE
(
INTEL
,
0x22c0
)
,
(
kernel_ulong_t
)
&
dw_pci_data
},
/* Haswell */
{
PCI_VDEVICE
(
INTEL
,
0x9c60
)
},
{
PCI_VDEVICE
(
INTEL
,
0x9c60
)
,
(
kernel_ulong_t
)
&
dw_pci_data
},
/* Broadwell */
{
PCI_VDEVICE
(
INTEL
,
0x9ce0
)
},
{
PCI_VDEVICE
(
INTEL
,
0x9ce0
)
,
(
kernel_ulong_t
)
&
dw_pci_data
},
{
}
};
...
...
This diff is collapsed.
Click to expand it.
drivers/dma/dw/platform.c
View file @
278489c2
// SPDX-License-Identifier: GPL-2.0
/*
* Platform driver for the Synopsys DesignWare DMA Controller
*
...
...
@@ -6,10 +7,6 @@
* Copyright (C) 2013 Intel Corporation
*
* Some parts of this driver are derived from the original dw_dmac.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
...
...
@@ -128,15 +125,6 @@ dw_dma_parse_dt(struct platform_device *pdev)
pdata
->
nr_masters
=
nr_masters
;
pdata
->
nr_channels
=
nr_channels
;
if
(
of_property_read_bool
(
np
,
"is_private"
))
pdata
->
is_private
=
true
;
/*
* All known devices, which use DT for configuration, support
* memory-to-memory transfers. So enable it by default.
*/
pdata
->
is_memcpy
=
true
;
if
(
!
of_property_read_u32
(
np
,
"chan_allocation_order"
,
&
tmp
))
pdata
->
chan_allocation_order
=
(
unsigned
char
)
tmp
;
...
...
@@ -264,7 +252,7 @@ static void dw_shutdown(struct platform_device *pdev)
struct
dw_dma_chip
*
chip
=
platform_get_drvdata
(
pdev
);
/*
* We have to call dw_dma_disable() to stop any ongoing transfer. On
* We have to call d
o_d
w_dma_disable() to stop any ongoing transfer. On
* some platforms we can't do that since DMA device is powered off.
* Moreover we have no possibility to check if the platform is affected
* or not. That's why we call pm_runtime_get_sync() / pm_runtime_put()
...
...
@@ -273,7 +261,7 @@ static void dw_shutdown(struct platform_device *pdev)
* used by the driver.
*/
pm_runtime_get_sync
(
chip
->
dev
);
dw_dma_disable
(
chip
);
d
o_d
w_dma_disable
(
chip
);
pm_runtime_put_sync_suspend
(
chip
->
dev
);
clk_disable_unprepare
(
chip
->
clk
);
...
...
@@ -303,7 +291,7 @@ static int dw_suspend_late(struct device *dev)
{
struct
dw_dma_chip
*
chip
=
dev_get_drvdata
(
dev
);
dw_dma_disable
(
chip
);
d
o_d
w_dma_disable
(
chip
);
clk_disable_unprepare
(
chip
->
clk
);
return
0
;
...
...
@@ -318,7 +306,7 @@ static int dw_resume_early(struct device *dev)
if
(
ret
)
return
ret
;
return
dw_dma_enable
(
chip
);
return
d
o_d
w_dma_enable
(
chip
);
}
#endif
/* CONFIG_PM_SLEEP */
...
...
This diff is collapsed.
Click to expand it.
drivers/dma/dw/regs.h
View file @
278489c2
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Driver for the Synopsys DesignWare AHB DMA Controller
*
* Copyright (C) 2005-2007 Atmel Corporation
* Copyright (C) 2010-2011 ST Microelectronics
* Copyright (C) 2016 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/bitops.h>
...
...
@@ -222,6 +219,16 @@ enum dw_dma_msize {
/* iDMA 32-bit support */
/* bursts size */
enum
idma32_msize
{
IDMA32_MSIZE_1
,
IDMA32_MSIZE_2
,
IDMA32_MSIZE_4
,
IDMA32_MSIZE_8
,
IDMA32_MSIZE_16
,
IDMA32_MSIZE_32
,
};
/* Bitfields in CTL_HI */
#define IDMA32C_CTLH_BLOCK_TS_MASK GENMASK(16, 0)
#define IDMA32C_CTLH_BLOCK_TS(x) ((x) & IDMA32C_CTLH_BLOCK_TS_MASK)
...
...
@@ -312,6 +319,21 @@ struct dw_dma {
u8
all_chan_mask
;
u8
in_use
;
/* Channel operations */
void
(
*
initialize_chan
)(
struct
dw_dma_chan
*
dwc
);
void
(
*
suspend_chan
)(
struct
dw_dma_chan
*
dwc
,
bool
drain
);
void
(
*
resume_chan
)(
struct
dw_dma_chan
*
dwc
,
bool
drain
);
u32
(
*
prepare_ctllo
)(
struct
dw_dma_chan
*
dwc
);
void
(
*
encode_maxburst
)(
struct
dw_dma_chan
*
dwc
,
u32
*
maxburst
);
u32
(
*
bytes2block
)(
struct
dw_dma_chan
*
dwc
,
size_t
bytes
,
unsigned
int
width
,
size_t
*
len
);
size_t
(
*
block2bytes
)(
struct
dw_dma_chan
*
dwc
,
u32
block
,
u32
width
);
/* Device operations */
void
(
*
set_device_name
)(
struct
dw_dma
*
dw
,
int
id
);
void
(
*
disable
)(
struct
dw_dma
*
dw
);
void
(
*
enable
)(
struct
dw_dma
*
dw
);
/* platform data */
struct
dw_dma_platform_data
*
pdata
;
};
...
...
This diff is collapsed.
Click to expand it.
drivers/tty/serial/8250/8250_lpss.c
View file @
278489c2
...
...
@@ -153,7 +153,6 @@ static int byt_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
#ifdef CONFIG_SERIAL_8250_DMA
static
const
struct
dw_dma_platform_data
qrk_serial_dma_pdata
=
{
.
nr_channels
=
2
,
.
is_private
=
true
,
.
chan_allocation_order
=
CHAN_ALLOCATION_ASCENDING
,
.
chan_priority
=
CHAN_PRIORITY_ASCENDING
,
.
block_size
=
4095
,
...
...
This diff is collapsed.
Click to expand it.
include/linux/dma/dw.h
View file @
278489c2
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Driver for the Synopsys DesignWare DMA Controller
*
* Copyright (C) 2007 Atmel Corporation
* Copyright (C) 2010-2011 ST Microelectronics
* Copyright (C) 2014 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _DMA_DW_H
#define _DMA_DW_H
...
...
@@ -45,9 +42,13 @@ struct dw_dma_chip {
#if IS_ENABLED(CONFIG_DW_DMAC_CORE)
int
dw_dma_probe
(
struct
dw_dma_chip
*
chip
);
int
dw_dma_remove
(
struct
dw_dma_chip
*
chip
);
int
idma32_dma_probe
(
struct
dw_dma_chip
*
chip
);
int
idma32_dma_remove
(
struct
dw_dma_chip
*
chip
);
#else
static
inline
int
dw_dma_probe
(
struct
dw_dma_chip
*
chip
)
{
return
-
ENODEV
;
}
static
inline
int
dw_dma_remove
(
struct
dw_dma_chip
*
chip
)
{
return
0
;
}
static
inline
int
idma32_dma_probe
(
struct
dw_dma_chip
*
chip
)
{
return
-
ENODEV
;
}
static
inline
int
idma32_dma_remove
(
struct
dw_dma_chip
*
chip
)
{
return
0
;
}
#endif
/* CONFIG_DW_DMAC_CORE */
#endif
/* _DMA_DW_H */
This diff is collapsed.
Click to expand it.
include/linux/platform_data/dma-dw.h
View file @
278489c2
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Driver for the Synopsys DesignWare DMA Controller
*
* Copyright (C) 2007 Atmel Corporation
* Copyright (C) 2010-2011 ST Microelectronics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _PLATFORM_DATA_DMA_DW_H
#define _PLATFORM_DATA_DMA_DW_H
...
...
@@ -38,10 +35,6 @@ struct dw_dma_slave {
/**
* struct dw_dma_platform_data - Controller configuration parameters
* @nr_channels: Number of channels supported by hardware (max 8)
* @is_private: The device channels should be marked as private and not for
* by the general purpose DMA channel allocator.
* @is_memcpy: The device channels do support memory-to-memory transfers.
* @is_idma32: The type of the DMA controller is iDMA32
* @chan_allocation_order: Allocate channels starting from 0 or 7
* @chan_priority: Set channel priority increasing from 0 to 7 or 7 to 0.
* @block_size: Maximum block size supported by the controller
...
...
@@ -53,9 +46,6 @@ struct dw_dma_slave {
*/
struct
dw_dma_platform_data
{
unsigned
int
nr_channels
;
bool
is_private
;
bool
is_memcpy
;
bool
is_idma32
;
#define CHAN_ALLOCATION_ASCENDING 0
/* zero to seven */
#define CHAN_ALLOCATION_DESCENDING 1
/* seven to zero */
unsigned
char
chan_allocation_order
;
...
...
This diff is collapsed.
Click to expand it.
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