Skip to content

Commit ab2ec32

Browse files
committed
ASoC: SOF: Intel: hda: add sof_icl_ops for ICL platforms
Separate the dsp ops for ICL ops to specify the use of ICCMAX FW boot sequence in the run op. All other ops are identical with TGL except post_fw_run. The recommended HW programming sequence for ICL is to power up core 3 and keep it in stall if HPRO is enabled. Signed-off-by: Fred Oh <fred.oh@linux.intel.com>
1 parent f798a46 commit ab2ec32

File tree

6 files changed

+212
-18
lines changed

6 files changed

+212
-18
lines changed

sound/soc/sof/intel/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ snd-sof-intel-ipc-objs := intel-ipc.o
88
snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \
99
hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \
1010
hda-dai.o hda-bus.o \
11-
apl.o cnl.o tgl.o
11+
apl.o cnl.o tgl.o icl.o
1212
snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-compress.o
1313

1414
snd-sof-intel-hda-objs := hda-codec.o

sound/soc/sof/intel/cnl.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -349,22 +349,6 @@ const struct sof_intel_dsp_desc cnl_chip_info = {
349349
};
350350
EXPORT_SYMBOL_NS(cnl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
351351

352-
const struct sof_intel_dsp_desc icl_chip_info = {
353-
/* Icelake */
354-
.cores_num = 4,
355-
.init_core_mask = 1,
356-
.host_managed_cores_mask = GENMASK(3, 0),
357-
.ipc_req = CNL_DSP_REG_HIPCIDR,
358-
.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
359-
.ipc_ack = CNL_DSP_REG_HIPCIDA,
360-
.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
361-
.ipc_ctl = CNL_DSP_REG_HIPCCTL,
362-
.rom_init_timeout = 300,
363-
.ssp_count = ICL_SSP_COUNT,
364-
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
365-
};
366-
EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
367-
368352
const struct sof_intel_dsp_desc ehl_chip_info = {
369353
/* Elkhartlake */
370354
.cores_num = 4,

sound/soc/sof/intel/hda-loader.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,46 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev)
472472
return hda_dsp_ctrl_clock_power_gating(sdev, true);
473473
}
474474

475+
/*
476+
* post fw run operations for ICL,
477+
* Core 3 will be powered up and in stall when HPRO is enabled
478+
*/
479+
int hda_dsp_post_fw_run_icl(struct snd_sof_dev *sdev)
480+
{
481+
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
482+
int ret;
483+
484+
if (sdev->first_boot) {
485+
ret = hda_sdw_startup(sdev);
486+
if (ret < 0) {
487+
dev_err(sdev->dev,
488+
"error: could not startup SoundWire links\n");
489+
return ret;
490+
}
491+
}
492+
493+
hda_sdw_int_enable(sdev, true);
494+
495+
/*
496+
* The recommended HW programming sequence for ICL is to
497+
* power up core 3 and keep it in stall if HPRO is enabled.
498+
* Major difference between ICL and TGL, on ICL core 3 is managed by
499+
* the host whereas on TGL it is handled by the firmware.
500+
*/
501+
if (!hda->clk_config_lpro) {
502+
ret = snd_sof_dsp_core_power_up(sdev, BIT(3));
503+
if (ret < 0) {
504+
dev_err(sdev->dev, "error: dsp core power up failed on core 3\n");
505+
return ret;
506+
}
507+
508+
snd_sof_dsp_stall(sdev, BIT(3));
509+
}
510+
511+
/* re-enable clock gating and power gating */
512+
return hda_dsp_ctrl_clock_power_gating(sdev, true);
513+
}
514+
475515
int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev,
476516
const struct sof_ext_man_elem_header *hdr)
477517
{
@@ -507,3 +547,24 @@ int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev,
507547

508548
return 0;
509549
}
550+
551+
int hda_dsp_core_stall_icl(struct snd_sof_dev *sdev, unsigned int core_mask)
552+
{
553+
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
554+
const struct sof_intel_dsp_desc *chip = hda->desc;
555+
556+
/* make sure core_mask in host managed cores */
557+
core_mask &= chip->host_managed_cores_mask;
558+
if (!core_mask) {
559+
dev_err(sdev->dev, "error: core_mask is not in host managed cores\n");
560+
return -EINVAL;
561+
}
562+
563+
/* stall core */
564+
snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
565+
HDA_DSP_REG_ADSPCS,
566+
HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
567+
HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
568+
569+
return 0;
570+
}

