Skip to contentSkip to conversation

Asoc: qcom: Fix plaback recover problem in suspend resume

PATCH Superseded Srinivasa Rao Mandadapu 2 participants 2 messages Nov 27, 2020

Subsystems (4)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

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
index af684fd..c99be03 100644
@@ -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
index 80b09de..2b0a7c1 100644
@@ -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.
#1 lore raw
Thank 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