diff options
author | Mark Brown <broonie@kernel.org> | 2020-09-17 17:35:38 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-09-17 17:35:38 +0200 |
commit | 4db68e62a0b912655c598de829b05b2383da0cab (patch) | |
tree | 14c717646e8de62283aaa9c08b747e8db3871dbd /sound/soc/intel | |
parent | Merge series "ASoC: SOF: DSP core management fixes for 5.10" from Kai Vehmane... (diff) | |
parent | ASoC: tlv320adcx140: Fix BCLK inversion for DSP modes (diff) | |
download | linux-4db68e62a0b912655c598de829b05b2383da0cab.tar.xz linux-4db68e62a0b912655c598de829b05b2383da0cab.zip |
Merge branch 'asoc-5.9' into asoc-5.10
Diffstat (limited to 'sound/soc/intel')
-rw-r--r-- | sound/soc/intel/atom/sst-mfld-platform-pcm.c | 11 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5640.c | 10 | ||||
-rw-r--r-- | sound/soc/intel/boards/skl_hda_dsp_generic.c | 2 | ||||
-rw-r--r-- | sound/soc/intel/haswell/sst-haswell-dsp.c | 185 |
4 files changed, 103 insertions, 105 deletions
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 6add70500ed8..9e9b05883557 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -333,6 +333,17 @@ static int sst_media_open(struct snd_pcm_substream *substream, if (ret_val < 0) goto out_power_up; + /* + * Make sure the period to be multiple of 1ms to align the + * design of firmware. Apply same rule to buffer size to make + * sure alsa could always find a value for period size + * regardless the buffer size given by user space. + */ + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 48); + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 48); + /* Make sure, that the period size is always even */ snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS, 2); diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 479992f4e97a..fc202747ba83 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -591,6 +591,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"), + DMI_MATCH(DMI_PRODUCT_NAME, "Converter9"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { /* MPMAN MPWIN895CL */ .matches = { diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c index ca4900036ead..bc50eda297ab 100644 --- a/sound/soc/intel/boards/skl_hda_dsp_generic.c +++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c @@ -181,7 +181,7 @@ static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card) struct snd_soc_dai *dai; for_each_card_rtds(card, rtd) { - if (!strstr(rtd->dai_link->codecs->name, "ehdaudio")) + if (!strstr(rtd->dai_link->codecs->name, "ehdaudio0D0")) continue; dai = asoc_rtd_to_codec(rtd, 0); hda_pvt = snd_soc_component_get_drvdata(dai->component); diff --git a/sound/soc/intel/haswell/sst-haswell-dsp.c b/sound/soc/intel/haswell/sst-haswell-dsp.c index de80e19454c1..88c3f63bded9 100644 --- a/sound/soc/intel/haswell/sst-haswell-dsp.c +++ b/sound/soc/intel/haswell/sst-haswell-dsp.c @@ -243,92 +243,45 @@ static irqreturn_t hsw_irq(int irq, void *context) return ret; } -#define CSR_DEFAULT_VALUE 0x8480040E -#define ISC_DEFAULT_VALUE 0x0 -#define ISD_DEFAULT_VALUE 0x0 -#define IMC_DEFAULT_VALUE 0x7FFF0003 -#define IMD_DEFAULT_VALUE 0x7FFF0003 -#define IPCC_DEFAULT_VALUE 0x0 -#define IPCD_DEFAULT_VALUE 0x0 -#define CLKCTL_DEFAULT_VALUE 0x7FF -#define CSR2_DEFAULT_VALUE 0x0 -#define LTR_CTRL_DEFAULT_VALUE 0x0 -#define HMD_CTRL_DEFAULT_VALUE 0x0 - -static void hsw_set_shim_defaults(struct sst_dsp *sst) -{ - sst_dsp_shim_write_unlocked(sst, SST_CSR, CSR_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_ISRX, ISC_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_ISRD, ISD_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_IMRX, IMC_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_IMRD, IMD_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_IPCX, IPCC_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_IPCD, IPCD_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_CLKCTL, CLKCTL_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_CSR2, CSR2_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_LTRC, LTR_CTRL_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_HMDC, HMD_CTRL_DEFAULT_VALUE); -} - -/* all clock-gating minus DCLCGE and DTCGE */ -#define SST_VDRTCL2_CG_OTHER 0xB7D - static void hsw_set_dsp_D3(struct sst_dsp *sst) { + u32 val; u32 reg; - /* disable clock core gating */ + /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg &= ~(SST_VDRTCL2_DCLCGE); + reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE); writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* stall, reset and set 24MHz XOSC */ - sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, - SST_CSR_24MHZ_LPCS | SST_CSR_STALL | SST_CSR_RST, - SST_CSR_24MHZ_LPCS | SST_CSR_STALL | SST_CSR_RST); - - /* DRAM power gating all */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); - reg |= SST_VDRTCL0_ISRAMPGE_MASK | - SST_VDRTCL0_DSRAMPGE_MASK; - reg &= ~(SST_VDRTCL0_D3SRAMPGD); - reg |= SST_VDRTCL0_D3PGD; - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); - udelay(50); + /* enable power gating and switch off DRAM & IRAM blocks */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + val |= SST_VDRTCL0_DSRAMPGE_MASK | + SST_VDRTCL0_ISRAMPGE_MASK; + val &= ~(SST_VDRTCL0_D3PGD | SST_VDRTCL0_D3SRAMPGD); + writel(val, sst->addr.pci_cfg + SST_VDRTCTL0); - /* PLL shutdown enable */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_APLLSE_MASK; - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + /* switch off audio PLL */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + val |= SST_VDRTCL2_APLLSE_MASK; + writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); - /* disable MCLK */ + /* disable MCLK(clkctl.smos = 0) */ sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL, - SST_CLKCTL_MASK, 0); - - /* switch clock gating */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_CG_OTHER; - reg &= ~(SST_VDRTCL2_DTCGE); - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* enable DTCGE separatelly */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_DTCGE; - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + SST_CLKCTL_MASK, 0); - /* set shim defaults */ - hsw_set_shim_defaults(sst); - - /* set D3 */ - reg = readl(sst->addr.pci_cfg + SST_PMCS); - reg |= SST_PMCS_PS_MASK; - writel(reg, sst->addr.pci_cfg + SST_PMCS); + /* Set D3 state, delay 50 us */ + val = readl(sst->addr.pci_cfg + SST_PMCS); + val |= SST_PMCS_PS_MASK; + writel(val, sst->addr.pci_cfg + SST_PMCS); udelay(50); - /* enable clock core gating */ + /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_DCLCGE; + reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE; writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + udelay(50); + } static void hsw_reset(struct sst_dsp *sst) @@ -346,62 +299,75 @@ static void hsw_reset(struct sst_dsp *sst) SST_CSR_RST | SST_CSR_STALL, SST_CSR_STALL); } -/* recommended CSR state for power-up */ -#define SST_CSR_D0_MASK (0x18A09C0C | SST_CSR_DCS_MASK) - static int hsw_set_dsp_D0(struct sst_dsp *sst) { - u32 reg; + int tries = 10; + u32 reg, fw_dump_bit; - /* disable clock core gating */ + /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg &= ~(SST_VDRTCL2_DCLCGE); + reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE); writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* switch clock gating */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_CG_OTHER; - reg &= ~(SST_VDRTCL2_DTCGE); - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + /* Disable D3PG (VDRTCTL0.D3PGD = 1) */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + reg |= SST_VDRTCL0_D3PGD; + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); - /* set D0 */ + /* Set D0 state */ reg = readl(sst->addr.pci_cfg + SST_PMCS); - reg &= ~(SST_PMCS_PS_MASK); + reg &= ~SST_PMCS_PS_MASK; writel(reg, sst->addr.pci_cfg + SST_PMCS); - /* DRAM power gating none */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); - reg &= ~(SST_VDRTCL0_ISRAMPGE_MASK | - SST_VDRTCL0_DSRAMPGE_MASK); - reg |= SST_VDRTCL0_D3SRAMPGD; - reg |= SST_VDRTCL0_D3PGD; - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); - mdelay(10); + /* check that ADSP shim is enabled */ + while (tries--) { + reg = readl(sst->addr.pci_cfg + SST_PMCS) & SST_PMCS_PS_MASK; + if (reg == 0) + goto finish; + + msleep(1); + } + + return -ENODEV; - /* set shim defaults */ - hsw_set_shim_defaults(sst); +finish: + /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */ + sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, + SST_CSR_S1IOCS | SST_CSR_SBCS1 | SST_CSR_LPCS, 0x0); + + /* stall DSP core, set clk to 192/96Mhz */ + sst_dsp_shim_update_bits_unlocked(sst, + SST_CSR, SST_CSR_STALL | SST_CSR_DCS_MASK, + SST_CSR_STALL | SST_CSR_DCS(4)); - /* restore MCLK */ + /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */ sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL, - SST_CLKCTL_MASK, SST_CLKCTL_MASK); + SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0, + SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0); - /* PLL shutdown disable */ + /* Stall and reset core, set CSR */ + hsw_reset(sst); + + /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg &= ~(SST_VDRTCL2_APLLSE_MASK); + reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE; writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, - SST_CSR_D0_MASK, SST_CSR_SBCS0 | SST_CSR_SBCS1 | - SST_CSR_STALL | SST_CSR_DCS(4)); udelay(50); - /* enable clock core gating */ + /* switch on audio PLL */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_DCLCGE; + reg &= ~SST_VDRTCL2_APLLSE_MASK; writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* clear reset */ - sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_RST, 0); + /* set default power gating control, enable power gating control for all blocks. that is, + can't be accessed, please enable each block before accessing. */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK; + /* for D0, always enable the block(DSRAM[0]) used for FW dump */ + fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT; + writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0); + /* disable DMA finish function for SSP0 & SSP1 */ sst_dsp_shim_update_bits_unlocked(sst, SST_CSR2, SST_CSR2_SDFD_SSP1, @@ -418,6 +384,12 @@ static int hsw_set_dsp_D0(struct sst_dsp *sst) sst_dsp_shim_update_bits(sst, SST_IMRD, (SST_IMRD_DONE | SST_IMRD_BUSY | SST_IMRD_SSP0 | SST_IMRD_DMAC), 0x0); + /* clear IPC registers */ + sst_dsp_shim_write(sst, SST_IPCX, 0x0); + sst_dsp_shim_write(sst, SST_IPCD, 0x0); + sst_dsp_shim_write(sst, 0x80, 0x6); + sst_dsp_shim_write(sst, 0xe0, 0x300a); + return 0; } @@ -443,6 +415,11 @@ static void hsw_sleep(struct sst_dsp *sst) { dev_dbg(sst->dev, "HSW_PM dsp runtime suspend\n"); + /* put DSP into reset and stall */ + sst_dsp_shim_update_bits(sst, SST_CSR, + SST_CSR_24MHZ_LPCS | SST_CSR_RST | SST_CSR_STALL, + SST_CSR_RST | SST_CSR_STALL | SST_CSR_24MHZ_LPCS); + hsw_set_dsp_D3(sst); dev_dbg(sst->dev, "HSW_PM dsp runtime suspend exit\n"); } |