Skip to content

Commit 72ebd4d

Browse files
committed
Merge branch 'linux-5.15-trunk/at91/audio' into linux-5.15-mchp
2 parents 1992bbe + e678a68 commit 72ebd4d

4 files changed

Lines changed: 84 additions & 50 deletions

File tree

sound/soc/atmel/mchp-asrc-dma.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ static void mchp_asrc_start_handle(unsigned long data)
258258
dma_async_issue_pending(dma_be_priv->desc->chan);
259259
}
260260

261-
static int mchp_asrc_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
261+
static int mchp_asrc_dmaengine_pcm_prepare_slave_config(struct device *dev,
262+
struct snd_pcm_substream *substream,
262263
struct snd_pcm_hw_params *params,
263264
struct snd_dmaengine_dai_dma_data *dma_data,
264265
struct dma_slave_config *slave_config)
@@ -270,6 +271,14 @@ static int mchp_asrc_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream
270271
return ret;
271272

272273
snd_dmaengine_pcm_set_config_from_dai_data(substream, dma_data, slave_config);
274+
dev_dbg(dev,
275+
"%s() FE AIF dir %s, src addr %#x, dst addr: %#x, src_addr_width %d, dst_addr_width %d, src maxburst %u, dst maxburst %u\n",
276+
__func__,
277+
slave_config->direction == DMA_MEM_TO_DEV ? "DMA_MEM_TO_DEV" :
278+
"DMA_DEV_TO_MEM",
279+
slave_config->src_addr, slave_config->dst_addr,
280+
slave_config->src_addr_width, slave_config->dst_addr_width,
281+
slave_config->src_maxburst, slave_config->dst_maxburst);
273282

274283
return 0;
275284
}
@@ -476,8 +485,8 @@ static int mchp_asrc_dma_hw_params(struct snd_soc_component *component,
476485
goto __cleanup_free_fe;
477486
}
478487

