Asoc: qcom: Fix plaback recover problem in suspend resume
Subsystems (4)
PATCH v2 1/1 Asoc: qcom: Fix plaback recover problem in suspend resume
To support playback continuation after hard suspend(bypass powerd)
and resume:
Prepare device in platform trigger callback.
Make I2s and DMA control registers as non volatile.
---
Changes Since v1:
-- Subject lines changed
sound/soc/qcom/lpass-cpu.c | 8 ++------ sound/soc/qcom/lpass-platform.c | 5 +++-- 2 files changed, 5 insertions(+), 8 deletions(-)
sound/soc/qcom/lpass-cpu.c +2 -6
@@ -454,20 +454,16 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)struct lpass_variant *v = drvdata->variant;int i; -for (i =0 ; i < v->i2s_ports; ++i) -if (reg ==LPAIF_I2SCTL_REG (v, i)) -return true;for (i =0 ; i < v->irq_ports; ++i)if (reg ==LPAIF_IRQSTAT_REG (v, i))return true;for (i =0 ; i < v->rdma_channels; ++i) -if (reg ==LPAIF_RDMACURR_REG (v, i) || reg ==LPAIF_RDMACTL_REG (v, i)) +if (reg ==LPAIF_RDMACURR_REG (v, i))return true;for (i =0 ; i < v->wrdma_channels; ++i) -if (reg ==LPAIF_WRDMACURR_REG (v, i + v->wrdma_channel_start) || - reg ==LPAIF_WRDMACTL_REG (v, i + v->wrdma_channel_start)) +if (reg ==LPAIF_WRDMACURR_REG (v, i + v->wrdma_channel_start))return true;return false;
sound/soc/qcom/lpass-platform.c +3 -2
@@ -481,8 +481,9 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,return -ENOTRECOVERABLE ; }switch (cmd) { -case SNDRV_PCM_TRIGGER_START :case SNDRV_PCM_TRIGGER_RESUME : +lpass_platform_pcmops_prepare (component, substream); +case SNDRV_PCM_TRIGGER_START :case SNDRV_PCM_TRIGGER_PAUSE_RELEASE : ret =regmap_fields_write (dmactl->enable, id,LPAIF_DMACTL_ENABLE_ON );
@@ -592,7 +593,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,break ; } -return 0 ; +return ret; } static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
kernel test robot
build botThank you for the patch! Perhaps something to improve:
Hi Srinivasa,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on asoc/for-next]
[also build test WARNING on v5.10-rc5 next-20201127]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Srinivasa-Rao-Mandadapu/Asoc-qcom-Fix-plaback-recover-problem-in-suspend-resume/20201127-170451 base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next config: parisc-randconfig-r031-20201127 (attached as .config) compiler: hppa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/5ac53c5b718810daf83f097680004328545e01ff
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Srinivasa-Rao-Mandadapu/Asoc-qcom-Fix-plaback-recover-problem-in-suspend-resume/20201127-170451 git checkout 5ac53c5b718810daf83f097680004328545e01ff
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=parisc
If you fix the issue, kindly add following tag as appropriate
All warnings (new ones prefixed by >>):
sound/soc/qcom/lpass-platform.c: In function 'lpass_platform_pcmops_trigger':
>> sound/soc/qcom/lpass-platform.c:485:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
485 | lpass_platform_pcmops_prepare(component, substream);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sound/soc/qcom/lpass-platform.c:486:2: note: here
486 | case SNDRV_PCM_TRIGGER_START:
| ^~~~vim +485 sound/soc/qcom/lpass-platform.c
437
438 static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
439 struct snd_pcm_substream *substream,
440 int cmd)
441 {
442 struct snd_soc_pcm_runtime *soc_runtime = asoc_substream_to_rtd(substream);
443 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(soc_runtime, 0);
444 struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
445 struct snd_pcm_runtime *rt = substream->runtime;
446 struct lpass_pcm_data *pcm_data = rt->private_data;
447 struct lpass_variant *v = drvdata->variant;
448 struct lpaif_dmactl *dmactl;
449 struct regmap *map;
450 int ret, ch, id;
451 int dir = substream->stream;
452 unsigned int reg_irqclr = 0, val_irqclr = 0;
453 unsigned int reg_irqen = 0, val_irqen = 0, val_mask = 0;
454 unsigned int dai_id = cpu_dai->driver->id;
455 unsigned int dma_ctrl_reg = 0;
456
457 ch = pcm_data->dma_ch;
458 if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
459 id = pcm_data->dma_ch;
460 if (dai_id == LPASS_DP_RX) {
461 dmactl = drvdata->hdmi_rd_dmactl;
462 map = drvdata->hdmiif_map;
463 } else {
464 dmactl = drvdata->rd_dmactl;
465 map = drvdata->lpaif_map;
466 }
467 } else {
468 dmactl = drvdata->wr_dmactl;
469 id = pcm_data->dma_ch - v->wrdma_channel_start;
470 map = drvdata->lpaif_map;
471 }
472 ret = regmap_read(map, LPAIF_DMACTL_REG(v, ch, dir, dai_id), &dma_ctrl_reg);
473 if (ret) {
474 dev_err(soc_runtime->dev, "error reading from rdmactl reg: %d\n", ret);
475 return ret;
476 }
477
478 if (dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE ||
479 dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE + 1) {
480 dev_err(soc_runtime->dev, "error in rdmactl register state\n");
481 return -ENOTRECOVERABLE;
482 }
483 switch (cmd) {
484 case SNDRV_PCM_TRIGGER_RESUME:
> 485 lpass_platform_pcmops_prepare(component, substream);
486 case SNDRV_PCM_TRIGGER_START:
487 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
488 ret = regmap_fields_write(dmactl->enable, id,
489 LPAIF_DMACTL_ENABLE_ON);
490 if (ret) {
491 dev_err(soc_runtime->dev,
492 "error writing to rdmactl reg: %d\n", ret);
493 return ret;
494 }
495 switch (dai_id) {
496 case LPASS_DP_RX:
497 ret = regmap_fields_write(dmactl->dyncclk, id,
498 LPAIF_DMACTL_DYNCLK_ON);
499 if (ret) {
500 dev_err(soc_runtime->dev,
501 "error writing to rdmactl reg: %d\n", ret);
502 return ret;
503 }
504 map = drvdata->hdmiif_map;
505 reg_irqclr = LPASS_HDMITX_APP_IRQCLEAR_REG(v);
506 val_irqclr = (LPAIF_IRQ_ALL(ch) |
507 LPAIF_IRQ_HDMI_REQ_ON_PRELOAD(ch) |
508 LPAIF_IRQ_HDMI_METADONE |
509 LPAIF_IRQ_HDMI_SDEEP_AUD_DIS(ch));
510
511 reg_irqen = LPASS_HDMITX_APP_IRQEN_REG(v);
512 val_mask = (LPAIF_IRQ_ALL(ch) |
513 LPAIF_IRQ_HDMI_REQ_ON_PRELOAD(ch) |
514 LPAIF_IRQ_HDMI_METADONE |
515 LPAIF_IRQ_HDMI_SDEEP_AUD_DIS(ch));
516 val_irqen = (LPAIF_IRQ_ALL(ch) |
517 LPAIF_IRQ_HDMI_REQ_ON_PRELOAD(ch) |
518 LPAIF_IRQ_HDMI_METADONE |
519 LPAIF_IRQ_HDMI_SDEEP_AUD_DIS(ch));
520 break;
521 case MI2S_PRIMARY:
522 case MI2S_SECONDARY:
523 map = drvdata->lpaif_map;
524 reg_irqclr = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
525 val_irqclr = LPAIF_IRQ_ALL(ch);
526
527
528 reg_irqen = LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST);
529 val_mask = LPAIF_IRQ_ALL(ch);
530 val_irqen = LPAIF_IRQ_ALL(ch);
531 break;
532 default:
533 dev_err(soc_runtime->dev, "%s: invalid %d interface\n", __func__, dai_id);
534 return -EINVAL;
535 }
536
537 ret = regmap_write(map, reg_irqclr, val_irqclr);
538 if (ret) {
539 dev_err(soc_runtime->dev, "error writing to irqclear reg: %d\n", ret);
540 return ret;
541 }
542 ret = regmap_update_bits(map, reg_irqen, val_mask, val_irqen);
543 if (ret) {
544 dev_err(soc_runtime->dev, "error writing to irqen reg: %d\n", ret);
545 return ret;
546 }
547 break;
548 case SNDRV_PCM_TRIGGER_STOP:
549 case SNDRV_PCM_TRIGGER_SUSPEND:
550 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
551 ret = regmap_fields_write(dmactl->enable, id,
552 LPAIF_DMACTL_ENABLE_OFF);
553 if (ret) {
554 dev_err(soc_runtime->dev,
555 "error writing to rdmactl reg: %d\n", ret);
556 return ret;
557 }
558 switch (dai_id) {
559 case LPASS_DP_RX:
560 ret = regmap_fields_write(dmactl->dyncclk, id,
561 LPAIF_DMACTL_DYNCLK_OFF);
562 if (ret) {
563 dev_err(soc_runtime->dev,
564 "error writing to rdmactl reg: %d\n", ret);
565 return ret;
566 }
567 map = drvdata->hdmiif_map;
568 reg_irqen = LPASS_HDMITX_APP_IRQEN_REG(v);
569 val_mask = (LPAIF_IRQ_ALL(ch) |
570 LPAIF_IRQ_HDMI_REQ_ON_PRELOAD(ch) |
571 LPAIF_IRQ_HDMI_METADONE |
572 LPAIF_IRQ_HDMI_SDEEP_AUD_DIS(ch));
573 val_irqen = 0;
574 break;
575 case MI2S_PRIMARY:
576 case MI2S_SECONDARY:
577 map = drvdata->lpaif_map;
578 reg_irqen = LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST);
579 val_mask = LPAIF_IRQ_ALL(ch);
580 val_irqen = 0;
581 break;
582 default:
583 dev_err(soc_runtime->dev, "%s: invalid %d interface\n", __func__, dai_id);
584 return -EINVAL;
585 }
586
587 ret = regmap_update_bits(map, reg_irqen, val_mask, val_irqen);
588 if (ret) {
589 dev_err(soc_runtime->dev,
590 "error writing to irqen reg: %d\n", ret);
591 return ret;
592 }
593 break;
594 }
595
596 return ret;
597 }
598
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org