summaryrefslogtreecommitdiff
path: root/asoc/codecs/wcd_cpe_core.h
blob: b16503d9cbde2ce094a49b4ec4334aff7408ebaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 */

#ifndef WCD_CPE_CORE_H
#define WCD_CPE_CORE_H

#include <soc/qcom/ramdump.h>
#include <linux/dma-mapping.h>
#include "wcd_cpe_services.h"

#define WCD_CPE_LAB_MAX_LATENCY 250
#define WCD_CPE_MAD_SLIM_CHANNEL 140

/* Indicates CPE block is ready for image re-download */
#define WCD_CPE_BLK_READY  (1 << 0)
/* Indicates the underlying bus is ready */
#define WCD_CPE_BUS_READY (1 << 1)

/*
 * only when the underlying bus and CPE block both are ready,
 * the state will be ready to download
 */
#define WCD_CPE_READY_TO_DLOAD	\
	(WCD_CPE_BLK_READY | WCD_CPE_BUS_READY)

#define WCD_CPE_LOAD_IMEM (1 << 0)
#define WCD_CPE_LOAD_DATA (1 << 1)
#define WCD_CPE_LOAD_ALL \
	(WCD_CPE_LOAD_IMEM | WCD_CPE_LOAD_DATA)

#define WCD_CPE_IMAGE_FNAME_MAX 64

#define WCD_CPE_AFE_OUT_PORT_2 2
#define WCD_CPE_AFE_OUT_PORT_4 4

enum {
	WCD_CPE_LSM_CAL_AFE = 0,
	WCD_CPE_LSM_CAL_LSM,
	WCD_CPE_LSM_CAL_TOPOLOGY_ID,
	WCD_CPE_LSM_CAL_MAX,
};

enum cpe_err_irq_cntl_type {
	CPE_ERR_IRQ_MASK = 0,
	CPE_ERR_IRQ_UNMASK,
	CPE_ERR_IRQ_CLEAR,
	CPE_ERR_IRQ_STATUS,
};

struct wcd_cpe_cdc_cb {
	/* codec provided callback to enable RCO */
	int (*cdc_clk_en)(struct snd_soc_component *cpmponent, bool enable);

	/* callback for FLL setup for codec */
	int (*cpe_clk_en)(struct snd_soc_component *component, bool enable);
	int (*cdc_ext_clk)(struct snd_soc_component *component, int enable,
			   bool dapm);
	int (*lab_cdc_ch_ctl)(struct snd_soc_component *component, u8 event);
	int (*get_afe_out_port_id)(struct snd_soc_component *component,
				   u16 *port_id);
	int (*bus_vote_bw)(struct snd_soc_component *component,
			   bool vote);

	/* Callback to control the cpe error interrupt mask/status/clear */
	int (*cpe_err_irq_control)(struct snd_soc_component *component,
				    enum cpe_err_irq_cntl_type cntl_type,
				    u8 *status);
};

enum wcd_cpe_ssr_state_event {
	/* Indicates CPE is initialized */
	WCD_CPE_INITIALIZED = 0,
	/* Indicates that IMEM is downloaded to CPE */
	WCD_CPE_IMEM_DOWNLOADED,
	/* Indicates CPE is enabled */
	WCD_CPE_ENABLED,
	/* Indicates that CPE is currently active */
	WCD_CPE_ACTIVE,
	/* Event from underlying bus notifying bus is down */
	WCD_CPE_BUS_DOWN_EVENT,
	/* Event from CPE block, notifying CPE is down */
	WCD_CPE_SSR_EVENT,
	/* Event from underlying bus notifying bus is up */
	WCD_CPE_BUS_UP_EVENT,
};

struct wcd_cpe_ssr_entry {
	int offline;
	u32 offline_change;
	wait_queue_head_t offline_poll_wait;
	struct snd_info_entry *entry;
};

struct wcd_cpe_irq_info {
	int cpe_engine_irq;
	int cpe_err_irq;
	u8 cpe_fatal_irqs;
};

