1  // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2  //
3  // Copyright(c) 2020 Intel Corporation
4  //
5  // Authors: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
6  //
7  
8  /*
9   * Hardware interface for audio DSP on Tigerlake.
10   */
11  
12  #include <sound/sof/ext_manifest4.h>
13  #include "../ipc4-priv.h"
14  #include "../ops.h"
15  #include "hda.h"
16  #include "hda-ipc.h"
17  #include "../sof-audio.h"
18  
19  static const struct snd_sof_debugfs_map tgl_dsp_debugfs[] = {
20  	{"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
21  	{"pp", HDA_DSP_PP_BAR,  0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS},
22  	{"dsp", HDA_DSP_BAR,  0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
23  };
24  
25  static const struct snd_sof_debugfs_map tgl_ipc4_dsp_debugfs[] = {
26  	{"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
27  	{"pp", HDA_DSP_PP_BAR,  0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS},
28  	{"dsp", HDA_DSP_BAR,  0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
29  	{"fw_regs", HDA_DSP_BAR,  SRAM_WINDOW_OFFSET(0), 0x1000, SOF_DEBUGFS_ACCESS_D0_ONLY},
30  };
31  
tgl_dsp_core_get(struct snd_sof_dev * sdev,int core)32  static int tgl_dsp_core_get(struct snd_sof_dev *sdev, int core)
33  {
34  	const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm;
35  
36  	/* power up primary core if not already powered up and return */
37  	if (core == SOF_DSP_PRIMARY_CORE)
38  		return hda_dsp_enable_core(sdev, BIT(core));
39  
40  	if (pm_ops->set_core_state)
41  		return pm_ops->set_core_state(sdev, core, true);
42  
43  	return 0;
44  }
45  
tgl_dsp_core_put(struct snd_sof_dev * sdev,int core)46  static int tgl_dsp_core_put(struct snd_sof_dev *sdev, int core)
47  {
48  	const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm;
49  	int ret;
50  
51  	if (pm_ops->set_core_state) {
52  		ret = pm_ops->set_core_state(sdev, core, false);
53  		if (ret < 0)
54  			return ret;
55  	}
56  
57  	/* power down primary core and return */
58  	if (core == SOF_DSP_PRIMARY_CORE)
59  		return hda_dsp_core_reset_power_down(sdev, BIT(core));
60  
61  	return 0;
62  }
63  
64  /* Tigerlake ops */
65  struct snd_sof_dsp_ops sof_tgl_ops;
66  
sof_tgl_ops_init(struct snd_sof_dev * sdev)67  int sof_tgl_ops_init(struct snd_sof_dev *sdev)
68  {
69  	/* common defaults */
70  	memcpy(&sof_tgl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
71  
72  	/* probe/remove/shutdown */
73  	sof_tgl_ops.shutdown	= hda_dsp_shutdown_dma_flush;
74  
75  	if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
76  		/* doorbell */
77  		sof_tgl_ops.irq_thread	= cnl_ipc_irq_thread;
78  
79  		/* ipc */
80  		sof_tgl_ops.send_msg	= cnl_ipc_send_msg;
81  
82  		/* debug */
83  		sof_tgl_ops.ipc_dump	= cnl_ipc_dump;
84  		sof_tgl_ops.debug_map	= tgl_dsp_debugfs;
85  		sof_tgl_ops.debug_map_count = ARRAY_SIZE(tgl_dsp_debugfs);
86  
87  		sof_tgl_ops.set_power_state = hda_dsp_set_power_state_ipc3;
88  	}
89  
90  	if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
91  		struct sof_ipc4_fw_data *ipc4_data;
92  
93  		sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL);
94  		if (!sdev->private)
95  			return -ENOMEM;
96  
97  		ipc4_data = sdev->private;
98  		ipc4_data->manifest_fw_hdr_offset = SOF_MAN4_FW_HDR_OFFSET;
99  
100  		ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_2;
101  
102  		ipc4_data->fw_context_save = true;
103  
104  		/* External library loading support */
105  		ipc4_data->load_library = hda_dsp_ipc4_load_library;
106  
107  		/* doorbell */
108  		sof_tgl_ops.irq_thread	= cnl_ipc4_irq_thread;
109  
110  		/* ipc */
111  		sof_tgl_ops.send_msg	= cnl_ipc4_send_msg;
112  
113  		/* debug */
114  		sof_tgl_ops.ipc_dump	= cnl_ipc4_dump;
115  		sof_tgl_ops.dbg_dump	= hda_ipc4_dsp_dump;
116  		sof_tgl_ops.debug_map	= tgl_ipc4_dsp_debugfs;
117  		sof_tgl_ops.debug_map_count = ARRAY_SIZE(tgl_ipc4_dsp_debugfs);
118  
119  		sof_tgl_ops.set_power_state = hda_dsp_set_power_state_ipc4;
120  	}
121  
122  	/* set DAI driver ops */
123  	hda_set_dai_drv_ops(sdev, &sof_tgl_ops);
124  
125  	/* pre/post fw run */
126  	sof_tgl_ops.post_fw_run = hda_dsp_post_fw_run;
127  
128  	/* firmware run */
129  	sof_tgl_ops.run = hda_dsp_cl_boot_firmware_iccmax;
130  
131  	/* dsp core get/put */
132  	sof_tgl_ops.core_get = tgl_dsp_core_get;
133  	sof_tgl_ops.core_put = tgl_dsp_core_put;
134  
135  	return 0;
136  };
137  
138  const struct sof_intel_dsp_desc tgl_chip_info = {
139  	/* Tigerlake , Alderlake */
140  	.cores_num = 4,
141  	.init_core_mask = 1,
142  	.host_managed_cores_mask = BIT(0),
143  	.ipc_req = CNL_DSP_REG_HIPCIDR,
144  	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
145  	.ipc_ack = CNL_DSP_REG_HIPCIDA,
146  	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
147  	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
148  	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
149  	.rom_init_timeout	= 300,
150  	.ssp_count = TGL_SSP_COUNT,
151  	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
152  	.sdw_shim_base = SDW_SHIM_BASE,
153  	.sdw_alh_base = SDW_ALH_BASE,
154  	.d0i3_offset = SOF_HDA_VS_D0I3C,
155  	.read_sdw_lcount =  hda_sdw_check_lcount_common,
156  	.enable_sdw_irq	= hda_common_enable_sdw_irq,
157  	.check_sdw_irq	= hda_common_check_sdw_irq,
158  	.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
159  	.sdw_process_wakeen = hda_sdw_process_wakeen_common,
160  	.check_ipc_irq	= hda_dsp_check_ipc_irq,
161  	.cl_init = cl_dsp_init,
162  	.power_down_dsp = hda_power_down_dsp,
163  	.disable_interrupts = hda_dsp_disable_interrupts,
164  	.hw_ip_version = SOF_INTEL_CAVS_2_5,
165  };
166  
167  const struct sof_intel_dsp_desc tglh_chip_info = {
168  	/* Tigerlake-H */
169  	.cores_num = 2,
170  	.init_core_mask = 1,
171  	.host_managed_cores_mask = BIT(0),
172  	.ipc_req = CNL_DSP_REG_HIPCIDR,
173  	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
174  	.ipc_ack = CNL_DSP_REG_HIPCIDA,
175  	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
176  	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
177  	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
178  	.rom_init_timeout	= 300,
179  	.ssp_count = TGL_SSP_COUNT,
180  	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
181  	.sdw_shim_base = SDW_SHIM_BASE,
182  	.sdw_alh_base = SDW_ALH_BASE,
183  	.d0i3_offset = SOF_HDA_VS_D0I3C,
184  	.read_sdw_lcount =  hda_sdw_check_lcount_common,
185  	.enable_sdw_irq	= hda_common_enable_sdw_irq,
186  	.check_sdw_irq	= hda_common_check_sdw_irq,
187  	.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
188  	.sdw_process_wakeen = hda_sdw_process_wakeen_common,
189  	.check_ipc_irq	= hda_dsp_check_ipc_irq,
190  	.cl_init = cl_dsp_init,
191  	.power_down_dsp = hda_power_down_dsp,
192  	.disable_interrupts = hda_dsp_disable_interrupts,
193  	.hw_ip_version = SOF_INTEL_CAVS_2_5,
194  };
195  
196  const struct sof_intel_dsp_desc ehl_chip_info = {
197  	/* Elkhartlake */
198  	.cores_num = 4,
199  	.init_core_mask = 1,
200  	.host_managed_cores_mask = BIT(0),
201  	.ipc_req = CNL_DSP_REG_HIPCIDR,
202  	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
203  	.ipc_ack = CNL_DSP_REG_HIPCIDA,
204  	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
205  	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
206  	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
207  	.rom_init_timeout	= 300,
208  	.ssp_count = TGL_SSP_COUNT,
209  	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
210  	.sdw_shim_base = SDW_SHIM_BASE,
211  	.sdw_alh_base = SDW_ALH_BASE,
212  	.d0i3_offset = SOF_HDA_VS_D0I3C,
213  	.read_sdw_lcount =  hda_sdw_check_lcount_common,
214  	.enable_sdw_irq	= hda_common_enable_sdw_irq,
215  	.check_sdw_irq	= hda_common_check_sdw_irq,
216  	.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
217  	.sdw_process_wakeen = hda_sdw_process_wakeen_common,
218  	.check_ipc_irq	= hda_dsp_check_ipc_irq,
219  	.cl_init = cl_dsp_init,
220  	.power_down_dsp = hda_power_down_dsp,
221  	.disable_interrupts = hda_dsp_disable_interrupts,
222  	.hw_ip_version = SOF_INTEL_CAVS_2_5,
223  };
224  
225  const struct sof_intel_dsp_desc adls_chip_info = {
226  	/* Alderlake-S */
227  	.cores_num = 2,
228  	.init_core_mask = BIT(0),
229  	.host_managed_cores_mask = BIT(0),
230  	.ipc_req = CNL_DSP_REG_HIPCIDR,
231  	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
232  	.ipc_ack = CNL_DSP_REG_HIPCIDA,
233  	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
234  	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
235  	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
236  	.rom_init_timeout	= 300,
237  	.ssp_count = TGL_SSP_COUNT,
238  	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
239  	.sdw_shim_base = SDW_SHIM_BASE,
240  	.sdw_alh_base = SDW_ALH_BASE,
241  	.d0i3_offset = SOF_HDA_VS_D0I3C,
242  	.read_sdw_lcount =  hda_sdw_check_lcount_common,
243  	.enable_sdw_irq	= hda_common_enable_sdw_irq,
244  	.check_sdw_irq	= hda_common_check_sdw_irq,
245  	.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
246  	.sdw_process_wakeen = hda_sdw_process_wakeen_common,
247  	.check_ipc_irq	= hda_dsp_check_ipc_irq,
248  	.cl_init = cl_dsp_init,
249  	.power_down_dsp = hda_power_down_dsp,
250  	.disable_interrupts = hda_dsp_disable_interrupts,
251  	.hw_ip_version = SOF_INTEL_CAVS_2_5,
252  };
253