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
7cfa7b54
Commit
7cfa7b54
authored
Jan 16, 2014
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/dma' into for-tiwai
parents
99896f71
d70e861a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
73 additions
and
29 deletions
+73
-29
drivers/dma/pl330.c
drivers/dma/pl330.c
+1
-0
include/linux/dmaengine.h
include/linux/dmaengine.h
+28
-0
sound/soc/adi/axi-i2s.c
sound/soc/adi/axi-i2s.c
+1
-2
sound/soc/adi/axi-spdif.c
sound/soc/adi/axi-spdif.c
+1
-2
sound/soc/samsung/dmaengine.c
sound/soc/samsung/dmaengine.c
+0
-1
sound/soc/soc-generic-dmaengine-pcm.c
sound/soc/soc-generic-dmaengine-pcm.c
+42
-24
No files found.
drivers/dma/pl330.c
View file @
7cfa7b54
...
...
@@ -2884,6 +2884,7 @@ static int pl330_dma_device_slave_caps(struct dma_chan *dchan,
caps
->
directions
=
BIT
(
DMA_DEV_TO_MEM
)
|
BIT
(
DMA_MEM_TO_DEV
);
caps
->
cmd_pause
=
false
;
caps
->
cmd_terminate
=
true
;
caps
->
residue_granularity
=
DMA_RESIDUE_GRANULARITY_DESCRIPTOR
;
return
0
;
}
...
...
include/linux/dmaengine.h
View file @
7cfa7b54
...
...
@@ -364,6 +364,32 @@ struct dma_slave_config {
unsigned
int
slave_id
;
};
/**
* enum dma_residue_granularity - Granularity of the reported transfer residue
* @DMA_RESIDUE_GRANULARITY_DESCRIPTOR: Residue reporting is not support. The
* DMA channel is only able to tell whether a descriptor has been completed or
* not, which means residue reporting is not supported by this channel. The
* residue field of the dma_tx_state field will always be 0.
* @DMA_RESIDUE_GRANULARITY_SEGMENT: Residue is updated after each successfully
* completed segment of the transfer (For cyclic transfers this is after each
* period). This is typically implemented by having the hardware generate an
* interrupt after each transferred segment and then the drivers updates the
* outstanding residue by the size of the segment. Another possibility is if
* the hardware supports scatter-gather and the segment descriptor has a field
* which gets set after the segment has been completed. The driver then counts
* the number of segments without the flag set to compute the residue.
* @DMA_RESIDUE_GRANULARITY_BURST: Residue is updated after each transferred
* burst. This is typically only supported if the hardware has a progress
* register of some sort (E.g. a register with the current read/write address
* or a register with the amount of bursts/beats/bytes that have been
* transferred or still need to be transferred).
*/
enum
dma_residue_granularity
{
DMA_RESIDUE_GRANULARITY_DESCRIPTOR
=
0
,
DMA_RESIDUE_GRANULARITY_SEGMENT
=
1
,
DMA_RESIDUE_GRANULARITY_BURST
=
2
,
};
/* struct dma_slave_caps - expose capabilities of a slave channel only
*
* @src_addr_widths: bit mask of src addr widths the channel supports
...
...
@@ -374,6 +400,7 @@ struct dma_slave_config {
* should be checked by controller as well
* @cmd_pause: true, if pause and thereby resume is supported
* @cmd_terminate: true, if terminate cmd is supported
* @residue_granularity: granularity of the reported transfer residue
*/
struct
dma_slave_caps
{
u32
src_addr_widths
;
...
...
@@ -381,6 +408,7 @@ struct dma_slave_caps {
u32
directions
;
bool
cmd_pause
;
bool
cmd_terminate
;
enum
dma_residue_granularity
residue_granularity
;
};
static
inline
const
char
*
dma_chan_name
(
struct
dma_chan
*
chan
)
...
...
sound/soc/adi/axi-i2s.c
View file @
7cfa7b54
...
...
@@ -236,8 +236,7 @@ static int axi_i2s_probe(struct platform_device *pdev)
if
(
ret
)
goto
err_clk_disable
;
ret
=
devm_snd_dmaengine_pcm_register
(
&
pdev
->
dev
,
NULL
,
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE
);
ret
=
devm_snd_dmaengine_pcm_register
(
&
pdev
->
dev
,
NULL
,
0
);
if
(
ret
)
goto
err_clk_disable
;
...
...
sound/soc/adi/axi-spdif.c
View file @
7cfa7b54
...
...
@@ -229,8 +229,7 @@ static int axi_spdif_probe(struct platform_device *pdev)
if
(
ret
)
goto
err_clk_disable
;
ret
=
devm_snd_dmaengine_pcm_register
(
&
pdev
->
dev
,
NULL
,
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE
);
ret
=
devm_snd_dmaengine_pcm_register
(
&
pdev
->
dev
,
NULL
,
0
);
if
(
ret
)
goto
err_clk_disable
;
...
...
sound/soc/samsung/dmaengine.c
View file @
7cfa7b54
...
...
@@ -68,7 +68,6 @@ int samsung_asoc_dma_platform_register(struct device *dev)
{
return
snd_dmaengine_pcm_register
(
dev
,
&
samsung_dmaengine_pcm_config
,
SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME
|
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE
|
SND_DMAENGINE_PCM_FLAG_COMPAT
);
}
EXPORT_SYMBOL_GPL
(
samsung_asoc_dma_platform_register
);
...
...
sound/soc/soc-generic-dmaengine-pcm.c
View file @
7cfa7b54
...
...
@@ -144,6 +144,8 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
if
(
ret
==
0
)
{
if
(
dma_caps
.
cmd_pause
)
hw
.
info
|=
SNDRV_PCM_INFO_PAUSE
|
SNDRV_PCM_INFO_RESUME
;
if
(
dma_caps
.
residue_granularity
<=
DMA_RESIDUE_GRANULARITY_SEGMENT
)
hw
.
info
|=
SNDRV_PCM_INFO_BATCH
;
}
return
snd_soc_set_runtime_hwparams
(
substream
,
&
hw
);
...
...
@@ -187,6 +189,21 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel(
dma_data
->
filter_data
);
}
static
bool
dmaengine_pcm_can_report_residue
(
struct
dma_chan
*
chan
)
{
struct
dma_slave_caps
dma_caps
;
int
ret
;
ret
=
dma_get_slave_caps
(
chan
,
&
dma_caps
);
if
(
ret
!=
0
)
return
true
;
if
(
dma_caps
.
residue_granularity
==
DMA_RESIDUE_GRANULARITY_DESCRIPTOR
)
return
false
;
return
true
;
}
static
int
dmaengine_pcm_new
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
dmaengine_pcm
*
pcm
=
soc_platform_to_pcm
(
rtd
->
platform
);
...
...
@@ -239,6 +256,16 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
max_buffer_size
);
if
(
ret
)
goto
err_free
;
/*
* This will only return false if we know for sure that at least
* one channel does not support residue reporting. If the DMA
* driver does not implement the slave_caps API we rely having
* the NO_RESIDUE flag set manually in case residue reporting is
* not supported.
*/
if
(
!
dmaengine_pcm_can_report_residue
(
pcm
->
chan
[
i
]))
pcm
->
flags
|=
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE
;
}
return
0
;
...
...
@@ -248,6 +275,18 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
return
ret
;
}
static
snd_pcm_uframes_t
dmaengine_pcm_pointer
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
dmaengine_pcm
*
pcm
=
soc_platform_to_pcm
(
rtd
->
platform
);
if
(
pcm
->
flags
&
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE
)
return
snd_dmaengine_pcm_pointer_no_residue
(
substream
);
else
return
snd_dmaengine_pcm_pointer
(
substream
);
}
static
const
struct
snd_pcm_ops
dmaengine_pcm_ops
=
{
.
open
=
dmaengine_pcm_open
,
.
close
=
snd_dmaengine_pcm_close
,
...
...
@@ -255,7 +294,7 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = {
.
hw_params
=
dmaengine_pcm_hw_params
,
.
hw_free
=
snd_pcm_lib_free_pages
,
.
trigger
=
snd_dmaengine_pcm_trigger
,
.
pointer
=
snd_
dmaengine_pcm_pointer
,
.
pointer
=
dmaengine_pcm_pointer
,
};
static
const
struct
snd_soc_platform_driver
dmaengine_pcm_platform
=
{
...
...
@@ -265,23 +304,6 @@ static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
.
probe_order
=
SND_SOC_COMP_ORDER_LATE
,
};
static
const
struct
snd_pcm_ops
dmaengine_no_residue_pcm_ops
=
{
.
open
=
dmaengine_pcm_open
,
.
close
=
snd_dmaengine_pcm_close
,
.
ioctl
=
snd_pcm_lib_ioctl
,
.
hw_params
=
dmaengine_pcm_hw_params
,
.
hw_free
=
snd_pcm_lib_free_pages
,
.
trigger
=
snd_dmaengine_pcm_trigger
,
.
pointer
=
snd_dmaengine_pcm_pointer_no_residue
,
};
static
const
struct
snd_soc_platform_driver
dmaengine_no_residue_pcm_platform
=
{
.
ops
=
&
dmaengine_no_residue_pcm_ops
,
.
pcm_new
=
dmaengine_pcm_new
,
.
pcm_free
=
dmaengine_pcm_free
,
.
probe_order
=
SND_SOC_COMP_ORDER_LATE
,
};
static
const
char
*
const
dmaengine_pcm_dma_channel_names
[]
=
{
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
"tx"
,
[
SNDRV_PCM_STREAM_CAPTURE
]
=
"rx"
,
...
...
@@ -374,12 +396,8 @@ int snd_dmaengine_pcm_register(struct device *dev,
if
(
ret
)
goto
err_free_dma
;
if
(
flags
&
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE
)
ret
=
snd_soc_add_platform
(
dev
,
&
pcm
->
platform
,
&
dmaengine_no_residue_pcm_platform
);
else
ret
=
snd_soc_add_platform
(
dev
,
&
pcm
->
platform
,
&
dmaengine_pcm_platform
);
ret
=
snd_soc_add_platform
(
dev
,
&
pcm
->
platform
,
&
dmaengine_pcm_platform
);
if
(
ret
)
goto
err_free_dma
;
...
...
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