File Index
Files and directories
Sign in
FILE

avs.h

File preview with syntax highlighting.

linux-6.19.14/sound/soc/intel/avs/avs.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright(c) 2021-2022 Intel Corporation
  4 *
  5 * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
  6 *          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
  7 */
  8
  9#ifndef __SOUND_SOC_INTEL_AVS_H
 10#define __SOUND_SOC_INTEL_AVS_H
 11
 12#include <linux/debugfs.h>
 13#include <linux/device.h>
 14#include <linux/firmware.h>
 15#include <linux/kfifo.h>
 16#include <sound/hda_codec.h>
 17#include <sound/hda_register.h>
 18#include <sound/soc-component.h>
 19#include "messages.h"
 20#include "registers.h"
 21
 22struct avs_dev;
 23struct avs_tplg;
 24struct avs_tplg_library;
 25struct avs_ipc_msg;
 26
 27#ifdef CONFIG_ACPI
 28#define AVS_S0IX_SUPPORTED \
 29	(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)
 30#else
 31#define AVS_S0IX_SUPPORTED false
 32#endif
 33
 34/*
 35 * struct avs_dsp_ops - Platform-specific DSP operations
 36 *
 37 * @power: Power on or off DSP cores
 38 * @reset: Enter or exit reset state on DSP cores
 39 * @stall: Stall or run DSP cores
 40 * @irq_handler: Top half of IPC servicing
 41 * @irq_thread: Bottom half of IPC servicing
 42 * @int_control: Enable or disable IPC interrupts
 43 */
 44struct avs_dsp_ops {
 45	int (* const power)(struct avs_dev *, u32, bool);
 46	int (* const reset)(struct avs_dev *, u32, bool);
 47	int (* const stall)(struct avs_dev *, u32, bool);
 48	irqreturn_t (* const dsp_interrupt)(struct avs_dev *);
 49	void (* const int_control)(struct avs_dev *, bool);
 50	int (* const load_basefw)(struct avs_dev *, struct firmware *);
 51	int (* const load_lib)(struct avs_dev *, struct firmware *, u32);
 52	int (* const transfer_mods)(struct avs_dev *, bool, struct avs_module_entry *, u32);
 53	int (* const config_basefw)(struct avs_dev *);
 54	int (* const enable_logs)(struct avs_dev *, enum avs_log_enable, u32, u32, unsigned long,
 55				  u32 *);
 56	int (* const log_buffer_offset)(struct avs_dev *, u32);
 57	int (* const log_buffer_status)(struct avs_dev *, union avs_notify_msg *);
 58	int (* const coredump)(struct avs_dev *, union avs_notify_msg *);
 59	bool (* const d0ix_toggle)(struct avs_dev *, struct avs_ipc_msg *, bool);
 60	int (* const set_d0ix)(struct avs_dev *, bool);
 61};
 62
 63#define avs_dsp_op(adev, op, ...) \
 64	((adev)->spec->dsp_ops->op(adev, ## __VA_ARGS__))
 65
 66extern const struct avs_dsp_ops avs_skl_dsp_ops;
 67extern const struct avs_dsp_ops avs_apl_dsp_ops;
 68extern const struct avs_dsp_ops avs_cnl_dsp_ops;
 69extern const struct avs_dsp_ops avs_icl_dsp_ops;
 70extern const struct avs_dsp_ops avs_tgl_dsp_ops;
 71extern const struct avs_dsp_ops avs_ptl_dsp_ops;
 72
 73#define AVS_PLATATTR_CLDMA		BIT_ULL(0)
 74#define AVS_PLATATTR_IMR		BIT_ULL(1)
 75#define AVS_PLATATTR_ACE		BIT_ULL(2)
 76#define AVS_PLATATTR_ALTHDA		BIT_ULL(3)
 77
 78#define avs_platattr_test(adev, attr) \
 79	((adev)->spec->attributes & AVS_PLATATTR_##attr)
 80
 81struct avs_sram_spec {
 82	const u32 base_offset;
 83	const u32 window_size;
 84};
 85
 86struct avs_hipc_spec {
 87	const u32 req_offset;
 88	const u32 req_ext_offset;
 89	const u32 req_busy_mask;
 90	const u32 ack_offset;
 91	const u32 ack_done_mask;
 92	const u32 rsp_offset;
 93	const u32 rsp_busy_mask;
 94	const u32 ctl_offset;
 95	const u32 sts_offset;
 96};
 97
 98/* Platform specific descriptor */
 99struct avs_spec {
100	const char *name;
101
102	const struct avs_dsp_ops *const dsp_ops;
103	struct avs_fw_version min_fw_version; /* anything below is rejected */
104
105	const u32 core_init_mask;	/* used during DSP boot */
106	const u64 attributes;		/* bitmask of AVS_PLATATTR_* */
107	const struct avs_sram_spec *sram;
108	const struct avs_hipc_spec *hipc;
109};
110
111struct avs_fw_entry {
112	const char *name;
113	const struct firmware *fw;
114
115	struct list_head node;
116};
117
118/*
119 * struct avs_dev - Intel HD-Audio driver data
120 *
121 * @dev: PCI device
122 * @dsp_ba: DSP bar address
123 * @spec: platform-specific descriptor
124 * @fw_cfg: Firmware configuration, obtained through FW_CONFIG message
125 * @hw_cfg: Hardware configuration, obtained through HW_CONFIG message
126 * @mods_info: Available module-types, obtained through MODULES_INFO message
127 * @mod_idas: Module instance ID pool, one per module-type
128 * @modres_mutex: For synchronizing any @mods_info updates
129 * @ppl_ida: Pipeline instance ID pool
130 * @fw_list: List of libraries loaded, including base firmware
131 */
132struct avs_dev {
133	struct hda_bus base;
134	struct device *dev;
135
136	void __iomem *dsp_ba;
137	const struct avs_spec *spec;
138	struct avs_ipc *ipc;
139
140	struct avs_fw_cfg fw_cfg;
141	struct avs_hw_cfg hw_cfg;
142	struct avs_mods_info *mods_info;
143	struct ida **mod_idas;
144	struct mutex modres_mutex;
145	void *modcfg_buf;		/* module configuration buffer */
146	struct ida ppl_ida;
147	struct list_head fw_list;
148	int *core_refs;		/* reference count per core */
149	char **lib_names;
150	int num_lp_paths;
151	atomic_t l1sen_counter;	/* controls whether L1SEN should be disabled */
152
153	struct completion fw_ready;
154	struct work_struct probe_work;
155
156	struct list_head comp_list;
157	struct mutex comp_list_mutex;
158	struct list_head path_list;
159	spinlock_t path_list_lock;
160	struct mutex path_mutex;
161
162	spinlock_t trace_lock;	/* serialize debug window I/O between each LOG_BUFFER_STATUS */
163#ifdef CONFIG_DEBUG_FS
164	struct kfifo trace_fifo;
165	wait_queue_head_t trace_waitq;
166	u32 aging_timer_period;
167	u32 fifo_full_timer_period;
168	u32 logged_resources;	/* context dependent: core or library */
169	struct dentry *debugfs_root;
170	/* probes */
171	struct hdac_ext_stream *extractor;
172	unsigned int num_probe_streams;
173#endif
174};
175
176/* from hda_bus to avs_dev */
177#define hda_to_avs(hda) container_of(hda, struct avs_dev, base)
178/* from hdac_bus to avs_dev */
179#define hdac_to_avs(hdac) hda_to_avs(to_hda_bus(hdac))
180/* from device to avs_dev */
181#define to_avs_dev(dev) \
182({ \
183	struct hdac_bus *__bus = dev_get_drvdata(dev); \
184	hdac_to_avs(__bus); \
185})
186
187int avs_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power);
188int avs_dsp_core_reset(struct avs_dev *adev, u32 core_mask, bool reset);
189int avs_dsp_core_stall(struct avs_dev *adev, u32 core_mask, bool stall);
190int avs_dsp_core_enable(struct avs_dev *adev, u32 core_mask);
191int avs_dsp_core_disable(struct avs_dev *adev, u32 core_mask);
192
193/* Inter Process Communication */
194
195struct avs_ipc_msg {
196	union {
197		u64 header;
198		union avs_global_msg glb;
199		union avs_reply_msg rsp;
200	};
201	void *data;
202	size_t size;
203};
204
205/*
206 * struct avs_ipc - DSP IPC context
207 *
208 * @dev: PCI device
209 * @rx: Reply message cache
210 * @default_timeout_ms: default message timeout in MS
211 * @ready: whether firmware is ready and communication is open
212 * @rx_completed: whether RX for previously sent TX has been received
213 * @rx_lock: for serializing manipulation of rx_* fields
214 * @msg_lock: for synchronizing request handling
215 * @done_completion: DONE-part of IPC i.e. ROM and ACKs from FW
216 * @busy_completion: BUSY-part of IPC i.e. receiving responses from FW
217 */
218struct avs_ipc {
219	struct device *dev;
220
221	struct avs_ipc_msg rx;
222	u32 default_timeout_ms;
223	bool ready;
224	atomic_t recovering;
225
226	bool rx_completed;
227	spinlock_t rx_lock;
228	struct mutex msg_mutex;
229	struct completion done_completion;
230	struct completion busy_completion;
231
232	struct work_struct recovery_work;
233	struct delayed_work d0ix_work;
234	atomic_t d0ix_disable_depth;
235	bool in_d0ix;
236};
237
238#define AVS_EIPC	EREMOTEIO
239/*
240 * IPC handlers may return positive value (firmware error code) what denotes
241 * successful HOST <-> DSP communication yet failure to process specific request.
242 *
243 * Below macro converts returned value to linux kernel error code.
244 * All IPC callers MUST use it as soon as firmware error code is consumed.
245 */
246#define AVS_IPC_RET(ret) \
247	(((ret) <= 0) ? (ret) : -AVS_EIPC)
248
249void avs_dsp_process_response(struct avs_dev *adev, u64 header);
250int avs_dsp_send_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request,
251			     struct avs_ipc_msg *reply, int timeout, const char *name);
252int avs_dsp_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request,
253		     struct avs_ipc_msg *reply, const char *name);
254/* Two variants below are for messages that control DSP power states. */
255int avs_dsp_send_pm_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request,
256				struct avs_ipc_msg *reply, int timeout, bool wake_d0i0,
257				const char *name);
258int avs_dsp_send_pm_msg(struct avs_dev *adev, struct avs_ipc_msg *request,
259			struct avs_ipc_msg *reply, bool wake_d0i0, const char *name);
260int avs_dsp_send_rom_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, int timeout,
261				 const char *name);
262int avs_dsp_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request, const char *name);
263void avs_dsp_interrupt_control(struct avs_dev *adev, bool enable);
264int avs_ipc_init(struct avs_ipc *ipc, struct device *dev);
265void avs_ipc_block(struct avs_ipc *ipc);
266
267int avs_dsp_disable_d0ix(struct avs_dev *adev);
268int avs_dsp_enable_d0ix(struct avs_dev *adev);
269
270int avs_mtl_core_power(struct avs_dev *adev, u32 core_mask, bool power);
271int avs_mtl_core_reset(struct avs_dev *adev, u32 core_mask, bool power);
272int avs_mtl_core_stall(struct avs_dev *adev, u32 core_mask, bool stall);
273int avs_lnl_core_stall(struct avs_dev *adev, u32 core_mask, bool stall);
274void avs_mtl_interrupt_control(struct avs_dev *adev, bool enable);
275void avs_skl_ipc_interrupt(struct avs_dev *adev);
276irqreturn_t avs_cnl_dsp_interrupt(struct avs_dev *adev);
277irqreturn_t avs_mtl_dsp_interrupt(struct avs_dev *adev);
278int avs_apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
279			u32 fifo_full_period, unsigned long resource_mask, u32 *priorities);
280int avs_icl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
281			u32 fifo_full_period, unsigned long resource_mask, u32 *priorities);
282int avs_skl_log_buffer_offset(struct avs_dev *adev, u32 core);
283int avs_icl_log_buffer_offset(struct avs_dev *adev, u32 core);
284int avs_apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg);
285int avs_apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg);
286bool avs_apl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake);
287bool avs_icl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake);
288int avs_apl_set_d0ix(struct avs_dev *adev, bool enable);
289int avs_icl_set_d0ix(struct avs_dev *adev, bool enable);
290
291/* Firmware resources management */
292
293int avs_get_module_entry(struct avs_dev *adev, const guid_t *uuid, struct avs_module_entry *entry);
294int avs_get_module_id_entry(struct avs_dev *adev, u32 module_id, struct avs_module_entry *entry);
295int avs_get_module_id(struct avs_dev *adev, const guid_t *uuid);
296bool avs_is_module_ida_empty(struct avs_dev *adev, u32 module_id);
297
298int avs_module_info_init(struct avs_dev *adev, bool purge);
299void avs_module_info_free(struct avs_dev *adev);
300int avs_module_id_alloc(struct avs_dev *adev, u16 module_id);
301void avs_module_id_free(struct avs_dev *adev, u16 module_id, u8 instance_id);
302int avs_request_firmware(struct avs_dev *adev, const struct firmware **fw_p, const char *name);
303void avs_release_last_firmware(struct avs_dev *adev);
304void avs_release_firmwares(struct avs_dev *adev);
305
306int avs_dsp_init_module(struct avs_dev *adev, u16 module_id, u8 ppl_instance_id,
307			u8 core_id, u8 domain, void *param, u32 param_size,
308			u8 *instance_id);
309void avs_dsp_delete_module(struct avs_dev *adev, u16 module_id, u8 instance_id,
310			   u8 ppl_instance_id, u8 core_id);
311int avs_dsp_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority,
312			    bool lp, u16 attributes, u8 *instance_id);
313int avs_dsp_delete_pipeline(struct avs_dev *adev, u8 instance_id);
314
315/* Firmware loading */
316
317void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable);
318void avs_hda_power_gating_enable(struct avs_dev *adev, bool enable);
319void avs_hda_l1sen_enable(struct avs_dev *adev, bool enable);
320
321int avs_dsp_load_libraries(struct avs_dev *adev, struct avs_tplg_library *libs, u32 num_libs);
322int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge);
323int avs_dsp_first_boot_firmware(struct avs_dev *adev);
324
325int avs_cldma_load_basefw(struct avs_dev *adev, struct firmware *fw);
326int avs_cldma_load_library(struct avs_dev *adev, struct firmware *lib, u32 id);
327int avs_cldma_transfer_modules(struct avs_dev *adev, bool load,
328			       struct avs_module_entry *mods, u32 num_mods);
329int avs_hda_load_basefw(struct avs_dev *adev, struct firmware *fw);
330int avs_hda_load_library(struct avs_dev *adev, struct firmware *lib, u32 id);
331int avs_hda_transfer_modules(struct avs_dev *adev, bool load,
332			     struct avs_module_entry *mods, u32 num_mods);
333
334int avs_icl_load_basefw(struct avs_dev *adev, struct firmware *fw);
335
336/* Soc component members */
337
338struct avs_soc_component {
339	struct snd_soc_component base;
340	struct avs_tplg *tplg;
341
342	struct list_head node;
343};
344
345#define to_avs_soc_component(comp) \
346	container_of(comp, struct avs_soc_component, base)
347
348extern const struct snd_soc_dai_ops avs_dai_fe_ops;
349
350int avs_register_dmic_component(struct avs_dev *adev, const char *name);
351int avs_register_i2s_component(struct avs_dev *adev, const char *name, unsigned long port_mask,
352			       unsigned long *tdms);
353int avs_register_hda_component(struct avs_dev *adev, const char *name);
354int avs_register_component(struct device *dev, const char *name,
355			   struct snd_soc_component_driver *drv,
356			   struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais);
357
358int avs_register_all_boards(struct avs_dev *adev);
359void avs_unregister_all_boards(struct avs_dev *adev);
360
361int avs_parse_sched_cfg(struct avs_dev *adev, const char *buf, size_t len);
362
363/* Filesystems integration */
364
365extern const struct attribute_group *avs_attr_groups[];
366
367#endif /* __SOUND_SOC_INTEL_AVS_H */
~/ Read-only file preview.