Merge series "ASoC: Intel: catpt: Offload fixes and code optimization" from Cezary...
authorMark Brown <broonie@kernel.org>
Mon, 16 Nov 2020 23:28:03 +0000 (23:28 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 16 Nov 2020 23:28:03 +0000 (23:28 +0000)
First two of the series address bugs connected mainly to offload streams:
- scenarios with very low buffer sizes: RESET_STREAM IPC timeouts
- fix lp clock selection when switching between PAUSE <-> RESUME states:
  glitches on first offload when no additional stream is opened
  simultaneously

Follow ups are: code reduction and optimization oriented patches.
This has been foretold in:

[PATCH v10 00/14] ASoC: Intel: Catpt - Lynx and Wildcat point
https://www.spinics.net/lists/alsa-devel/msg116440.html
  Note: LPT power up/down sequences might get aligned with WPT once
  enough testing is done as capabilities are shared for both DSPs.

First, optimize applying of user settings - prevent redundand calls from
happening - and then as mentioned above, streamline power on/off sequence
for LPT and WPT.

Cezary Rojewski (5):
  ASoC: Intel: catpt: Skip position update for unprepared streams
  ASoC: Intel: catpt: Correct clock selection for dai trigger
  ASoC: Intel: catpt: Optimize applying user settings
  ASoC: Intel: catpt: Streamline power routines across LPT and WPT
  ASoC: Intel: catpt: Cleanup after power routines streamlining

 sound/soc/intel/catpt/core.h   |  10 ++-
 sound/soc/intel/catpt/device.c |  18 +++---
 sound/soc/intel/catpt/dsp.c    |  56 ++--------------
 sound/soc/intel/catpt/pcm.c    | 113 ++++++++++++++++-----------------
 4 files changed, 74 insertions(+), 123 deletions(-)

--
2.17.1

base-commit: 3650b228f83adda7e5ee532e2b90429c03f7b9ec

sound/soc/intel/catpt/core.h
sound/soc/intel/catpt/device.c
sound/soc/intel/catpt/dsp.c
sound/soc/intel/catpt/pcm.c

index 88dc3fb..0f53a0d 100644 (file)
@@ -80,9 +80,9 @@ struct catpt_spec {
        u32 host_ssp_offset[CATPT_SSP_COUNT];
        u32 dram_mask;
        u32 iram_mask;
+       u32 d3srampgd_bit;
+       u32 d3pgd_bit;
        void (*pll_shutdown)(struct catpt_dev *cdev, bool enable);
-       int (*power_up)(struct catpt_dev *cdev);
-       int (*power_down)(struct catpt_dev *cdev);
 };
 
 struct catpt_dev {
@@ -126,10 +126,8 @@ int catpt_dma_memcpy_fromdsp(struct catpt_dev *cdev, struct dma_chan *chan,
 
 void lpt_dsp_pll_shutdown(struct catpt_dev *cdev, bool enable);
 void wpt_dsp_pll_shutdown(struct catpt_dev *cdev, bool enable);
-int lpt_dsp_power_up(struct catpt_dev *cdev);
-int lpt_dsp_power_down(struct catpt_dev *cdev);
-int wpt_dsp_power_up(struct catpt_dev *cdev);
-int wpt_dsp_power_down(struct catpt_dev *cdev);
+int catpt_dsp_power_up(struct catpt_dev *cdev);
+int catpt_dsp_power_down(struct catpt_dev *cdev);
 int catpt_dsp_stall(struct catpt_dev *cdev, bool stall);
 void catpt_dsp_update_srampge(struct catpt_dev *cdev, struct resource *sram,
                              unsigned long mask);
index a701799..b1d3808 100644 (file)
@@ -69,7 +69,7 @@ release_dma_chan:
        dma_release_channel(chan);
        if (ret)
                return ret;
-       return cdev->spec->power_down(cdev);
+       return catpt_dsp_power_down(cdev);
 }
 
 static int __maybe_unused catpt_resume(struct device *dev)
@@ -77,7 +77,7 @@ static int __maybe_unused catpt_resume(struct device *dev)
        struct catpt_dev *cdev = dev_get_drvdata(dev);
        int ret, i;
 
-       ret = cdev->spec->power_up(cdev);
+       ret = catpt_dsp_power_up(cdev);
        if (ret)
                return ret;
 
@@ -162,7 +162,7 @@ static int catpt_probe_components(struct catpt_dev *cdev)
 {
        int ret;
 
-       ret = cdev->spec->power_up(cdev);
+       ret = catpt_dsp_power_up(cdev);
        if (ret)
                return ret;
 
@@ -204,7 +204,7 @@ err_reg_board:
 err_boot_fw:
        catpt_dmac_remove(cdev);
 err_dmac_probe:
-       cdev->spec->power_down(cdev);
+       catpt_dsp_power_down(cdev);
 
        return ret;
 }
@@ -293,7 +293,7 @@ static int catpt_acpi_remove(struct platform_device *pdev)
 
        snd_soc_unregister_component(cdev->dev);
        catpt_dmac_remove(cdev);
-       cdev->spec->power_down(cdev);
+       catpt_dsp_power_down(cdev);
 
        catpt_sram_free(&cdev->iram);
        catpt_sram_free(&cdev->dram);
@@ -311,9 +311,9 @@ static struct catpt_spec lpt_desc = {
        .host_ssp_offset = { 0x0E8000, 0x0E9000 },
        .dram_mask = LPT_VDRTCTL0_DSRAMPGE_MASK,
        .iram_mask = LPT_VDRTCTL0_ISRAMPGE_MASK,
+       .d3srampgd_bit = LPT_VDRTCTL0_D3SRAMPGD,
+       .d3pgd_bit = LPT_VDRTCTL0_D3PGD,
        .pll_shutdown = lpt_dsp_pll_shutdown,
-       .power_up = lpt_dsp_power_up,
-       .power_down = lpt_dsp_power_down,
 };
 
 static struct catpt_spec wpt_desc = {
@@ -326,9 +326,9 @@ static struct catpt_spec wpt_desc = {
        .host_ssp_offset = { 0x0FC000, 0x0FD000 },
        .dram_mask = WPT_VDRTCTL0_DSRAMPGE_MASK,
        .iram_mask = WPT_VDRTCTL0_ISRAMPGE_MASK,
+       .d3srampgd_bit = WPT_VDRTCTL0_D3SRAMPGD,
+       .d3pgd_bit = WPT_VDRTCTL0_D3PGD,
        .pll_shutdown = wpt_dsp_pll_shutdown,
-       .power_up = wpt_dsp_power_up,
-       .power_down = wpt_dsp_power_down,
 };
 
 static const struct acpi_device_id catpt_ids[] = {
index 9e807b9..9c5fd18 100644 (file)
@@ -344,53 +344,7 @@ static void catpt_dsp_set_regs_defaults(struct catpt_dev *cdev)
        }
 }
 
-int lpt_dsp_power_down(struct catpt_dev *cdev)
-{
-       catpt_dsp_reset(cdev, true);
-
-       /* set 24Mhz clock for both SSPs */
-       catpt_updatel_shim(cdev, CS1, CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1),
-                          CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1));
-       catpt_dsp_select_lpclock(cdev, true, false);
-
-       /* DRAM power gating all */
-       catpt_dsp_set_srampge(cdev, &cdev->dram, cdev->spec->dram_mask,
-                             cdev->spec->dram_mask);
-       catpt_dsp_set_srampge(cdev, &cdev->iram, cdev->spec->iram_mask,
-                             cdev->spec->iram_mask);
-
-       catpt_updatel_pci(cdev, PMCS, PCI_PM_CTRL_STATE_MASK, PCI_D3hot);
-       /* give hw time to drop off */
-       udelay(50);
-
-       return 0;
-}
-
-int lpt_dsp_power_up(struct catpt_dev *cdev)
-{
-       /* SRAM power gating none */
-       catpt_dsp_set_srampge(cdev, &cdev->dram, cdev->spec->dram_mask, 0);
-       catpt_dsp_set_srampge(cdev, &cdev->iram, cdev->spec->iram_mask, 0);
-
-       catpt_updatel_pci(cdev, PMCS, PCI_PM_CTRL_STATE_MASK, PCI_D0);
-       /* give hw time to wake up */
-       udelay(100);
-
-       catpt_dsp_select_lpclock(cdev, false, false);
-       catpt_updatel_shim(cdev, CS1,
-                          CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1),
-                          CATPT_CS_SBCS(0) | CATPT_CS_SBCS(1));
-       /* stagger DSP reset after clock selection */
-       udelay(50);
-
-       catpt_dsp_reset(cdev, false);
-       /* generate int deassert msg to fix inversed int logic */
-       catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCDB | CATPT_IMC_IPCCD, 0);
-
-       return 0;
-}
-
-int wpt_dsp_power_down(struct catpt_dev *cdev)
+int catpt_dsp_power_down(struct catpt_dev *cdev)
 {
        u32 mask, val;
 
@@ -420,8 +374,8 @@ int wpt_dsp_power_down(struct catpt_dev *cdev)
                              cdev->spec->dram_mask);
        catpt_dsp_set_srampge(cdev, &cdev->iram, cdev->spec->iram_mask,
                              cdev->spec->iram_mask);