struct wcd_cpe_hw_info {
	u32 dram_offset;
	size_t dram_size;
	u32 iram_offset;
	size_t iram_size;
};

struct wcd_cpe_core {
	/* handle to cpe services */
	void *cpe_handle;

	/* registration handle to cpe services */
	void *cpe_reg_handle;

	/* cmi registration handle for afe service */
	void *cmi_afe_handle;

	/* handle to codec */
	struct snd_soc_component *component;

	/* codec device */
	struct device *dev;

	/* firmware image file name */
	char fname[WCD_CPE_IMAGE_FNAME_MAX];

	/* firmware image file name from sysfs */
	char dyn_fname[WCD_CPE_IMAGE_FNAME_MAX];

	/* codec information needed by cpe services */
	struct cpe_svc_codec_info_v1 cdc_info;

	/* work to perform image download */
	struct work_struct load_fw_work;

	/* flag to indicate mode in which cpe needs to be booted */
	int cpe_debug_mode;

	/* callbacks for codec specific implementation */
	const struct wcd_cpe_cdc_cb *cpe_cdc_cb;

	/* work to handle CPE SSR*/
	struct work_struct ssr_work;

	/* PM handle for suspend mode during SSR */
	struct pm_qos_request pm_qos_req;

	/* completion event indicating CPE OFFLINE */
	struct completion offline_compl;

	/* entry into snd card procfs indicating cpe status */
	struct wcd_cpe_ssr_entry ssr_entry;

	/*
	 * completion event to signal CPE is
	 * ready for image re-download
	 */
	struct completion ready_compl;

	/* maintains the status for cpe ssr */
	u8 ready_status;

	/* Indicate SSR type */
	enum wcd_cpe_ssr_state_event ssr_type;

	/* mutex to protect cpe ssr status variables */
	struct mutex ssr_lock;

	/* mutex to protect cpe session status variables */
	struct mutex session_lock;

	/* Store the calibration data needed for cpe */
	struct cal_type_data *cal_data[WCD_CPE_LSM_CAL_MAX];

	/* completion event to signal CPE is online */
	struct completion online_compl;

	/* reference counter for cpe usage */
	u8 cpe_users;

	/* Ramdump support */
	void *cpe_ramdump_dev;
	struct ramdump_segment cpe_ramdump_seg;
	dma_addr_t cpe_dump_addr;
	void *cpe_dump_v_addr;

	/* SFR support */
	u32 sfr_buf_addr;
	size_t sfr_buf_size;

	/* IRQ information for CPE interrupts */
	struct wcd_cpe_irq_info irq_info;

	/* Kobject for sysfs entry */
	struct kobject cpe_kobj;

	/* Reference count for cpe clk*/
	int cpe_clk_ref;

	/* codec based hardware info */
	struct wcd_cpe_hw_info hw_info;
};

struct wcd_cpe_params {
	struct snd_soc_component *component;
	struct wcd_cpe_core * (*get_cpe_core)(
				struct snd_soc_component *component);
	const struct wcd_cpe_cdc_cb *cdc_cb;
	int dbg_mode;
	u16 cdc_major_ver;
	u16 cdc_minor_ver;
	u32 cdc_id;

	struct wcd_cpe_irq_info cdc_irq_info;

	struct cpe_svc_init_param *cpe_svc_params;
};

#if IS_ENABLED(CONFIG_SND_SOC_WCD_CPE)
int wcd_cpe_ssr_event(void *core_handle,
		      enum wcd_cpe_ssr_state_event event);
struct wcd_cpe_core *wcd_cpe_init(const char *img_fname,
struct snd_soc_component *component, struct wcd_cpe_params *params);
#else /* CONFIG_SND_SOC_WCD_CPE */
static inline int wcd_cpe_ssr_event(void *core_handle,
		      enum wcd_cpe_ssr_state_event event)
{
	return 0;
}
static inline struct wcd_cpe_core *wcd_cpe_init(const char *img_fname,
					struct snd_soc_component *component,
					struct wcd_cpe_params *params)
{
	return NULL;
}
#endif /* CONFIG_SND_SOC_WCD_CPE */
#endif