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
nexedi
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