Merge remote-tracking branch 'asoc/fix/rcar' into asoc-linus
This commit is contained in:
commit
54dbb868af
|
@ -222,7 +222,7 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod,
|
||||||
NULL, &val, NULL);
|
NULL, &val, NULL);
|
||||||
|
|
||||||
val = val << shift;
|
val = val << shift;
|
||||||
mask = 0xffff << shift;
|
mask = 0x0f1f << shift;
|
||||||
|
|
||||||
rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);
|
rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
|
||||||
|
|
||||||
in = in << shift;
|
in = in << shift;
|
||||||
out = out << shift;
|
out = out << shift;
|
||||||
mask = 0xffff << shift;
|
mask = 0x0f1f << shift;
|
||||||
|
|
||||||
switch (id / 2) {
|
switch (id / 2) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -380,7 +380,7 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
|
||||||
ckr = 0x80000000;
|
ckr = 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsnd_mod_bset(adg_mod, BRGCKR, 0x80FF0000, adg->ckr | ckr);
|
rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr);
|
||||||
rsnd_mod_write(adg_mod, BRRA, adg->rbga);
|
rsnd_mod_write(adg_mod, BRRA, adg->rbga);
|
||||||
rsnd_mod_write(adg_mod, BRRB, adg->rbgb);
|
rsnd_mod_write(adg_mod, BRRB, adg->rbgb);
|
||||||
|
|
||||||
|
|
|
@ -1332,8 +1332,8 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||||
|
|
||||||
return snd_pcm_lib_preallocate_pages_for_all(
|
return snd_pcm_lib_preallocate_pages_for_all(
|
||||||
rtd->pcm,
|
rtd->pcm,
|
||||||
SNDRV_DMA_TYPE_CONTINUOUS,
|
SNDRV_DMA_TYPE_DEV,
|
||||||
snd_dma_continuous_data(GFP_KERNEL),
|
rtd->card->snd_card->dev,
|
||||||
PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
|
PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,7 @@
|
||||||
struct rsnd_dmaen {
|
struct rsnd_dmaen {
|
||||||
struct dma_chan *chan;
|
struct dma_chan *chan;
|
||||||
dma_cookie_t cookie;
|
dma_cookie_t cookie;
|
||||||
dma_addr_t dma_buf;
|
|
||||||
unsigned int dma_len;
|
unsigned int dma_len;
|
||||||
unsigned int dma_period;
|
|
||||||
unsigned int dma_cnt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rsnd_dmapp {
|
struct rsnd_dmapp {
|
||||||
|
@ -71,38 +68,10 @@ static struct rsnd_mod mem = {
|
||||||
/*
|
/*
|
||||||
* Audio DMAC
|
* Audio DMAC
|
||||||
*/
|
*/
|
||||||
#define rsnd_dmaen_sync(dmaen, io, i) __rsnd_dmaen_sync(dmaen, io, i, 1)
|
|
||||||
#define rsnd_dmaen_unsync(dmaen, io, i) __rsnd_dmaen_sync(dmaen, io, i, 0)
|
|
||||||
static void __rsnd_dmaen_sync(struct rsnd_dmaen *dmaen, struct rsnd_dai_stream *io,
|
|
||||||
int i, int sync)
|
|
||||||
{
|
|
||||||
struct device *dev = dmaen->chan->device->dev;
|
|
||||||
enum dma_data_direction dir;
|
|
||||||
int is_play = rsnd_io_is_play(io);
|
|
||||||
dma_addr_t buf;
|
|
||||||
int len, max;
|
|
||||||
size_t period;
|
|
||||||
|
|
||||||
len = dmaen->dma_len;
|
|
||||||
period = dmaen->dma_period;
|
|
||||||
max = len / period;
|
|
||||||
i = i % max;
|
|
||||||
buf = dmaen->dma_buf + (period * i);
|
|
||||||
|
|
||||||
dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
|
|
||||||
|
|
||||||
if (sync)
|
|
||||||
dma_sync_single_for_device(dev, buf, period, dir);
|
|
||||||
else
|
|
||||||
dma_sync_single_for_cpu(dev, buf, period, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
|
static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
|
||||||
struct rsnd_dai_stream *io)
|
struct rsnd_dai_stream *io)
|
||||||
{
|
{
|
||||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||||
struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
|
|
||||||
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
|
|
||||||
bool elapsed = false;
|
bool elapsed = false;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -115,22 +84,9 @@ static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
|
||||||
if (rsnd_io_is_working(io)) {
|
if (rsnd_io_is_working(io))
|
||||||
rsnd_dmaen_unsync(dmaen, io, dmaen->dma_cnt);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Next period is already started.
|
|
||||||
* Let's sync Next Next period
|
|
||||||
* see
|
|
||||||
* rsnd_dmaen_start()
|
|
||||||
*/
|
|
||||||
rsnd_dmaen_sync(dmaen, io, dmaen->dma_cnt + 2);
|
|
||||||
|
|
||||||
elapsed = true;
|
elapsed = true;
|
||||||
|
|
||||||
dmaen->dma_cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
if (elapsed)
|
if (elapsed)
|
||||||
|
@ -165,14 +121,8 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod,
|
||||||
struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
|
struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
|
||||||
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
|
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
|
||||||
|
|
||||||
if (dmaen->chan) {
|
if (dmaen->chan)
|
||||||
int is_play = rsnd_io_is_play(io);
|
|
||||||
|
|
||||||
dmaengine_terminate_all(dmaen->chan);
|
dmaengine_terminate_all(dmaen->chan);
|
||||||
dma_unmap_single(dmaen->chan->device->dev,
|
|
||||||
dmaen->dma_buf, dmaen->dma_len,
|
|
||||||
is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -237,11 +187,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
|
||||||
struct device *dev = rsnd_priv_to_dev(priv);
|
struct device *dev = rsnd_priv_to_dev(priv);
|
||||||
struct dma_async_tx_descriptor *desc;
|
struct dma_async_tx_descriptor *desc;
|
||||||
struct dma_slave_config cfg = {};
|
struct dma_slave_config cfg = {};
|
||||||
dma_addr_t buf;
|
|
||||||
size_t len;
|
|
||||||
size_t period;
|
|
||||||
int is_play = rsnd_io_is_play(io);
|
int is_play = rsnd_io_is_play(io);
|
||||||
int i;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
|
cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
|
||||||
|
@ -258,19 +204,10 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
len = snd_pcm_lib_buffer_bytes(substream);
|
|
||||||
period = snd_pcm_lib_period_bytes(substream);
|
|
||||||
buf = dma_map_single(dmaen->chan->device->dev,
|
|
||||||
substream->runtime->dma_area,
|
|
||||||
len,
|
|
||||||
is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
|
||||||
if (dma_mapping_error(dmaen->chan->device->dev, buf)) {
|
|
||||||
dev_err(dev, "dma map failed\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
desc = dmaengine_prep_dma_cyclic(dmaen->chan,
|
desc = dmaengine_prep_dma_cyclic(dmaen->chan,
|
||||||
buf, len, period,
|
substream->runtime->dma_addr,
|
||||||
|
snd_pcm_lib_buffer_bytes(substream),
|
||||||
|
snd_pcm_lib_period_bytes(substream),
|
||||||
is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
|
is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
|
||||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||||
|
|
||||||
|
@ -282,18 +219,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
|
||||||
desc->callback = rsnd_dmaen_complete;
|
desc->callback = rsnd_dmaen_complete;
|
||||||
desc->callback_param = rsnd_mod_get(dma);
|
desc->callback_param = rsnd_mod_get(dma);
|
||||||
|
|
||||||
dmaen->dma_buf = buf;
|
dmaen->dma_len = snd_pcm_lib_buffer_bytes(substream);
|
||||||
dmaen->dma_len = len;
|
|
||||||
dmaen->dma_period = period;
|
|
||||||
dmaen->dma_cnt = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* synchronize this and next period
|
|
||||||
* see
|
|
||||||
* __rsnd_dmaen_complete()
|
|
||||||
*/
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
rsnd_dmaen_sync(dmaen, io, i);
|
|
||||||
|
|
||||||
dmaen->cookie = dmaengine_submit(desc);
|
dmaen->cookie = dmaengine_submit(desc);
|
||||||
if (dmaen->cookie < 0) {
|
if (dmaen->cookie < 0) {
|
||||||
|
|
|
@ -446,25 +446,29 @@ static bool rsnd_ssi_pointer_update(struct rsnd_mod *mod,
|
||||||
int byte)
|
int byte)
|
||||||
{
|
{
|
||||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||||
|
bool ret = false;
|
||||||
|
int byte_pos;
|
||||||
|
|
||||||
ssi->byte_pos += byte;
|
byte_pos = ssi->byte_pos + byte;
|
||||||
|
|
||||||
if (ssi->byte_pos >= ssi->next_period_byte) {
|
if (byte_pos >= ssi->next_period_byte) {
|
||||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||||
|
|
||||||
ssi->period_pos++;
|
ssi->period_pos++;
|
||||||
ssi->next_period_byte += ssi->byte_per_period;
|
ssi->next_period_byte += ssi->byte_per_period;
|
||||||
|
|
||||||
if (ssi->period_pos >= runtime->periods) {
|
if (ssi->period_pos >= runtime->periods) {
|
||||||
ssi->byte_pos = 0;
|
byte_pos = 0;
|
||||||
ssi->period_pos = 0;
|
ssi->period_pos = 0;
|
||||||
ssi->next_period_byte = ssi->byte_per_period;
|
ssi->next_period_byte = ssi->byte_per_period;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
WRITE_ONCE(ssi->byte_pos, byte_pos);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -838,7 +842,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod,
|
||||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||||
|
|
||||||
*pointer = bytes_to_frames(runtime, ssi->byte_pos);
|
*pointer = bytes_to_frames(runtime, READ_ONCE(ssi->byte_pos));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
|
||||||
{
|
{
|
||||||
int hdmi = rsnd_ssi_hdmi_port(io);
|
int hdmi = rsnd_ssi_hdmi_port(io);
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 mode = 0;
|
||||||
|
|
||||||
ret = rsnd_ssiu_init(mod, io, priv);
|
ret = rsnd_ssiu_init(mod, io, priv);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -136,9 +137,11 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
|
||||||
* see
|
* see
|
||||||
* rsnd_ssi_config_init()
|
* rsnd_ssi_config_init()
|
||||||
*/
|
*/
|
||||||
rsnd_mod_write(mod, SSI_MODE, 0x1);
|
mode = 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rsnd_mod_write(mod, SSI_MODE, mode);
|
||||||
|
|
||||||
if (rsnd_ssi_use_busif(io)) {
|
if (rsnd_ssi_use_busif(io)) {
|
||||||
rsnd_mod_write(mod, SSI_BUSIF_ADINR,
|
rsnd_mod_write(mod, SSI_BUSIF_ADINR,
|
||||||
rsnd_get_adinr_bit(mod, io) |
|
rsnd_get_adinr_bit(mod, io) |
|
||||||
|
|
Loading…
Reference in New Issue