File Index
Files and directories
Sign in
FILE

imx-common.h

File preview with syntax highlighting.

linux-6.19.14/sound/soc/sof/imx/imx-common.h C
  1/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
  2
  3#ifndef __IMX_COMMON_H__
  4#define __IMX_COMMON_H__
  5
  6#include <linux/clk.h>
  7#include <linux/of_platform.h>
  8#include <sound/sof/xtensa.h>
  9
 10#include "../sof-of-dev.h"
 11#include "../ops.h"
 12
 13#define EXCEPT_MAX_HDR_SIZE	0x400
 14#define IMX8_STACK_DUMP_SIZE 32
 15
 16/* chip_info refers to the data stored in struct sof_dev_desc's chip_info */
 17#define get_chip_info(sdev)\
 18	((const struct imx_chip_info *)((sdev)->pdata->desc->chip_info))
 19
 20/* chip_pdata refers to the data stored in struct imx_common_data's chip_pdata */
 21#define get_chip_pdata(sdev)\
 22	(((struct imx_common_data *)((sdev)->pdata->hw_pdata))->chip_pdata)
 23
 24/* can be used if:
 25 *	1) The only supported IPC version is IPC3.
 26 *	2) The default paths/FW name match values below.
 27 *
 28 * otherwise, just explicitly declare the structure
 29 */
 30#define IMX_SOF_DEV_DESC(mach_name, of_machs,				\
 31			 mach_chip_info, mach_ops, mach_ops_init)	\
 32static struct sof_dev_desc sof_of_##mach_name##_desc = {		\
 33	.of_machines = of_machs,					\
 34	.chip_info = mach_chip_info,					\
 35	.ipc_supported_mask = BIT(SOF_IPC_TYPE_3),			\
 36	.ipc_default = SOF_IPC_TYPE_3,					\
 37	.default_fw_path = {						\
 38		[SOF_IPC_TYPE_3] = "imx/sof",				\
 39	},								\
 40	.default_tplg_path = {						\
 41		[SOF_IPC_TYPE_3] = "imx/sof-tplg",			\
 42	},								\
 43	.default_fw_filename = {					\
 44		[SOF_IPC_TYPE_3] = "sof-" #mach_name ".ri",		\
 45	},								\
 46	.ops = mach_ops,						\
 47	.ops_init = mach_ops_init,					\
 48}
 49
 50/* to be used alongside IMX_SOF_DEV_DESC() */
 51#define IMX_SOF_DEV_DESC_NAME(mach_name) sof_of_##mach_name##_desc
 52
 53/* dai driver entry w/ playback and capture caps. If one direction is missing
 54 * then set the channels to 0.
 55 */
 56#define IMX_SOF_DAI_DRV_ENTRY(dai_name, pb_cmin, pb_cmax, cap_cmin, cap_cmax)	\
 57{										\
 58	.name = dai_name,							\
 59	.playback = {								\
 60		.channels_min = pb_cmin,					\
 61		.channels_max = pb_cmax,					\
 62	},									\
 63	.capture = {								\
 64		.channels_min = cap_cmin,					\
 65		.channels_max = cap_cmax,					\
 66	},									\
 67}
 68
 69/* use if playback and capture have the same min/max channel count */
 70#define IMX_SOF_DAI_DRV_ENTRY_BIDIR(dai_name, cmin, cmax)\
 71	IMX_SOF_DAI_DRV_ENTRY(dai_name, cmin, cmax, cmin, cmax)
 72
 73struct imx_ipc_info {
 74	/* true if core is able to write a panic code to the debug box */
 75	bool has_panic_code;
 76	/* offset to mailbox in which firmware initially writes FW_READY */
 77	int boot_mbox_offset;
 78	/* offset to region at which the mailboxes start */
 79	int window_offset;
 80};
 81
 82struct imx_chip_ops {
 83	/* called after clocks and PDs are enabled */
 84	int (*probe)(struct snd_sof_dev *sdev);
 85	/* used directly by the SOF core */
 86	int (*core_kick)(struct snd_sof_dev *sdev);
 87	/* called during suspend()/remove() before clocks are disabled */
 88	int (*core_shutdown)(struct snd_sof_dev *sdev);
 89	/* used directly by the SOF core */
 90	int (*core_reset)(struct snd_sof_dev *sdev);
 91};
 92
 93struct imx_memory_info {
 94	const char *name;
 95	bool reserved;
 96};
 97
 98struct imx_chip_info {
 99	struct imx_ipc_info ipc_info;
100	/* does the chip have a reserved memory region for DMA? */
101	bool has_dma_reserved;
102	struct imx_memory_info *memory;
103	struct snd_soc_dai_driver *drv;
104	int num_drv;
105	/* optional */
106	const struct imx_chip_ops *ops;
107};
108
109struct imx_common_data {
110	struct platform_device *ipc_dev;
111	struct imx_dsp_ipc *ipc_handle;
112	/* core may have no clocks */
113	struct clk_bulk_data *clks;
114	int clk_num;
115	/* core may have no PDs */
116	struct dev_pm_domain_list *pd_list;
117	void *chip_pdata;
118};
119
120static inline int imx_chip_core_kick(struct snd_sof_dev *sdev)
121{
122	const struct imx_chip_ops *ops = get_chip_info(sdev)->ops;
123
124	if (ops && ops->core_kick)
125		return ops->core_kick(sdev);
126
127	return 0;
128}
129
130static inline int imx_chip_core_shutdown(struct snd_sof_dev *sdev)
131{
132	const struct imx_chip_ops *ops = get_chip_info(sdev)->ops;
133
134	if (ops && ops->core_shutdown)
135		return ops->core_shutdown(sdev);
136
137	return 0;
138}
139
140static inline int imx_chip_core_reset(struct snd_sof_dev *sdev)
141{
142	const struct imx_chip_ops *ops = get_chip_info(sdev)->ops;
143
144	if (ops && ops->core_reset)
145		return ops->core_reset(sdev);
146
147	return 0;
148}
149
150static inline int imx_chip_probe(struct snd_sof_dev *sdev)
151{
152	const struct imx_chip_ops *ops = get_chip_info(sdev)->ops;
153
154	if (ops && ops->probe)
155		return ops->probe(sdev);
156
157	return 0;
158}
159
160void imx8_get_registers(struct snd_sof_dev *sdev,
161			struct sof_ipc_dsp_oops_xtensa *xoops,
162			struct sof_ipc_panic_info *panic_info,
163			u32 *stack, size_t stack_words);
164
165void imx8_dump(struct snd_sof_dev *sdev, u32 flags);
166
167extern const struct snd_sof_dsp_ops sof_imx_ops;
168
169#endif
~/ Read-only file preview.