aboutsummaryrefslogtreecommitdiff
path: root/drivers/soc/qcom/icnss2/main.h
blob: 6e4bff30a587749c304c58dca58a92d6c539ec43 (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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

#ifndef __MAIN_H__
#define __MAIN_H__

#include <linux/adc-tm-clients.h>
#include <linux/iio/consumer.h>
#include <linux/irqreturn.h>
#include <asm/dma-iommu.h>
#include <linux/kobject.h>
#include <linux/platform_device.h>
#include <linux/ipc_logging.h>
#include <dt-bindings/iio/qcom,spmi-vadc.h>
#include <soc/qcom/icnss2.h>
#include <soc/qcom/service-locator.h>
#include <soc/qcom/service-notifier.h>
#include "wlan_firmware_service_v01.h"

#define WCN6750_DEVICE_ID 0x6750
#define ADRASTEA_DEVICE_ID 0xabcd
#define QMI_WLFW_MAX_NUM_MEM_SEG 32
#define THERMAL_NAME_LENGTH 20
extern uint64_t dynamic_feature_mask;

enum icnss_bdf_type {
	ICNSS_BDF_BIN,
	ICNSS_BDF_ELF,
	ICNSS_BDF_REGDB = 4,
	ICNSS_BDF_DUMMY = 255,
};

struct icnss_control_params {
	unsigned long quirks;
	unsigned int qmi_timeout;
	unsigned int bdf_type;
};

enum icnss_driver_event_type {
	ICNSS_DRIVER_EVENT_SERVER_ARRIVE,
	ICNSS_DRIVER_EVENT_SERVER_EXIT,
	ICNSS_DRIVER_EVENT_FW_READY_IND,
	ICNSS_DRIVER_EVENT_REGISTER_DRIVER,
	ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
	ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
	ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND,
	ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
	ICNSS_DRIVER_EVENT_IDLE_RESTART,
	ICNSS_DRIVER_EVENT_FW_INIT_DONE_IND,
	ICNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM,
	ICNSS_DRIVER_EVENT_QDSS_TRACE_SAVE,
	ICNSS_DRIVER_EVENT_QDSS_TRACE_FREE,
	ICNSS_DRIVER_EVENT_MAX,
};

enum icnss_soc_wake_event_type {
	ICNSS_SOC_WAKE_REQUEST_EVENT,
	ICNSS_SOC_WAKE_RELEASE_EVENT,
	ICNSS_SOC_WAKE_EVENT_MAX,
};

struct icnss_event_server_arrive_data {
	unsigned int node;
	unsigned int port;
};

struct icnss_event_pd_service_down_data {
	bool crashed;
	bool fw_rejuvenate;
};

struct icnss_driver_event {
	struct list_head list;
	enum icnss_driver_event_type type;
	bool sync;
	struct completion complete;
	int ret;
	void *data;
};

struct icnss_soc_wake_event {
	struct list_head list;
	enum icnss_soc_wake_event_type type;
	bool sync;
	struct completion complete;
	int ret;
	void *data;
};

enum icnss_driver_state {
	ICNSS_WLFW_CONNECTED,
	ICNSS_POWER_ON,
	ICNSS_FW_READY,
	ICNSS_DRIVER_PROBED,
	ICNSS_FW_TEST_MODE,
	ICNSS_PM_SUSPEND,
	ICNSS_PM_SUSPEND_NOIRQ,
	ICNSS_SSR_REGISTERED,
	ICNSS_PDR_REGISTERED,
	ICNSS_PD_RESTART,
	ICNSS_WLFW_EXISTS,
	ICNSS_SHUTDOWN_DONE,
	ICNSS_HOST_TRIGGERED_PDR,
	ICNSS_FW_DOWN,
	ICNSS_DRIVER_UNLOADING,
	ICNSS_REJUVENATE,
	ICNSS_MODE_ON,
	ICNSS_BLOCK_SHUTDOWN,
	ICNSS_PDR,
	ICNSS_DEL_SERVER,
	ICNSS_COLD_BOOT_CAL,
};

struct ce_irq_list {
	int irq;
	irqreturn_t (*handler)(int irq, void *priv);
};

struct icnss_vreg_cfg {
	const char *name;
	u32 min_uv;
	u32 max_uv;
	u32 load_ua;
	u32 delay_us;
	u32 need_unvote;
	bool required;
};

struct icnss_vreg_info {
	struct list_head list;
	struct regulator *reg;
	struct icnss_vreg_cfg cfg;
	u32 enabled;
};

struct icnss_cpr_info {
	resource_size_t tcs_cmd_base_addr;
	resource_size_t tcs_cmd_data_addr;
	void __iomem *tcs_cmd_base_addr_io;
	void __iomem *tcs_cmd_data_addr_io;
	u32 cpr_pmic_addr;
	u32 voltage;
};

enum icnss_vreg_type {
	ICNSS_VREG_PRIM,
};
struct icnss_clk_cfg {
	const char *name;
	u32 freq;
	u32 required;
};

struct icnss_clk_info {
	struct list_head list;
	struct clk *clk;
	struct icnss_clk_cfg cfg;
	u32 enabled;
};

struct icnss_fw_mem {
	size_t size;
	void *va;
	phys_addr_t pa;
	u8 valid;
	u32 type;
	unsigned long attrs;
};

struct icnss_stats {
	struct {
		uint32_t posted;
		uint32_t processed;
	} events[ICNSS_DRIVER_EVENT_MAX];

	struct {
		u32 posted;
		u32 processed;
	} soc_wake_events[ICNSS_SOC_WAKE_EVENT_MAX];

	struct {
		uint32_t request;
		uint32_t free;
		uint32_t enable;
		uint32_t disable;
	} ce_irqs[ICNSS_MAX_IRQ_REGISTRATIONS];

	struct {
		uint32_t pdr_fw_crash;
		uint32_t pdr_host_error;
		uint32_t root_pd_crash;
		uint32_t root_pd_shutdown;
	} recovery;

	uint32_t pm_suspend;
	uint32_t pm_suspend_err;
	uint32_t pm_resume;
	uint32_t pm_resume_err;
	uint32_t pm_suspend_noirq;
	uint32_t pm_suspend_noirq_err;
	uint32_t pm_resume_noirq;
	uint32_t pm_resume_noirq_err;
	uint32_t pm_stay_awake;
	uint32_t pm_relax;

	uint32_t ind_register_req;
	uint32_t ind_register_resp;
	uint32_t ind_register_err;
	uint32_t msa_info_req;
	uint32_t msa_info_resp;
	uint32_t msa_info_err;
	uint32_t msa_ready_req;
	uint32_t msa_ready_resp;
	uint32_t msa_ready_err;
	uint32_t msa_ready_ind;
	uint32_t cap_req;
	uint32_t cap_resp;
	uint32_t cap_err;
	uint32_t pin_connect_result;
	uint32_t cfg_req;
	uint32_t cfg_resp;
	uint32_t cfg_req_err;
	uint32_t mode_req;
	uint32_t mode_resp;
	uint32_t mode_req_err;
	uint32_t ini_req;
	uint32_t ini_resp;
	uint32_t ini_req_err;
	u32 rejuvenate_ind;
	uint32_t rejuvenate_ack_req;
	uint32_t rejuvenate_ack_resp;
	uint32_t rejuvenate_ack_err;
	uint32_t vbatt_req;
	uint32_t vbatt_resp;
	uint32_t vbatt_req_err;
	uint32_t device_info_req;
	uint32_t device_info_resp;
	uint32_t device_info_err;
	u32 exit_power_save_req;
	u32 exit_power_save_resp;
	u32 exit_power_save_err;
	u32 soc_wake_req;
	u32 soc_wake_resp;
	u32 soc_wake_err;
};

#define WLFW_MAX_TIMESTAMP_LEN 32
#define WLFW_MAX_BUILD_ID_LEN 128
#define WLFW_MAX_NUM_MEMORY_REGIONS 2
#define WLFW_FUNCTION_NAME_LEN 129
#define WLFW_MAX_DATA_SIZE 6144
#define WLFW_MAX_STR_LEN 16
#define WLFW_MAX_NUM_CE 12
#define WLFW_MAX_NUM_SVC 24
#define WLFW_MAX_NUM_SHADOW_REG 24

struct service_notifier_context {
	void *handle;
	uint32_t instance_id;
	char name[QMI_SERVREG_LOC_NAME_LENGTH_V01 + 1];
};

struct wlfw_rf_chip_info {
	uint32_t chip_id;
	uint32_t chip_family;
};

struct wlfw_rf_board_info {
	uint32_t board_id;
};

struct wlfw_fw_version_info {
	uint32_t fw_version;
	char fw_build_timestamp[WLFW_MAX_TIMESTAMP_LEN + 1];
};

struct icnss_mem_region_info {
	uint64_t reg_addr;
	uint32_t size;
	uint8_t secure_flag;
};

struct icnss_msi_user {
	char *name;
	int num_vectors;
	u32 base_vector;
};

struct icnss_msi_config {
	int total_vectors;
	int total_users;
	struct icnss_msi_user *users;
};

struct icnss_thermal_cdev {
	struct list_head tcdev_list;
	int tcdev_id;
	unsigned long curr_thermal_state;
	unsigned long max_thermal_state;
	struct device_node *dev_node;
	struct thermal_cooling_device *tcdev;
};

struct icnss_priv {
	uint32_t magic;
	struct platform_device *pdev;
	struct icnss_driver_ops *ops;
	struct ce_irq_list ce_irq_list[ICNSS_MAX_IRQ_REGISTRATIONS];
	struct list_head vreg_list;
	struct list_head clk_list;
	struct icnss_cpr_info cpr_info;
	unsigned long device_id;
	struct icnss_msi_config *msi_config;
	u32 msi_base_data;
	struct icnss_control_params ctrl_params;
	u8 cal_done;
	u32 ce_irqs[ICNSS_MAX_IRQ_REGISTRATIONS];
	u32 srng_irqs[IWCN_MAX_IRQ_REGISTRATIONS];
	phys_addr_t mem_base_pa;
	void __iomem *mem_base_va;
	u32 mem_base_size;
	struct iommu_domain *iommu_domain;
	dma_addr_t smmu_iova_start;
	size_t smmu_iova_len;
	dma_addr_t smmu_iova_ipa_start;
	size_t smmu_iova_ipa_len;
	struct qmi_handle qmi;
	struct list_head event_list;
	struct list_head soc_wake_msg_list;
	spinlock_t event_lock;
	spinlock_t soc_wake_msg_lock;
	struct work_struct event_work;
	struct work_struct fw_recv_msg_work;
	struct work_struct soc_wake_msg_work;
	struct workqueue_struct *event_wq;
	struct workqueue_struct *soc_wake_wq;
	phys_addr_t msa_pa;
	phys_addr_t msi_addr_pa;
	dma_addr_t msi_addr_iova;
	uint32_t msa_mem_size;
	void *msa_va;
	unsigned long state;
	struct wlfw_rf_chip_info chip_info;
	uint32_t board_id;
	uint32_t soc_id;
	struct wlfw_fw_version_info fw_version_info;
	char fw_build_id[WLFW_MAX_BUILD_ID_LEN + 1];
	u32 pwr_pin_result;
	u32 phy_io_pin_result;
	u32 rf_pin_result;
	uint32_t nr_mem_region;
	struct icnss_mem_region_info
		mem_region[WLFW_MAX_NUM_MEMORY_REGIONS];
	struct dentry *root_dentry;
	spinlock_t on_off_lock;
	struct icnss_stats stats;
	struct work_struct service_notifier_work;
	struct service_notifier_context *service_notifier;
	struct notifier_block service_notifier_nb;
	int total_domains;
	struct notifier_block get_service_nb;
	void *modem_notify_handler;
	struct notifier_block modem_ssr_nb;
	uint32_t diag_reg_read_addr;
	uint32_t diag_reg_read_mem_type;
	uint32_t diag_reg_read_len;
	uint8_t *diag_reg_read_buf;
	atomic_t pm_count;
	struct ramdump_device *msa0_dump_dev;
	bool force_err_fatal;
	bool allow_recursive_recovery;
	bool early_crash_ind;
	u8 cause_for_rejuvenation;
	u8 requesting_sub_system;
	u16 line_number;
	struct mutex dev_lock;
	uint32_t fw_error_fatal_irq;
	uint32_t fw_early_crash_irq;
	struct completion unblock_shutdown;
	struct adc_tm_param vph_monitor_params;
	struct adc_tm_chip *adc_tm_dev;
	struct iio_channel *channel;
	uint64_t vph_pwr;
	bool vbatt_supported;
	char function_name[WLFW_FUNCTION_NAME_LEN + 1];
	bool is_ssr;
	bool smmu_s1_enable;
	struct kobject *icnss_kobject;
	atomic_t is_shutdown;
	u32 qdss_mem_seg_len;
	struct icnss_fw_mem qdss_mem[QMI_WLFW_MAX_NUM_MEM_SEG];
	void *get_info_cb_ctx;
	int (*get_info_cb)(void *ctx, void *event, int event_len);
	atomic_t soc_wake_ref_count;
	struct list_head icnss_tcdev_list;
	struct mutex tcdev_lock;
};

struct icnss_reg_info {
	uint32_t mem_type;
	uint32_t reg_offset;
	uint32_t data_len;
};

char *icnss_driver_event_to_str(enum icnss_driver_event_type type);
int icnss_call_driver_uevent(struct icnss_priv *priv,
				    enum icnss_uevent uevent, void *data);
int icnss_driver_event_post(struct icnss_priv *priv,
			    enum icnss_driver_event_type type,
			    u32 flags, void *data);
void icnss_allow_recursive_recovery(struct device *dev);
void icnss_disallow_recursive_recovery(struct device *dev);
char *icnss_soc_wake_event_to_str(enum icnss_soc_wake_event_type type);
int icnss_soc_wake_event_post(struct icnss_priv *priv,
			      enum icnss_soc_wake_event_type type,
			      u32 flags, void *data);
int icnss_get_iova(struct icnss_priv *priv, u64 *addr, u64 *size);
int icnss_get_iova_ipa(struct icnss_priv *priv, u64 *addr, u64 *size);
int icnss_get_cpr_info(struct icnss_priv *priv);
int icnss_update_cpr_info(struct icnss_priv *priv);
#endif