Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 150
ASoC: SOF: (Intel HDA) Add support for DSPless debug mode#3962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
90c088b3a81ea5e25ffe055412f5199494d9dd5b23d3a07ae16a20b8b025a8c1391992f35598a4936fa6File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -208,6 +208,11 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) | ||
| /* set up platform component driver */ | ||
| snd_sof_new_platform_drv(sdev); | ||
| if (sdev->dspless_mode_selected) { | ||
| sof_set_fw_state(sdev, SOF_DSPLESS_MODE); | ||
| goto skip_dsp_init; | ||
| } | ||
| /* register any debug/trace capabilities */ | ||
| ret = snd_sof_dbg_init(sdev); | ||
| if (ret < 0) { | ||
| @@ -266,6 +271,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) | ||
| dev_dbg(sdev->dev, "SOF firmware trace disabled\n"); | ||
| } | ||
| skip_dsp_init: | ||
| /* hereafter all FW boot flows are for PM reasons */ | ||
| sdev->first_boot = false; | ||
| @@ -365,6 +371,15 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) | ||
| if (sof_core_debug) | ||
| dev_info(dev, "sof_debug value: %#x\n", sof_core_debug); | ||
| if (sof_debug_check_flag(SOF_DBG_DSPLESS_MODE)) { | ||
| if (plat_data->desc->dspless_mode_supported) { | ||
| dev_info(dev, "Switching to DSPless mode\n"); | ||
| sdev->dspless_mode_selected = true; | ||
| } else { | ||
| dev_info(dev, "DSPless mode is not supported by the platform\n"); | ||
ranj063 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| } | ||
| /* check IPC support */ | ||
| if (!(BIT(plat_data->ipc_type) & plat_data->desc->ipc_supported_mask)) { | ||
| dev_err(dev, "ipc_type %d is not supported on this platform, mask is %#x\n", | ||
| @@ -378,12 +393,18 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) | ||
| return ret; | ||
| /* check all mandatory ops */ | ||
| if (!sof_ops(sdev) || !sof_ops(sdev)->probe || !sof_ops(sdev)->run || | ||
| !sof_ops(sdev)->block_read || !sof_ops(sdev)->block_write || | ||
| !sof_ops(sdev)->send_msg || !sof_ops(sdev)->load_firmware || | ||
| !sof_ops(sdev)->ipc_msg_data) { | ||
| if (!sof_ops(sdev) || !sof_ops(sdev)->probe) { | ||
| sof_ops_free(sdev); | ||
| dev_err(dev, "missing mandatory ops\n"); | ||
| return -EINVAL; | ||
| } | ||
| if (!sdev->dspless_mode_selected && | ||
| (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read || | ||
| !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg || | ||
| !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) { | ||
| sof_ops_free(sdev); | ||
| dev_err(dev, "error: missing mandatory ops\n"); | ||
| dev_err(dev, "missing mandatory DSP ops\n"); | ||
| return -EINVAL; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -319,13 +319,44 @@ static const struct hda_dai_widget_dma_ops hda_ipc3_dma_ops = { | ||
| .post_trigger = hda_ipc3_post_trigger, | ||
| }; | ||
| static struct hdac_ext_stream * | ||
| hda_dspless_get_hext_stream(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, | ||
| struct snd_pcm_substream *substream) | ||
| { | ||
| struct hdac_stream *hstream = substream->runtime->private_data; | ||
| return stream_to_hdac_ext_stream(hstream); | ||
| } | ||
| static void hda_dspless_setup_hext_stream(struct snd_sof_dev *sdev, | ||
| struct hdac_ext_stream *hext_stream, | ||
| unsigned int format_val) | ||
| { | ||
| /* | ||
| * Save the format_val which was adjusted by the maxbps of the codec. | ||
| * This information is not available on the FE side since there we are | ||
| * using dummy_codec. | ||
| */ | ||
| hext_stream->hstream.format_val = format_val; | ||
ranj063 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| static const struct hda_dai_widget_dma_ops hda_dspless_dma_ops = { | ||
| .get_hext_stream = hda_dspless_get_hext_stream, | ||
| .setup_hext_stream = hda_dspless_setup_hext_stream, | ||
| }; | ||
| #endif | ||
| const struct hda_dai_widget_dma_ops * | ||
| hda_select_dai_widget_ops(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) | ||
| { | ||
| #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) | ||
| struct snd_sof_dai *sdai = swidget->private; | ||
| struct snd_sof_dai *sdai; | ||
| if (sdev->dspless_mode_selected) | ||
| return &hda_dspless_dma_ops; | ||
| sdai = swidget->private; | ||
| switch (sdev->pdata->ipc_type) { | ||
| case SOF_IPC: | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -111,7 +111,13 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev, | ||
| dmab = substream->runtime->dma_buffer_p; | ||
| hstream->format_val = rate | bits | (params_channels(params) - 1); | ||
| /* | ||
| * Use the codec required format val (which is link_bps adjusted) when | ||
| * the DSP is not in use | ||
plbossart marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| */ | ||
| if (!sdev->dspless_mode_selected) | ||
| hstream->format_val = rate | bits | (params_channels(params) - 1); | ||
| hstream->bufsize = size; | ||
| hstream->period_bytes = params_period_bytes(params); | ||
| hstream->no_period_wakeup = | ||
| @@ -249,6 +255,11 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, | ||
| snd_pcm_hw_constraint_integer(substream->runtime, | ||
| SNDRV_PCM_HW_PARAM_PERIODS); | ||
| /* Only S16 and S32 supported by HDA hardware when used without DSP */ | ||
| if (sdev->dspless_mode_selected) | ||
| snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_FORMAT, | ||
| SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S32); | ||
| /* binding pcm substream to hda stream */ | ||
| substream->runtime->private_data = &dsp_stream->hstream; | ||
| return 0; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -485,9 +485,8 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, | ||
| { | ||
| const struct sof_intel_dsp_desc *chip = get_chip_info(sdev->pdata); | ||
| struct hdac_bus *bus = sof_to_bus(sdev); | ||
| struct hdac_stream *hstream = &hext_stream->hstream; | ||
| int sd_offset = SOF_STREAM_SD_OFFSET(hstream); | ||
| int ret; | ||
| struct hdac_stream *hstream; | ||
| int sd_offset, ret; | ||
plbossart marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| u32 dma_start = SOF_HDA_SD_CTL_DMA_START; | ||
| u32 mask; | ||
| u32 run; | ||
| @@ -502,10 +501,14 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, | ||
| return -ENODEV; | ||
| } | ||
| /* decouple host and link DMA */ | ||
| mask = 0x1 << hstream->index; | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, | ||
| mask, mask); | ||
| hstream = &hext_stream->hstream; | ||
| sd_offset = SOF_STREAM_SD_OFFSET(hstream); | ||
| mask = BIT(hstream->index); | ||
| /* decouple host and link DMA if the DSP is used */ | ||
| if (!sdev->dspless_mode_selected) | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, | ||
| mask, mask); | ||
| /* clear stream status */ | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, | ||
| @@ -606,23 +609,21 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, | ||
| * enable decoupled mode | ||
| */ | ||
| if (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK) { | ||
| if (!sdev->dspless_mode_selected && (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK)) | ||
| /* couple host and link DMA, disable DSP features */ | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, | ||
| mask, 0); | ||
| } | ||
| /* program stream format */ | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, | ||
| sd_offset + | ||
| SOF_HDA_ADSP_REG_SD_FORMAT, | ||
| 0xffff, hstream->format_val); | ||
| if (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK) { | ||
| if (!sdev->dspless_mode_selected && (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK)) | ||
| /* decouple host and link DMA, enable DSP features */ | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, | ||
| mask, mask); | ||
| } | ||
| /* program last valid index */ | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, | ||
| @@ -675,20 +676,23 @@ int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev, | ||
| struct hdac_ext_stream *hext_stream = container_of(hstream, | ||
| struct hdac_ext_stream, | ||
| hstream); | ||
| struct hdac_bus *bus = sof_to_bus(sdev); | ||
| u32 mask = 0x1 << hstream->index; | ||
| int ret; | ||
| ret = hda_dsp_stream_reset(sdev, hstream); | ||
| if (ret < 0) | ||
| return ret; | ||
| spin_lock_irq(&bus->reg_lock); | ||
| /* couple host and link DMA if link DMA channel is idle */ | ||
| if (!hext_stream->link_locked) | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, | ||
| SOF_HDA_REG_PP_PPCTL, mask, 0); | ||
| spin_unlock_irq(&bus->reg_lock); | ||
| if (!sdev->dspless_mode_selected) { | ||
| struct hdac_bus *bus = sof_to_bus(sdev); | ||
| u32 mask = BIT(hstream->index); | ||
| spin_lock_irq(&bus->reg_lock); | ||
| /* couple host and link DMA if link DMA channel is idle */ | ||
| if (!hext_stream->link_locked) | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, | ||
| SOF_HDA_REG_PP_PPCTL, mask, 0); | ||
| spin_unlock_irq(&bus->reg_lock); | ||
| } | ||
| hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0); | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.