sound/soc/sof/intel/hda.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,11 +615,14 @@ int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir);
615615
*/
616616
int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev);
617617
int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev);
618+
int hda_dsp_cl_boot_firmware_iccmax_icl(struct snd_sof_dev *sdev);
618619
int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev);
619620

620621
/* pre and post fw run ops */
621622
int hda_dsp_pre_fw_run(struct snd_sof_dev *sdev);
622623
int hda_dsp_post_fw_run(struct snd_sof_dev *sdev);
624+
int hda_dsp_post_fw_run_icl(struct snd_sof_dev *sdev);
625+
int hda_dsp_core_stall_icl(struct snd_sof_dev *sdev, unsigned int core_mask);
623626

624627
/* parse platform specific ext manifest ops */
625628
int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev,
@@ -740,6 +743,7 @@ extern struct snd_soc_dai_driver skl_dai[];
740743
extern const struct snd_sof_dsp_ops sof_apl_ops;
741744
extern const struct snd_sof_dsp_ops sof_cnl_ops;
742745
extern const struct snd_sof_dsp_ops sof_tgl_ops;
746+
extern const struct snd_sof_dsp_ops sof_icl_ops;
743747

744748
extern const struct sof_intel_dsp_desc apl_chip_info;
745749
extern const struct sof_intel_dsp_desc cnl_chip_info;