-       mask = WPT_VDRTCTL0_D3SRAMPGD | WPT_VDRTCTL0_D3PGD;
-       catpt_updatel_pci(cdev, VDRTCTL0, mask, WPT_VDRTCTL0_D3PGD);
+       mask = cdev->spec->d3srampgd_bit | cdev->spec->d3pgd_bit;
+       catpt_updatel_pci(cdev, VDRTCTL0, mask, cdev->spec->d3pgd_bit);
 
        catpt_updatel_pci(cdev, PMCS, PCI_PM_CTRL_STATE_MASK, PCI_D3hot);
        /* give hw time to drop off */
@@ -435,7 +389,7 @@ int wpt_dsp_power_down(struct catpt_dev *cdev)
        return 0;
 }
 
-int wpt_dsp_power_up(struct catpt_dev *cdev)
+int catpt_dsp_power_up(struct catpt_dev *cdev)
 {
        u32 mask, val;
 
@@ -450,7 +404,7 @@ int wpt_dsp_power_up(struct catpt_dev *cdev)
        catpt_updatel_pci(cdev, PMCS, PCI_PM_CTRL_STATE_MASK, PCI_D0);
 
        /* SRAM power gating none */
-       mask = WPT_VDRTCTL0_D3SRAMPGD | WPT_VDRTCTL0_D3PGD;
+       mask = cdev->spec->d3srampgd_bit | cdev->spec->d3pgd_bit;
        catpt_updatel_pci(cdev, VDRTCTL0, mask, mask);
        catpt_dsp_set_srampge(cdev, &cdev->dram, cdev->spec->dram_mask, 0);
        catpt_dsp_set_srampge(cdev, &cdev->iram, cdev->spec->iram_mask, 0);
index 1775540..e5d54bb 100644 (file)
@@ -324,6 +324,54 @@ static void catpt_dai_shutdown(struct snd_pcm_substream *substream,
        snd_soc_dai_set_dma_data(dai, substream, NULL);
 }
 
+static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol);
+
+static int catpt_dai_apply_usettings(struct snd_soc_dai *dai,
+                                    struct catpt_stream_runtime *stream)
+{
+       struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
+       struct snd_soc_component *component = dai->component;
+       struct snd_kcontrol *pos, *kctl = NULL;
+       const char *name;
+       int ret;
+       u32 id = stream->info.stream_hw_id;
+
+       /* only selected streams have individual controls */
+       switch (id) {
+       case CATPT_PIN_ID_OFFLOAD1:
+               name = "Media0 Playback Volume";
+               break;
+       case CATPT_PIN_ID_OFFLOAD2:
+               name = "Media1 Playback Volume";
+               break;
+       case CATPT_PIN_ID_CAPTURE1:
+               name = "Mic Capture Volume";
+               break;
+       case CATPT_PIN_ID_REFERENCE:
+               name = "Loopback Mute";
+               break;
+       default:
+               return 0;
+       };
+
+       list_for_each_entry(pos, &component->card->snd_card->controls, list) {
+               if (pos->private_data == component &&
+                   !strncmp(name, pos->id.name, sizeof(pos->id.name))) {
+                       kctl = pos;
+                       break;
+               }
+       }
+       if (!kctl)
+               return -ENOENT;
+
+       if (stream->template->type != CATPT_STRM_TYPE_LOOPBACK)
+               return catpt_set_dspvol(cdev, id, (long *)kctl->private_value);
+       ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)kctl->private_value);
+       if (ret)
+               return CATPT_IPC_ERROR(ret);
+       return 0;
+}
+
 static int catpt_dai_hw_params(struct snd_pcm_substream *substream,
                               struct snd_pcm_hw_params *params,
                               struct snd_soc_dai *dai)