479-
ret = mchp_asrc_dmaengine_pcm_prepare_slave_config(substream, params, dma_data_fe,
480-
&config_fe);
488+
ret = mchp_asrc_dmaengine_pcm_prepare_slave_config(dev, substream, params,
489+
dma_data_fe, &config_fe);
481490
if (ret) {
482491
dev_err(dev, "failed to prepare DMA config for FE %s\n", cpu_dai->name);
483492
goto __cleanup_dma_fe;
@@ -759,8 +768,11 @@ static int mchp_asrc_dma_prepare(struct snd_soc_component *component,
759768
}
760769
dma_fe_priv->desc = desc;
761770

762-
dev_dbg(dev, "%s() FE buffer_size %ld, period_size %ld\n", __func__,
763-
subs->runtime->buffer_size, subs->runtime->period_size);
771+
dev_dbg(dev,
772+
"%s() FE buffer_size(periods) %ld, buffer_size(bytes) %u period_size(frames) %ld period_size(bytes) %u\n",
773+
__func__,
774+
subs->runtime->buffer_size, snd_pcm_lib_buffer_bytes(subs),
775+
subs->runtime->period_size, snd_pcm_lib_period_bytes(subs));
764776
dma_fe_priv->desc->callback = mchp_asrc_pcm_dma_complete;
765777
dma_fe_priv->desc->callback_param = subs;
766778
} else {

sound/soc/atmel/mchp-asrc.c

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/io.h>
1414
#include <linux/lcm.h>
1515
#include <linux/list.h>
16+
#include <linux/minmax.h>
1617
#include <linux/module.h>
1718
#include <linux/slab.h>
1819

@@ -365,7 +366,6 @@ struct mchp_asrc_be_rtm {
365366
struct mchp_asrc_be_trigger *trig; /* backpointer */
366367
struct snd_pcm_hw_params *hw_params; // used by the links that are not BE
367368
struct mchp_asrc_slot const *slot;
368-
int maxburst;
369369
struct list_head list;
370370
};
371371

@@ -388,6 +388,7 @@ struct mchp_asrc_pcm_priv {
388388
struct xmit_ch *tc;
389389
struct mchp_asrc_be_rtm rtm_fe; /* used for FE --- BEs links */
390390
int refcount;
391+
int maxburst;
391392
bool is_hostless;
392393
};
393394

@@ -405,18 +406,18 @@ struct mchp_asrc_dev {
405406
int rhr_opmode;
406407
};
407408

408-
static inline int mchp_asrc_period_to_burst(int period_size)
409+
static inline int mchp_asrc_period_to_burst(int period_size, int sample_size)
409410
{
410-
if (!(period_size % 16))
411+
if (!(period_size % (sample_size * 16)))
411412
return 16;
412413

413-
if (!(period_size % 8))
414+
if (!(period_size % (sample_size * 8)))
414415
return 8;
415416

416-
if (!(period_size % 4))
417+
if (!(period_size % (sample_size * 4)))
417418
return 4;
418419

419-
if (!(period_size % 2))
420+
if (!(period_size % (sample_size * 2)))
420421
return 2;
421422

422423
return 1;
@@ -700,7 +701,6 @@ static int mchp_asrc_bes_get(struct mchp_asrc_dev *priv, struct snd_pcm_substrea
700701
struct snd_soc_pcm_runtime *be = dpcm->be;
701702
struct snd_soc_dai *dai = asoc_rtd_to_cpu(be, 0);
702703
struct snd_pcm_substream *substream_be;
703-
int period_bytes;
704704

705705
if (dpcm->fe != rtd)
706706
continue;
@@ -715,7 +715,6 @@ static int mchp_asrc_bes_get(struct mchp_asrc_dev *priv, struct snd_pcm_substrea
715715
params_format(&dpcm->hw_params), params_width(&dpcm->hw_params),
716716
params_channels(&dpcm->hw_params));
717717

718-
period_bytes = snd_pcm_lib_period_bytes(substream_be);
719718
for (i = 0; i < priv->trig_count; i++) {
720719
struct mchp_asrc_be_trigger *trig_be = &priv->trig[i];
721720
struct mchp_asrc_be_rtm *rtm_be;
@@ -730,7 +729,6 @@ static int mchp_asrc_bes_get(struct mchp_asrc_dev *priv, struct snd_pcm_substrea
730729
if (set_trig)
731730
rtm_be->trig = trig_be;
732731
rtm_be->hw_params = &dpcm->hw_params;
733-
rtm_be->maxburst = mchp_asrc_period_to_burst(period_bytes);
734732

735733
/* keep the order */
736734
list_add_tail(&rtm_be->list, head);
@@ -987,11 +985,11 @@ static void mchp_asrc_tc_free(struct mchp_asrc_dev *priv, struct mchp_asrc_pcm_p
987985
MCHP_ASRC_CH_CONF_THROPMODE_MASK | MCHP_ASRC_CH_CONF_RHROPMODE_MASK, 0);
988986
}
989987

990-
static void mchp_asrc_maxburst_limit(int thr_opmode, int rhr_opmode,
991-
int dsps_used, bool is_mono,
988+
/* apply HW DMA Chunk Size limitations */
989+
static void mchp_asrc_maxburst_limit(int thr_opmode, int rhr_opmode, bool is_mono,
992990
int *maxburst)
993991
{
994-
if ((thr_opmode == 0 || rhr_opmode == 0 || dsps_used == 1) &&
992+
if ((thr_opmode == 0 || rhr_opmode == 0) &&
995993
*maxburst > 4) {
996994
if (is_mono)
997995
*maxburst = 4;
@@ -1031,9 +1029,9 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
10311029
int ratio_min;
10321030
struct list_head *list_head_bes;
10331031
int i;
1034-
int maxburst[MCHP_ASRC_NB_STEREO_CH] = {0};
10351032
struct opmode_to_slot const *be_opm;
10361033
struct xmit_ch *tc;
1034+
bool is_mono = false;
10371035

10381036
dev_dbg(priv->dev, "%s() DAI %s id %d rate=%u format=%#x width=%u channels=%u\n",
10391037
__func__, dai->name, dai->id, fs, params ? params_format(params) : 0,
@@ -1093,11 +1091,8 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
10931091
dsps_req = (ret + 1) / 2;
10941092

10951093
if (!pcm->is_hostless) {
1096-
int period_size = snd_pcm_lib_period_bytes(substream);
1097-
10981094
pcm->rtm_fe.hw_params = params;
10991095
pcm->rtm_fe.trig = NULL;
1100-
pcm->rtm_fe.maxburst = mchp_asrc_period_to_burst(period_size);
11011096

11021097
/* keep the order */
11031098
if (is_playback)
@@ -1167,12 +1162,17 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
11671162
struct mchp_asrc_slot const *slot_be = rtm_be->slot;
11681163
int chan_be = params_channels(rtm_be->hw_params);
11691164
u32 idx = trig_be ? trig_be->idx : 0;
1165+
int physical_width = params_physical_width(rtm_be->hw_params) / 8;
1166+
int period_bytes = params_period_size(rtm_be->hw_params) *
1167+
params_channels(rtm_be->hw_params) * physical_width;
1168+
int maxburst = mchp_asrc_period_to_burst(period_bytes, physical_width);
11701169

11711170
/* treat odd streams, set only last DSP as mono */
11721171
if (chan_be % 2) {
11731172
dsp = slot_be->first_dsp + slot_be->dsp_count - 1;
11741173
ch_conf |= MCHP_ASRC_CH_CONF_MONO(dsp);
11751174
ch_conf_mask |= MCHP_ASRC_CH_CONF_MONO(dsp);
1175+
is_mono = true;
11761176
}
11771177

11781178
for (dsp = slot_be->first_dsp;
@@ -1191,23 +1191,32 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
11911191
if (max_sr < params_rate(rtm_be->hw_params))
11921192
max_sr = params_rate(rtm_be->hw_params);
11931193

1194-
maxburst[slot_be->slot_id] = rtm_be->maxburst;
1194+
if (pcm->maxburst)
1195+
pcm->maxburst = min(pcm->maxburst, maxburst);
1196+
else
1197+
pcm->maxburst = maxburst;
11951198

1196-
mchp_asrc_maxburst_limit(priv->thr_opmode, priv->rhr_opmode, slot_be->dsp_count,
1197-
chan_be % 2, &maxburst[slot_be->slot_id]);
1199+
dev_dbg(priv->dev, "%s: period bytes %d, width %d -> maxburst %d\n",
1200+
trig_be ? trig_be->phandle->np->full_name : dai->name,
1201+
period_bytes, physical_width, maxburst);
11981202
}
11991203

12001204
list_for_each_entry(rtm_be, &pcm->list_head_out, list) {
12011205
struct mchp_asrc_be_trigger *trig_be = rtm_be->trig;
12021206
struct mchp_asrc_slot const *slot_be = rtm_be->slot;
12031207
int chan_be = params_channels(rtm_be->hw_params);
1208+
int physical_width = params_physical_width(rtm_be->hw_params) / 8;
1209+
int period_bytes = params_period_size(rtm_be->hw_params) *
1210+
params_channels(rtm_be->hw_params) * physical_width;
1211+
int maxburst = mchp_asrc_period_to_burst(period_bytes, physical_width);
12041212
u32 idx = trig_be ? trig_be->idx : 0;
12051213

12061214
/* treat odd streams, set only last DSP as mono */
12071215
if (chan_be % 2) {
12081216
dsp = slot_be->first_dsp + slot_be->dsp_count - 1;
12091217
ch_conf |= MCHP_ASRC_CH_CONF_MONO(dsp);
12101218
ch_conf_mask |= MCHP_ASRC_CH_CONF_MONO(dsp);
1219+
is_mono = true;
12111220
}
12121221

12131222
for (dsp = slot_be->first_dsp;
@@ -1226,15 +1235,19 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12261235
if (max_sr < params_rate(rtm_be->hw_params))
12271236
max_sr = params_rate(rtm_be->hw_params);
12281237

1229-
if (!maxburst[slot_be->slot_id] ||
1230-
maxburst[slot_be->slot_id] > rtm_be->maxburst)
1231-
maxburst[slot_be->slot_id] = rtm_be->maxburst;
1238+
if (pcm->maxburst)
1239+
pcm->maxburst = min(pcm->maxburst, maxburst);
1240+
else
1241+
pcm->maxburst = maxburst;
12321242

1233-
mchp_asrc_maxburst_limit(priv->thr_opmode, priv->rhr_opmode,
1234-
slot_be->dsp_count, chan_be % 2,
1235-
&maxburst[slot_be->slot_id]);
1243+
dev_dbg(priv->dev, "%s: period bytes %d, width %d -> maxburst %d\n",
1244+
trig_be ? trig_be->phandle->np->full_name : dai->name,
1245+
period_bytes, physical_width, maxburst);
12361246
}
12371247

1248+
mchp_asrc_maxburst_limit(priv->thr_opmode, priv->rhr_opmode, is_mono, &pcm->maxburst);
1249+
dev_dbg(priv->dev, "maxburst value to be used by all DSPs: %d\n", pcm->maxburst);
1250+
12381251
/* set DMAengine data for each IN/OUT AIF */
12391252
INIT_LIST_HEAD(&dma->dma_in_list);
12401253
list_for_each_entry(rtm_be, &pcm->list_head_in, list) {
@@ -1256,7 +1269,7 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12561269
ret = -ENOMEM;
12571270
goto __cleanup_dma_bes;
12581271
}
1259-
dma_data_be->maxburst = maxburst[slot_be->slot_id];
1272+
dma_data_be->maxburst = pcm->maxburst;
12601273

12611274
/* keep the order of the BEs */
12621275
list_add_tail(&dma_be->list, &dma->dma_in_list);
@@ -1288,13 +1301,13 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12881301
ret = -ENOMEM;
12891302
goto __cleanup_dma_bes;
12901303
}
1291-
dma_data_be->maxburst = maxburst[slot_be->slot_id];
1304+
dma_data_be->maxburst = pcm->maxburst;
12921305

12931306
/* needed only once, since the same DPSs are used for IN and OUT AIFs */
12941307
for (dsp = slot_be->first_dsp; dsp < slot_be->first_dsp + slot_be->dsp_count;
12951308
dsp++) {
12961309
ch_conf |= mchp_asrc_burst_to_chunk(dsp,
1297-
maxburst[slot_be->slot_id]);
1310+
pcm->maxburst);
12981311
ch_conf_mask |= MCHP_ASRC_CH_CONF_CHUNK_MASK(dsp);
12991312
}
13001313

sound/soc/atmel/mchp-i2s-mcc.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -504,13 +504,13 @@ static int mchp_i2s_mcc_is_running(struct mchp_i2s_mcc_dev *dev)
504504
return !!(sr & (MCHP_I2SMCC_SR_TXEN | MCHP_I2SMCC_SR_RXEN));
505505
}
506506

507-
static inline int mchp_i2s_mcc_period_to_maxburst(int period_size)
507+
static inline int mchp_i2s_mcc_period_to_maxburst(int period_size, int sample_size)
508508
{
509-
if (!(period_size % 8))
509+
if (!(period_size % (sample_size * 8)))
510510
return 8;
511-
if (!(period_size % 4))
511+
if (!(period_size % (sample_size * 4)))
512512
return 4;
513-
if (!(period_size % 2))
513+
if (!(period_size % (sample_size * 2)))
514514
return 2;
515515
return 1;
516516
}
@@ -521,7 +521,10 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
521521
{
522522
unsigned long rate = 0;
523523
struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
524-
int period_size = snd_pcm_lib_period_bytes(substream);
524+
int sample_bytes = params_physical_width(params) / 8;
525+
int period_bytes = params_period_size(params) *
526+
params_channels(params) * sample_bytes;
527+
int maxburst;
525528
u32 mra = 0;
526529
u32 mrb = 0;
527530
unsigned int channels = params_channels(params);
@@ -531,9 +534,9 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
531534
int ret;
532535
bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
533536

534-
dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
537+
dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u period_bytes=%d\n",
535538
__func__, params_rate(params), params_format(params),
536-
params_width(params), params_channels(params));
539+
params_width(params), params_channels(params), period_bytes);
537540

538541
switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
539542
case SND_SOC_DAIFMT_I2S:
@@ -642,11 +645,12 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
642645
* We must have the same burst size configured
643646
* in the DMA transfer and in out IP
644647
*/
645-
mrb |= MCHP_I2SMCC_MRB_DMACHUNK(mchp_i2s_mcc_period_to_maxburst(period_size));
648+
maxburst = mchp_i2s_mcc_period_to_maxburst(period_bytes, sample_bytes);
649+
mrb |= MCHP_I2SMCC_MRB_DMACHUNK(maxburst);
646650
if (is_playback)
647-
dev->playback.maxburst = mchp_i2s_mcc_period_to_maxburst(period_size);
651+
dev->playback.maxburst = maxburst;
648652
else
649-
dev->capture.maxburst = mchp_i2s_mcc_period_to_maxburst(period_size);
653+
dev->capture.maxburst = maxburst;
650654

651655
switch (params_format(params)) {
652656
case SNDRV_PCM_FORMAT_S8:

sound/soc/atmel/mchp-pdmc.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -506,13 +506,13 @@ static u32 mchp_pdmc_mr_set_osr(int audio_filter_en, unsigned int osr)
506506
return 0;
507507
}
508508

509-
static inline int mchp_pdmc_period_to_maxburst(int period_size)
509+
static inline int mchp_pdmc_period_to_maxburst(int period_size, int sample_size)
510510
{
511-
if (!(period_size % 8))
511+
if (!(period_size % (sample_size * 8)))
512512
return 8;
513-
if (!(period_size % 4))
513+
if (!(period_size % (sample_size * 4)))
514514
return 4;
515-
if (!(period_size % 2))
515+
if (!(period_size % (sample_size * 2)))
516516
return 2;
517517
return 1;
518518
}
@@ -542,14 +542,18 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
542542
unsigned int channels = params_channels(params);
543543
unsigned int osr = 0, osr_start;
544544
unsigned int fs = params_rate(params);
545+
int sample_bytes = params_physical_width(params) / 8;
546+
int period_bytes = params_period_size(params) *
547+
params_channels(params) * sample_bytes;
548+
int maxburst;
545549
u32 mr_val = 0;
546550
u32 cfgr_val = 0;
547551
int i;
548552
int ret;
549553

550-
dev_dbg(comp->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
554+
dev_dbg(comp->dev, "%s() rate=%u format=%#x width=%u channels=%u period_bytes=%d\n",
551555
__func__, params_rate(params), params_format(params),
552-
params_width(params), params_channels(params));
556+
params_width(params), params_channels(params), period_bytes);
553557

554558
if (channels > dd->mic_no) {
555559
dev_err(comp->dev, "more channels %u than microphones %d\n",
@@ -611,7 +615,8 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
611615

612616
mr_val |= MCHP_PDMC_MR_SINCORDER(dd->sinc_order);
613617

614-
dd->addr.maxburst = mchp_pdmc_period_to_maxburst(snd_pcm_lib_period_bytes(substream));
618+
maxburst = mchp_pdmc_period_to_maxburst(period_bytes, sample_bytes);
619+
dd->addr.maxburst = maxburst;
615620
mr_val |= MCHP_PDMC_MR_CHUNK(dd->addr.maxburst);
616621
dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst);
617622

0 commit comments

Comments
 (0)