sound/soc/sof/intel/icl.c

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2+
//
3+
// Copyright(c) 2020 Intel Corporation. All rights reserved.
4+
//
5+
// Author: Fred Oh <fred.oh@linux.intel.com>
6+
//
7+
8+
/*
9+
* Hardware interface for audio DSP on IceLake.
10+
*/
11+
12+
#include <linux/kernel.h>
13+
#include <linux/kconfig.h>
14+
#include <linux/export.h>
15+
#include <linux/bits.h>
16+
#include "../ops.h"
17+
#include "hda.h"
18+
#include "hda-ipc.h"
19+
#include "../sof-audio.h"
20+
21+
static const struct snd_sof_debugfs_map icl_dsp_debugfs[] = {
22+
{"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
23+
{"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS},
24+
{"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
25+
};
26+
27+
/* Icelake ops */
28+
const struct snd_sof_dsp_ops sof_icl_ops = {
29+
/* probe and remove */
30+
.probe = hda_dsp_probe,
31+
.remove = hda_dsp_remove,
32+
33+
/* Register IO */
34+
.write = sof_io_write,
35+
.read = sof_io_read,
36+
.write64 = sof_io_write64,
37+
.read64 = sof_io_read64,
38+
39+
/* Block IO */
40+
.block_read = sof_block_read,
41+
.block_write = sof_block_write,
42+
43+
/* doorbell */
44+
.irq_thread = cnl_ipc_irq_thread,
45+
46+
/* ipc */
47+
.send_msg = cnl_ipc_send_msg,
48+
.fw_ready = sof_fw_ready,
49+
.get_mailbox_offset = hda_dsp_ipc_get_mailbox_offset,
50+
.get_window_offset = hda_dsp_ipc_get_window_offset,
51+
52+
.ipc_msg_data = hda_ipc_msg_data,
53+
.ipc_pcm_params = hda_ipc_pcm_params,
54+
55+
/* machine driver */
56+
.machine_select = hda_machine_select,
57+
.machine_register = sof_machine_register,
58+
.machine_unregister = sof_machine_unregister,
59+
.set_mach_params = hda_set_mach_params,
60+
61+
/* debug */
62+
.debug_map = icl_dsp_debugfs,
63+
.debug_map_count = ARRAY_SIZE(icl_dsp_debugfs),
64+
.dbg_dump = hda_dsp_dump,
65+
.ipc_dump = cnl_ipc_dump,
66+
67+
/* stream callbacks */
68+
.pcm_open = hda_dsp_pcm_open,
69+
.pcm_close = hda_dsp_pcm_close,
70+
.pcm_hw_params = hda_dsp_pcm_hw_params,
71+
.pcm_hw_free = hda_dsp_stream_hw_free,
72+
.pcm_trigger = hda_dsp_pcm_trigger,
73+
.pcm_pointer = hda_dsp_pcm_pointer,
74+
75+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
76+
/* probe callbacks */
77+
.probe_assign = hda_probe_compr_assign,
78+
.probe_free = hda_probe_compr_free,
79+
.probe_set_params = hda_probe_compr_set_params,
80+
.probe_trigger = hda_probe_compr_trigger,
81+
.probe_pointer = hda_probe_compr_pointer,
82+
#endif
83+
84+
/* firmware loading */
85+
.load_firmware = snd_sof_load_firmware_raw,
86+
87+
/* pre/post fw run */
88+
.pre_fw_run = hda_dsp_pre_fw_run,
89+
.post_fw_run = hda_dsp_post_fw_run_icl,
90+
91+
/* parse platform specific extended manifest */
92+
.parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data,
93+
94+
/* dsp core power up/down */
95+
.core_power_up = hda_dsp_enable_core,
96+
.core_power_down = hda_dsp_core_reset_power_down,
97+
98+
/* firmware run */
99+
.run = hda_dsp_cl_boot_firmware_iccmax,
100+
.stall = hda_dsp_core_stall_icl,
101+
102+
/* trace callback */
103+
.trace_init = hda_dsp_trace_init,
104+
.trace_release = hda_dsp_trace_release,
105+
.trace_trigger = hda_dsp_trace_trigger,
106+
107+
/* DAI drivers */
108+
.drv = skl_dai,
109+
.num_drv = SOF_SKL_NUM_DAIS,
110+
111+
/* PM */
112+
.suspend = hda_dsp_suspend,
113+
.resume = hda_dsp_resume,
114+
.runtime_suspend = hda_dsp_runtime_suspend,
115+
.runtime_resume = hda_dsp_runtime_resume,
116+
.runtime_idle = hda_dsp_runtime_idle,
117+
.set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume,
118+
.set_power_state = hda_dsp_set_power_state,
119+
120+
/* ALSA HW info flags */
121+
.hw_info = SNDRV_PCM_INFO_MMAP |
122+
SNDRV_PCM_INFO_MMAP_VALID |
123+
SNDRV_PCM_INFO_INTERLEAVED |
124+
SNDRV_PCM_INFO_PAUSE |
125+
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
126+
127+
.arch_ops = &sof_xtensa_arch_ops,
128+
};
129+
EXPORT_SYMBOL_NS(sof_icl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
130+
131+
const struct sof_intel_dsp_desc icl_chip_info = {
132+
/* Icelake */
133+
.cores_num = 4,
134+
.init_core_mask = 1,
135+
.host_managed_cores_mask = GENMASK(3, 0),
136+
.ipc_req = CNL_DSP_REG_HIPCIDR,
137+
.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
138+
.ipc_ack = CNL_DSP_REG_HIPCIDA,
139+
.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
140+
.ipc_ctl = CNL_DSP_REG_HIPCCTL,
141+
.rom_init_timeout = 300,
142+
.ssp_count = ICL_SSP_COUNT,
143+
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
144+
};
145+
EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);

sound/soc/sof/sof-pci-dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ static const struct sof_dev_desc icl_desc = {
209209
.default_tplg_path = "intel/sof-tplg",
210210
.default_fw_filename = "sof-icl.ri",
211211
.nocodec_tplg_filename = "sof-icl-nocodec.tplg",
212-
.ops = &sof_cnl_ops,
212+
.ops = &sof_icl_ops,
213213
};
214214
#endif
215215

0 commit comments

Comments
 (0)