@@ -370,6 +418,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream,
        if (ret)
                return CATPT_IPC_ERROR(ret);
 
+       ret = catpt_dai_apply_usettings(dai, stream);
+       if (ret)
+               return ret;
+
        stream->allocated = true;
        return 0;
 }
@@ -391,54 +443,6 @@ static int catpt_dai_hw_free(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol);
-
-static int catpt_dai_apply_usettings(struct snd_soc_dai *dai,
-                                    struct catpt_stream_runtime *stream)
-{
-       struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
-       struct snd_soc_component *component = dai->component;
-       struct snd_kcontrol *pos, *kctl = NULL;
-       const char *name;
-       int ret;
-       u32 id = stream->info.stream_hw_id;
-
-       /* only selected streams have individual controls */
-       switch (id) {
-       case CATPT_PIN_ID_OFFLOAD1:
-               name = "Media0 Playback Volume";
-               break;
-       case CATPT_PIN_ID_OFFLOAD2:
-               name = "Media1 Playback Volume";
-               break;
-       case CATPT_PIN_ID_CAPTURE1:
-               name = "Mic Capture Volume";
-               break;
-       case CATPT_PIN_ID_REFERENCE:
-               name = "Loopback Mute";
-               break;
-       default:
-               return 0;
-       }
-
-       list_for_each_entry(pos, &component->card->snd_card->controls, list) {
-               if (pos->private_data == component &&
-                   !strncmp(name, pos->id.name, sizeof(pos->id.name))) {
-                       kctl = pos;
-                       break;
-               }
-       }
-       if (!kctl)
-               return -ENOENT;
-
-       if (stream->template->type != CATPT_STRM_TYPE_LOOPBACK)
-               return catpt_set_dspvol(cdev, id, (long *)kctl->private_value);
-       ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)kctl->private_value);
-       if (ret)
-               return CATPT_IPC_ERROR(ret);
-       return 0;
-}
-
 static int catpt_dai_prepare(struct snd_pcm_substream *substream,
                             struct snd_soc_dai *dai)
 {
@@ -458,14 +462,6 @@ static int catpt_dai_prepare(struct snd_pcm_substream *substream,
        if (ret)
                return CATPT_IPC_ERROR(ret);
 
-       ret = catpt_dsp_update_lpclock(cdev);
-       if (ret)
-               return ret;
-
-       ret = catpt_dai_apply_usettings(dai, stream);
-       if (ret)
-               return ret;
-
        stream->prepared = true;
        return 0;
 }
@@ -500,6 +496,7 @@ static int catpt_dai_trigger(struct snd_pcm_substream *substream, int cmd,
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
        resume_stream:
+               catpt_dsp_update_lpclock(cdev);
                ret = catpt_ipc_resume_stream(cdev, stream->info.stream_hw_id);
                if (ret)
                        return CATPT_IPC_ERROR(ret);
@@ -507,11 +504,11 @@ static int catpt_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 
        case SNDRV_PCM_TRIGGER_STOP:
                stream->prepared = false;
-               catpt_dsp_update_lpclock(cdev);
                fallthrough;
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
                ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id);
+               catpt_dsp_update_lpclock(cdev);
                if (ret)
                        return CATPT_IPC_ERROR(ret);
                break;
@@ -534,6 +531,8 @@ void catpt_stream_update_position(struct catpt_dev *cdev,
 
        dsppos = bytes_to_frames(r, pos->stream_position);
 
+       if (!stream->prepared)
+               goto exit;
        /* only offload is set_write_pos driven */
        if (stream->template->type != CATPT_STRM_TYPE_RENDER)
                goto exit;