Commit | Line | Data |
---|---|---|
ec470a07 TK |
1 | /**************************************************************************** |
2 | * | |
85aa0fce | 3 | * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved |
ec470a07 TK |
4 | * |
5 | ****************************************************************************/ | |
6 | ||
7 | #ifndef _SCSC_CORE_H | |
8 | #define _SCSC_CORE_H | |
9 | ||
10 | #include <linux/types.h> | |
11 | #include <linux/notifier.h> | |
12 | #include "scsc_mifram.h" | |
13 | ||
14 | #define SCSC_PANIC_CODE_FW 0 | |
15 | #define SCSC_PANIC_CODE_HOST 1 | |
16 | ||
17 | #define SCSC_FW_EVENT_FAILURE 0 | |
18 | #define SCSC_FW_EVENT_MOREDUMP_COMPLETE 1 | |
19 | ||
0cc73f69 RG |
20 | /** The following flags define the pools that can used for memory allocation. |
21 | * To be used with scsc_mx_service_mifram_alloc_extended **/ | |
22 | /* Standard memory allocation */ | |
23 | #define MIFRAMMAN_MEM_POOL_GENERIC 1 | |
24 | /* Used for buffers containing logs that will not be dumped by moredump */ | |
25 | #define MIFRAMMAN_MEM_POOL_LOGGING 2 | |
26 | ||
ec470a07 TK |
27 | struct device; |
28 | struct firmware; | |
29 | struct scsc_mx; | |
30 | ||
31 | enum scsc_service_id { | |
32 | SCSC_SERVICE_ID_NULL = 0, | |
33 | SCSC_SERVICE_ID_WLAN = 1, | |
34 | SCSC_SERVICE_ID_BT = 2, | |
35 | SCSC_SERVICE_ID_ANT = 3, | |
36 | SCSC_SERVICE_ID_R4DBG = 4, | |
37 | SCSC_SERVICE_ID_ECHO = 5, | |
38 | SCSC_SERVICE_ID_DBG_SAMPLER = 6, | |
39 | SCSC_SERVICE_ID_CLK20MHZ = 7, | |
40 | SCSC_SERVICE_ID_FM = 8, | |
41 | SCSC_SERVICE_ID_INVALID = 0xff, | |
42 | }; | |
43 | ||
5fcd17b3 | 44 | #ifdef CONFIG_SCSC_QOS |
ec470a07 | 45 | #define SCSC_SERVICE_TOTAL 9 |
5fcd17b3 | 46 | #endif |
ec470a07 TK |
47 | |
48 | enum scsc_module_client_reason { | |
49 | SCSC_MODULE_CLIENT_REASON_HW_PROBE = 0, | |
50 | SCSC_MODULE_CLIENT_REASON_HW_REMOVE = 1, | |
51 | SCSC_MODULE_CLIENT_REASON_RECOVERY = 2, | |
52 | SCSC_MODULE_CLIENT_REASON_INVALID = 0xff, | |
53 | }; | |
54 | ||
5fcd17b3 | 55 | #ifdef CONFIG_SCSC_QOS |
ec470a07 TK |
56 | enum scsc_qos_config { |
57 | SCSC_QOS_DISABLED = 0, | |
58 | SCSC_QOS_MIN = 1, | |
59 | SCSC_QOS_MED = 2, | |
60 | SCSC_QOS_MAX = 3, | |
61 | }; | |
5fcd17b3 | 62 | #endif |
bced05ce | 63 | |
5fcd17b3 | 64 | /* Core Driver Module registration */ |
ec470a07 TK |
65 | struct scsc_mx_module_client { |
66 | char *name; | |
67 | void (*probe)(struct scsc_mx_module_client *module_client, struct scsc_mx *mx, enum scsc_module_client_reason reason); | |
68 | void (*remove)(struct scsc_mx_module_client *module_client, struct scsc_mx *mx, enum scsc_module_client_reason reason); | |
69 | }; | |
70 | ||
71 | /* Service Client interface */ | |
72 | ||
73 | struct scsc_service_client; | |
74 | ||
75 | struct scsc_service_client { | |
76 | /** Called on Maxwell failure. The Client should Stop all SDRAM & MIF | |
77 | * Mailbox access as fast as possible and inform the Manager by calling | |
78 | * client_stopped() */ | |
79 | void (*stop_on_failure)(struct scsc_service_client *client); | |
80 | /** Called when Maxwell failure has handled and the Maxwell has been | |
81 | * reset. The Client should assume that any Maxwell resources it held are | |
82 | * invalid */ | |
83 | void (*failure_reset)(struct scsc_service_client *client, u16 scsc_panic_code); | |
84 | /* called when AP processor is going into suspend. */ | |
85 | int (*suspend)(struct scsc_service_client *client); | |
86 | /* called when AP processor has resumed */ | |
87 | int (*resume)(struct scsc_service_client *client); | |
084c2776 AC |
88 | /* called when log collection has been triggered */ |
89 | void (*log)(struct scsc_service_client *client, u16 reason); | |
ec470a07 TK |
90 | }; |
91 | ||
92 | #ifdef CONFIG_SCSC_FM | |
93 | /* | |
94 | * This must be used by FM Radio Service only. Other services must not use it. | |
95 | * FM Radio client must allocate memory for this structure using scsc_mx_service_mifram_alloc() | |
96 | * and pass this structure as a ref parameter to scsc_mx_service_start(). | |
97 | * The version of fm_ldo_conf (the LDO configuration structure) must be written | |
98 | * to the version field by the FM Radio Service and confirmed to match the define by the firmware. | |
99 | * Increment the version (FM_LDO_CONFIG_VERSION) when changing the layout of the structure. | |
100 | */ | |
101 | #define FM_LDO_CONFIG_VERSION 0 | |
102 | ||
103 | struct fm_ldo_conf { | |
104 | uint32_t version; /* FM_LDO_CONFIG_VERSION */ | |
105 | uint32_t ldo_on; | |
106 | }; | |
85aa0fce Y |
107 | |
108 | /* Parameters to pass from FM radio client driver to WLBT drivers */ | |
109 | struct wlbt_fm_params { | |
110 | u32 freq; /* Frequency (Hz) in use by FM radio */ | |
111 | }; | |
112 | ||
ec470a07 TK |
113 | #endif |
114 | ||
115 | #define PANIC_RECORD_SIZE 64 | |
116 | #define PANIC_RECORD_DUMP_BUFFER_SZ 4096 | |
117 | ||
118 | /* WARNING: THIS IS INTERRUPT CONTEXT! | |
119 | * here: some serious warnings about not blocking or doing anything lengthy at all | |
120 | */ | |
121 | typedef void (*scsc_mifintrbit_handler)(int which_bit, void *data); | |
122 | ||
123 | /* | |
124 | * Core Module Inteface | |
125 | */ | |
126 | int scsc_mx_module_register_client_module(struct scsc_mx_module_client *module_client); | |
127 | void scsc_mx_module_unregister_client_module(struct scsc_mx_module_client *module_client); | |
128 | int scsc_mx_module_reset(void); | |
129 | ||
130 | /* | |
131 | * Core Instance interface | |
132 | */ | |
133 | /** 1st thing to do is call open and return service managment interface*/ | |
134 | struct scsc_service *scsc_mx_service_open(struct scsc_mx *mx, enum scsc_service_id id, struct scsc_service_client *client, int *status); | |
135 | ||
136 | /* | |
137 | * Service interface | |
138 | */ | |
139 | /** pass a portable dram reference and returns kernel pointer (basically is dealing with the pointers) */ | |
140 | void *scsc_mx_service_mif_addr_to_ptr(struct scsc_service *service, scsc_mifram_ref ref); | |
141 | void *scsc_mx_service_mif_addr_to_phys(struct scsc_service *service, scsc_mifram_ref ref); | |
142 | int scsc_mx_service_mif_ptr_to_addr(struct scsc_service *service, void *mem_ptr, scsc_mifram_ref *ref); | |
143 | ||
144 | int scsc_mx_service_start(struct scsc_service *service, scsc_mifram_ref ref); | |
145 | int scsc_mx_service_stop(struct scsc_service *service); | |
146 | int scsc_mx_service_close(struct scsc_service *service); | |
147 | int scsc_mx_service_mif_dump_registers(struct scsc_service *service); | |
148 | ||
149 | /** Signal a failure detected by the Client. This will trigger the systemwide | |
150 | * failure handling procedure: _All_ Clients will be called back via | |
151 | * their stop_on_failure() handler as a side-effect. */ | |
152 | void scsc_mx_service_service_failed(struct scsc_service *service, const char *reason); | |
153 | ||
ec470a07 | 154 | /* MEMORY Interface*/ |
0cc73f69 RG |
155 | /** Allocate a contiguous block of SDRAM accessible to Client Driver. The memory will be allocated |
156 | * from generic pool (MIFRAMMAN_MEM_POOL_GENERIC) */ | |
ec470a07 | 157 | int scsc_mx_service_mifram_alloc(struct scsc_service *service, size_t nbytes, scsc_mifram_ref *ref, u32 align); |
0cc73f69 RG |
158 | /* Same as scsc_mx_service_mifram_alloc but allows to specify flags (MIFRAMMAN_MEM_POOL_XX). |
159 | * So, for example, to allocate memory from the logging pool use MIFRAMMAN_MEM_POOL_LOGGING. */ | |
160 | int scsc_mx_service_mifram_alloc_extended(struct scsc_service *service, size_t nbytes, scsc_mifram_ref *ref, u32 align, uint32_t flags); | |
5fcd17b3 PK |
161 | struct scsc_bt_audio_abox *scsc_mx_service_get_bt_audio_abox(struct scsc_service *service); |
162 | struct mifabox *scsc_mx_service_get_aboxram(struct scsc_service *service); | |
ec470a07 TK |
163 | /** Free a contiguous block of SDRAM */ |
164 | void scsc_mx_service_mifram_free(struct scsc_service *service, scsc_mifram_ref ref); | |
0cc73f69 | 165 | void scsc_mx_service_mifram_free_extended(struct scsc_service *service, scsc_mifram_ref ref, uint32_t flags); |
ec470a07 TK |
166 | |
167 | /* MBOX Interface */ | |
168 | /** Allocate n contiguous mailboxes. Outputs index of first mbox, returns FALSE if can’t allocate n contiguous mailboxes. */ | |
169 | bool scsc_mx_service_alloc_mboxes(struct scsc_service *service, int n, int *first_mbox_index); | |
170 | /** Free n contiguous mailboxes. */ | |
171 | void scsc_service_free_mboxes(struct scsc_service *service, int n, int first_mbox_index); | |
172 | ||
173 | /** Get kernel-space pointer to a mailbox. | |
174 | * The pointer can be cached as it is guaranteed not to change between service start & stop. | |
175 | **/ | |
176 | u32 *scsc_mx_service_get_mbox_ptr(struct scsc_service *service, int mbox_index); | |
177 | ||
178 | /* IRQ Interface */ | |
179 | /* Getters/Setters */ | |
180 | ||
181 | /* From R4/M4 */ | |
182 | int scsc_service_mifintrbit_bit_mask_status_get(struct scsc_service *service); | |
183 | int scsc_service_mifintrbit_get(struct scsc_service *service); | |
184 | void scsc_service_mifintrbit_bit_clear(struct scsc_service *service, int which_bit); | |
185 | void scsc_service_mifintrbit_bit_mask(struct scsc_service *service, int which_bit); | |
186 | void scsc_service_mifintrbit_bit_unmask(struct scsc_service *service, int which_bit); | |
187 | ||
188 | /* To R4/M4 */ | |
189 | enum scsc_mifintr_target { | |
190 | SCSC_MIFINTR_TARGET_R4 = 0, | |
191 | SCSC_MIFINTR_TARGET_M4 = 1 | |
192 | }; | |
193 | ||
194 | void scsc_service_mifintrbit_bit_set(struct scsc_service *service, int which_bit, enum scsc_mifintr_target dir); | |
195 | ||
196 | /* Register an interrupt handler -TOHOST direction. | |
197 | * Function returns the IRQ associated , -EIO if all interrupts have been assigned */ | |
198 | int scsc_service_mifintrbit_register_tohost(struct scsc_service *service, scsc_mifintrbit_handler handler, void *data); | |
199 | /* Unregister an interrupt handler associated with a bit -TOHOST direction */ | |
200 | int scsc_service_mifintrbit_unregister_tohost(struct scsc_service *service, int which_bit); | |
201 | ||
202 | /* Get an interrupt bit associated with the target (R4/M4) -FROMHOST direction | |
203 | * Function returns the IRQ bit associated , -EIO if error */ | |
204 | int scsc_service_mifintrbit_alloc_fromhost(struct scsc_service *service, enum scsc_mifintr_target dir); | |
205 | /* Free an interrupt bit associated with the target (R4/M4) -FROMHOST direction | |
206 | * Function returns the 0 if succedes , -EIO if error */ | |
207 | int scsc_service_mifintrbit_free_fromhost(struct scsc_service *service, int which_bit, enum scsc_mifintr_target dir); | |
208 | /* | |
209 | * Return a kernel device associated 1:1 with the Maxwell instance. | |
210 | * This is published only for the purpose of associating service drivers | |
211 | * with a Maxwell instance for logging purposes. Clients should not make | |
212 | * any assumptions about the device type. In some configurations this may | |
213 | * be the associated host-interface device (AXI/PCIe), | |
214 | * but this may change in future. | |
215 | */ | |
216 | struct device *scsc_service_get_device(struct scsc_service *service); | |
5fcd17b3 | 217 | struct device *scsc_service_get_device_by_mx(struct scsc_mx *mx); |
ec470a07 TK |
218 | |
219 | int scsc_service_force_panic(struct scsc_service *service); | |
220 | ||
85aa0fce Y |
221 | /* |
222 | * API to share /sys/wifi kobject between core and wifi driver modules. | |
223 | * Depending upon the order of loading respective drivers, a kobject is | |
224 | * created and shared with the other driver. This convoluted implementation | |
225 | * is required as we need the common kobject associated with "/sys/wifi" directory | |
226 | * when creating a file underneth. core driver (mxman.c) need to create "memdump" | |
227 | * and wifi driver (dev.c,mgt.c) needs to create "mac_addr" files respectively. | |
228 | */ | |
229 | struct kobject *mxman_wifi_kobject_ref_get(void); | |
230 | void mxman_wifi_kobject_ref_put(void); | |
ec470a07 TK |
231 | |
232 | #ifdef CONFIG_SCSC_SMAPPER | |
233 | /* SMAPPER Interface */ | |
234 | /* Configure smapper. Function should configure smapper FW memory map, range, and granularity */ | |
235 | void scsc_service_mifsmapper_configure(struct scsc_service *service, u32 granularity); | |
236 | /* Allocate large/small entries bank. Outputs index of bank, returns -EIO if can’t allocate any banks. */ | |
237 | /* Function also returns by the numbers of entries that could be used in the bank as the number of entries | |
238 | * is HW dependent (entries/granurality/memory window in FW) | |
239 | */ | |
240 | int scsc_service_mifsmapper_alloc_bank(struct scsc_service *service, bool large_bank, u32 entry_size, u16 *entries); | |
241 | /* Free large/small entries bank */ | |
242 | int scsc_service_mifsmapper_free_bank(struct scsc_service *service, u8 bank); | |
243 | /* Get number entries, returns error if entries have not been allocated */ | |
244 | int scsc_service_mifsmapper_get_entries(struct scsc_service *service, u8 bank, u8 num_entries, u8 *entries); | |
245 | /* Free number entries, returns error if entries have not been allocated */ | |
246 | int scsc_service_mifsmapper_free_entries(struct scsc_service *service, u8 bank, u8 num_entries, u8 *entries); | |
247 | /* Program SRAM entry */ | |
248 | int scsc_service_mifsmapper_write_sram(struct scsc_service *service, u8 bank, u8 num_entries, u8 first_entry, dma_addr_t *addr); | |
249 | u32 scsc_service_mifsmapper_get_bank_base_address(struct scsc_service *service, u8 bank); | |
34f6bc20 AC |
250 | /* Get SMAPPER aligment */ |
251 | u16 scsc_service_get_alignment(struct scsc_service *service); | |
ec470a07 TK |
252 | #endif |
253 | ||
5fcd17b3 | 254 | #ifdef CONFIG_SCSC_QOS |
ec470a07 TK |
255 | int scsc_service_pm_qos_add_request(struct scsc_service *service, enum scsc_qos_config config); |
256 | int scsc_service_pm_qos_update_request(struct scsc_service *service, enum scsc_qos_config config); | |
257 | int scsc_service_pm_qos_remove_request(struct scsc_service *service); | |
5fcd17b3 | 258 | #endif |
084c2776 AC |
259 | |
260 | /* MXLOGGER API */ | |
261 | /* If there is no service/mxman associated, register the observer as global (will affect all the mx instanes)*/ | |
262 | /* Users of these functions should ensure that the registers/unregister functions are balanced (i.e. if observer is registed as global, | |
263 | * it _has_ to unregister as global) */ | |
264 | int scsc_service_register_observer(struct scsc_service *service, char *name); | |
265 | /* Unregister an observer */ | |
266 | int scsc_service_unregister_observer(struct scsc_service *service, char *name); | |
267 | ||
ec470a07 TK |
268 | /* Reads a configuration file into memory. |
269 | * | |
270 | * Path is relative to the currently selected firmware configuration | |
271 | * subdirectory. | |
272 | * Returns pointer to data or NULL if file not found. | |
273 | * Call mx140_file_release_conf()to release the memory. | |
274 | */ | |
479ea86c | 275 | int mx140_file_request_conf(struct scsc_mx *mx, const struct firmware **conf, const char *config_path, const char *filename); |
ec470a07 TK |
276 | |
277 | /* Reads a debug configuration file into memory. | |
278 | * | |
279 | * Path is relative to the currently selected firmware configuration | |
280 | * subdirectory. | |
281 | * Returns pointer to data or NULL if file not found. | |
282 | * Call mx140_file_release_conf()to release the memory. | |
283 | */ | |
284 | int mx140_file_request_debug_conf(struct scsc_mx *mx, const struct firmware **conf, const char *config_path); | |
285 | ||
286 | /* Read device configuration file into memory. | |
287 | * | |
288 | * Path is relative to the device configuration directory. | |
289 | * Returns pointer to data or NULL if file not found. | |
290 | * Call mx140_file_release_conf() to release the memory. | |
291 | * This call is only used for configuration files that are | |
292 | * device instance specific (e.g. mac addresses) | |
293 | */ | |
294 | int mx140_file_request_device_conf(struct scsc_mx *mx, const struct firmware **conf, const char *config_path); | |
295 | ||
296 | /* Release configuration file memory | |
297 | * | |
298 | * If conf is NULL, has no effect. | |
299 | */ | |
300 | void mx140_file_release_conf(struct scsc_mx *mx, const struct firmware *conf); | |
301 | ||
302 | /* Read device configuration file into memory. | |
303 | * | |
304 | * Path is absolute. | |
305 | * Returns pointer to data or NULL if file not found. | |
306 | * Call mx140_release_file() to release the memory. | |
307 | */ | |
308 | int mx140_request_file(struct scsc_mx *mx, char *path, const struct firmware **firmp); | |
b697b8ad | 309 | |
ec470a07 TK |
310 | /* Release configuration file memory allocated with mx140_request_file() |
311 | * | |
312 | * If firmp is NULL, has no effect. | |
313 | */ | |
314 | int mx140_release_file(struct scsc_mx *mx, const struct firmware *firmp); | |
315 | ||
316 | /* 20 MHz clock API. | |
317 | * The mx140 device uses a clock that is also required by the USB driver. | |
318 | * This API allows the USB/clock driver to inform the mx140 driver that the | |
319 | * clock is required and that it must boot and/or keep the clock running. | |
320 | */ | |
321 | ||
322 | enum mx140_clk20mhz_status { | |
323 | MX140_CLK_SUCCESS = 0, /* Returned successfully */ | |
324 | MX140_CLK_STARTED, /* mx140 has started the clock */ | |
325 | MX140_CLK_STOPPED, /* mx140 has stopped the clock */ | |
326 | MX140_CLK_NOT_STARTED, /* failed to start the clock */ | |
327 | MX140_CLK_NOT_STOPPED, /* failed to stop the clock */ | |
328 | MX140_CLK_ASYNC_FAIL, /* mx140 failure, async call */ | |
329 | }; | |
330 | ||
331 | /* Register for 20 MHz clock API callbacks | |
332 | * | |
333 | * Parameters: | |
334 | * client_cb: | |
335 | * If client provides non-NULL client_cb, the request is asynchronous and | |
336 | * the client will be called back when the clock service is started. | |
337 | * If client_cb is NULL, the request is blocking. | |
338 | * data: | |
339 | * opaque context for the client, and will be passed back in any callback | |
340 | * | |
341 | * Note it is possible that the callback may be made in the context of the | |
342 | * calling request/release function. | |
343 | * | |
344 | * Returns 0 on success | |
345 | */ | |
346 | int mx140_clk20mhz_register(void (*client_cb)(void *data, enum mx140_clk20mhz_status event), void *data); | |
347 | ||
348 | /* Unregister for 20 MHz clock API callbacks. | |
349 | * After this call is made, the mx140 driver will no longer call back. | |
350 | */ | |
351 | void mx140_clk20mhz_unregister(void); | |
352 | ||
353 | /* Client request that the clock be available. | |
354 | * | |
355 | * If a callback was installed via mx140_clk20mhz_register(), the mx140 driver | |
356 | * will call back when the clock is available. If no callback was installed, | |
357 | * the request is blocking and will return when the clock is running. | |
358 | * | |
359 | * Returns: | |
360 | * mx140_clk20mhz_status if a blocking attempt was made to start the clock, | |
361 | * MX140_CLK_SUCCESS if the request will happen asynchronously, or, | |
362 | * -ve error code on other error. | |
363 | * | |
364 | */ | |
365 | int mx140_clk20mhz_request(void); | |
366 | ||
367 | /* Client informs that the clock is no longer needed | |
368 | * | |
369 | * Returns: | |
370 | * mx140_clk20mhz_status if a blocking attempt was made to stop the clock, | |
371 | * MX140_CLK_SUCCESS if the request will happen asynchronously, or, | |
372 | * -ve error code on other error. | |
373 | */ | |
374 | int mx140_clk20mhz_release(void); | |
375 | ||
376 | ||
377 | /* Client requests that FM LDO be available. | |
378 | * | |
379 | * Returns: | |
380 | * 0 on success or -ve error code on error. | |
381 | * | |
382 | */ | |
383 | int mx250_fm_request(void); | |
384 | ||
385 | ||
386 | /* Client informs that the LDO is no longer needed | |
387 | * | |
388 | * Returns: | |
389 | * 0 on success or -ve error code on error. | |
390 | */ | |
391 | int mx250_fm_release(void); | |
392 | ||
393 | ||
85aa0fce Y |
394 | /* FM client informs of parameter change. |
395 | * | |
396 | * mx250_fm_request() must have been called first. | |
397 | * | |
398 | * Returns: | |
399 | * None | |
400 | */ | |
401 | void mx250_fm_set_params(struct wlbt_fm_params *info); | |
402 | ||
ec470a07 TK |
403 | /* |
404 | * for set test mode. | |
405 | * | |
406 | */ | |
407 | bool slsi_is_rf_test_mode_enabled(void); | |
408 | ||
409 | int mx140_log_dump(void); | |
410 | ||
411 | void mxman_get_fw_version(char *version, size_t ver_sz); | |
412 | void mxman_get_driver_version(char *version, size_t ver_sz); | |
413 | ||
414 | int mxman_register_firmware_notifier(struct notifier_block *nb); | |
415 | int mxman_unregister_firmware_notifier(struct notifier_block *nb); | |
416 | ||
85aa0fce Y |
417 | /* Status of WLBT autorecovery on the platform |
418 | * | |
419 | * Returns: | |
420 | * false - enabled, true disabled | |
421 | */ | |
422 | bool mxman_recovery_disabled(void); | |
423 | ||
424 | /* function to provide string representation of uint8 trigger code */ | |
425 | static inline const char *scsc_get_trigger_str(int code) | |
426 | { | |
427 | switch (code) { | |
428 | case 1: return "scsc_log_fw_panic"; | |
429 | case 2: return "scsc_log_user"; | |
430 | case 3: return "scsc_log_fw"; | |
431 | case 4: return "scsc_log_dumpstate"; | |
432 | case 5: return "scsc_log_host_wlan"; | |
433 | case 6: return "scsc_log_host_bt"; | |
434 | case 7: return "scsc_log_host_common"; | |
15e9b75a | 435 | case 8: return "scsc_log_sys_error"; |
85aa0fce Y |
436 | case 0: |
437 | default: | |
438 | return "unknown"; | |
439 | } | |
440 | }; | |
441 | ||
ec470a07 | 442 | #endif |