299 lines
11 KiB
C
Executable File
299 lines
11 KiB
C
Executable File
/****************************************************************************
|
||
*
|
||
* Copyright (c) 2014 - 2016 Samsung Electronics Co., Ltd. All rights reserved
|
||
*
|
||
****************************************************************************/
|
||
|
||
#ifndef _SCSC_CORE_H
|
||
#define _SCSC_CORE_H
|
||
|
||
#include <linux/types.h>
|
||
#include <linux/notifier.h>
|
||
#include "scsc_mifram.h"
|
||
|
||
#define SCSC_PANIC_CODE_FW 0
|
||
#define SCSC_PANIC_CODE_HOST 1
|
||
/* offset from 0x80000000, the start of BAAW1 region */
|
||
#define SCSC_BAAW1_OFFSET 0x400000
|
||
|
||
#define SCSC_FW_EVENT_FAILURE 0
|
||
#define SCSC_FW_EVENT_MOREDUMP_COMPLETE 1
|
||
|
||
struct device;
|
||
struct firmware;
|
||
struct scsc_mx;
|
||
|
||
enum scsc_service_id {
|
||
SCSC_SERVICE_ID_NULL = 0,
|
||
SCSC_SERVICE_ID_WLAN = 1,
|
||
SCSC_SERVICE_ID_BT = 2,
|
||
SCSC_SERVICE_ID_ANT = 3,
|
||
SCSC_SERVICE_ID_R4DBG = 4,
|
||
SCSC_SERVICE_ID_ECHO = 5,
|
||
SCSC_SERVICE_ID_DBG_SAMPLER = 6,
|
||
SCSC_SERVICE_ID_CLK20MHZ = 7,
|
||
SCSC_SERVICE_ID_INVALID = 0xff,
|
||
};
|
||
|
||
enum scsc_module_client_reason {
|
||
SCSC_MODULE_CLIENT_REASON_HW_PROBE = 0,
|
||
SCSC_MODULE_CLIENT_REASON_HW_REMOVE = 1,
|
||
SCSC_MODULE_CLIENT_REASON_RECOVERY = 2,
|
||
SCSC_MODULE_CLIENT_REASON_INVALID = 0xff,
|
||
};
|
||
|
||
/* Core Driver Module registration */
|
||
|
||
struct scsc_mx_module_client {
|
||
char *name;
|
||
void (*probe)(struct scsc_mx_module_client *module_client, struct scsc_mx *mx, enum scsc_module_client_reason reason);
|
||
void (*remove)(struct scsc_mx_module_client *module_client, struct scsc_mx *mx, enum scsc_module_client_reason reason);
|
||
};
|
||
|
||
/* Service Client interface */
|
||
|
||
struct scsc_service_client;
|
||
|
||
struct scsc_service_client {
|
||
/** Called on Maxwell failure. The Client should Stop all SDRAM & MIF
|
||
* Mailbox access as fast as possible and inform the Manager by calling
|
||
* client_stopped() */
|
||
void (*stop_on_failure)(struct scsc_service_client *client);
|
||
/** Called when Maxwell failure has handled and the Maxwell has been
|
||
* reset. The Client should assume that any Maxwell resources it held are
|
||
* invalid */
|
||
void (*failure_reset)(struct scsc_service_client *client, u16 scsc_panic_code);
|
||
/* called when AP processor is going into suspend. */
|
||
int (*suspend)(struct scsc_service_client *client);
|
||
/* called when AP processor has resumed */
|
||
int (*resume)(struct scsc_service_client *client);
|
||
};
|
||
|
||
|
||
#define PANIC_RECORD_SIZE 64
|
||
#define PANIC_RECORD_DUMP_BUFFER_SZ 4096
|
||
/* WARNING: THIS IS INTERRUPT CONTEXT!
|
||
* here: some serious warnings about not blocking or doing anything lengthy at all
|
||
*/
|
||
typedef void (*scsc_mifintrbit_handler)(int which_bit, void *data);
|
||
|
||
/*
|
||
* Core Module Inteface
|
||
*/
|
||
int scsc_mx_module_register_client_module(struct scsc_mx_module_client *module_client);
|
||
void scsc_mx_module_unregister_client_module(struct scsc_mx_module_client *module_client);
|
||
int scsc_mx_module_reset(void);
|
||
|
||
/*
|
||
* Core Instance interface
|
||
*/
|
||
/** 1st thing to do is call open and return service managment interface*/
|
||
struct scsc_service *scsc_mx_service_open(struct scsc_mx *mx, enum scsc_service_id id, struct scsc_service_client *client, int *status);
|
||
|
||
/*
|
||
* Service interface
|
||
*/
|
||
/** pass a portable dram reference and returns kernel pointer (basically is dealing with the pointers) */
|
||
void *scsc_mx_service_mif_addr_to_ptr(struct scsc_service *service, scsc_mifram_ref ref);
|
||
void *scsc_mx_service_mif_addr_to_phys(struct scsc_service *service, scsc_mifram_ref ref);
|
||
int scsc_mx_service_mif_ptr_to_addr(struct scsc_service *service, void *mem_ptr, scsc_mifram_ref *ref);
|
||
|
||
int scsc_mx_service_start(struct scsc_service *service, scsc_mifram_ref ref);
|
||
int scsc_mx_service_stop(struct scsc_service *service);
|
||
int scsc_mx_service_close(struct scsc_service *service);
|
||
int scsc_mx_service_mif_dump_registers(struct scsc_service *service);
|
||
int scsc_mx_service_get_abox_shared_mem(struct scsc_service *service, void **data);
|
||
/** Signal a failure detected by the Client. This will trigger the systemwide
|
||
* failure handling procedure: _All_ Clients will be called back via
|
||
* their stop_on_failure() handler as a side-effect. */
|
||
void scsc_mx_service_service_failed(struct scsc_service *service, const char *reason);
|
||
|
||
|
||
/* MEMORY Interface*/
|
||
/** Allocate a contiguous block of SDRAM accessible to Client Driver */
|
||
int scsc_mx_service_mifram_alloc(struct scsc_service *service, size_t nbytes, scsc_mifram_ref *ref, u32 align);
|
||
/** Free a contiguous block of SDRAM */
|
||
void scsc_mx_service_mifram_free(struct scsc_service *service, scsc_mifram_ref ref);
|
||
|
||
/* MBOX Interface */
|
||
/** Allocate n contiguous mailboxes. Outputs index of first mbox, returns FALSE if can’t allocate n contiguous mailboxes. */
|
||
bool scsc_mx_service_alloc_mboxes(struct scsc_service *service, int n, int *first_mbox_index);
|
||
/** Free n contiguous mailboxes. */
|
||
void scsc_service_free_mboxes(struct scsc_service *service, int n, int first_mbox_index);
|
||
|
||
/** Get kernel-space pointer to a mailbox.
|
||
* The pointer can be cached as it is guaranteed not to change between service start & stop.
|
||
**/
|
||
u32 *scsc_mx_service_get_mbox_ptr(struct scsc_service *service, int mbox_index);
|
||
|
||
/* IRQ Interface */
|
||
/* Getters/Setters */
|
||
|
||
/* From R4/M4 */
|
||
int scsc_service_mifintrbit_bit_mask_status_get(struct scsc_service *service);
|
||
int scsc_service_mifintrbit_get(struct scsc_service *service);
|
||
void scsc_service_mifintrbit_bit_clear(struct scsc_service *service, int which_bit);
|
||
void scsc_service_mifintrbit_bit_mask(struct scsc_service *service, int which_bit);
|
||
void scsc_service_mifintrbit_bit_unmask(struct scsc_service *service, int which_bit);
|
||
|
||
/* To R4/M4 */
|
||
enum scsc_mifintr_target {
|
||
SCSC_MIFINTR_TARGET_R4 = 0,
|
||
SCSC_MIFINTR_TARGET_M4 = 1
|
||
};
|
||
|
||
void scsc_service_mifintrbit_bit_set(struct scsc_service *service, int which_bit, enum scsc_mifintr_target dir);
|
||
|
||
/* Register an interrupt handler -TOHOST direction.
|
||
* Function returns the IRQ associated , -EIO if all interrupts have been assigned */
|
||
int scsc_service_mifintrbit_register_tohost(struct scsc_service *service, scsc_mifintrbit_handler handler, void *data);
|
||
/* Unregister an interrupt handler associated with a bit -TOHOST direction */
|
||
int scsc_service_mifintrbit_unregister_tohost(struct scsc_service *service, int which_bit);
|
||
|
||
/* Get an interrupt bit associated with the target (R4/M4) -FROMHOST direction
|
||
* Function returns the IRQ bit associated , -EIO if error */
|
||
int scsc_service_mifintrbit_alloc_fromhost(struct scsc_service *service, enum scsc_mifintr_target dir);
|
||
/* Free an interrupt bit associated with the target (R4/M4) -FROMHOST direction
|
||
* Function returns the 0 if succedes , -EIO if error */
|
||
int scsc_service_mifintrbit_free_fromhost(struct scsc_service *service, int which_bit, enum scsc_mifintr_target dir);
|
||
/*
|
||
* Return a kernel device associated 1:1 with the Maxwell instance.
|
||
* This is published only for the purpose of associating service drivers
|
||
* with a Maxwell instance for logging purposes. Clients should not make
|
||
* any assumptions about the device type. In some configurations this may
|
||
* be the associated host-interface device (AXI/PCIe),
|
||
* but this may change in future.
|
||
*/
|
||
struct device *scsc_service_get_device(struct scsc_service *service);
|
||
|
||
int scsc_service_force_panic(struct scsc_service *service);
|
||
|
||
/* Reads a configuration file into memory.
|
||
*
|
||
* Path is relative to the currently selected firmware configuration
|
||
* subdirectory.
|
||
* Returns pointer to data or NULL if file not found.
|
||
* Call mx140_file_release_conf()to release the memory.
|
||
*/
|
||
int mx140_file_request_conf(struct scsc_mx *mx, const struct firmware **conf, const char *config_path);
|
||
|
||
/* Reads a debug configuration file into memory.
|
||
*
|
||
* Path is relative to the currently selected firmware configuration
|
||
* subdirectory.
|
||
* Returns pointer to data or NULL if file not found.
|
||
* Call mx140_file_release_conf()to release the memory.
|
||
*/
|
||
int mx140_file_request_debug_conf(struct scsc_mx *mx, const struct firmware **conf, const char *config_path);
|
||
|
||
/* Read device configuration file into memory.
|
||
*
|
||
* Path is relative to the device configuration directory.
|
||
* Returns pointer to data or NULL if file not found.
|
||
* Call mx140_file_release_conf() to release the memory.
|
||
* This call is only used for configuration files that are
|
||
* device instance specific (e.g. mac addresses)
|
||
*/
|
||
int mx140_file_request_device_conf(struct scsc_mx *mx, const struct firmware **conf, const char *config_path);
|
||
|
||
/* Release configuration file memory
|
||
*
|
||
* If conf is NULL, has no effect.
|
||
*/
|
||
void mx140_file_release_conf(struct scsc_mx *mx, const struct firmware *conf);
|
||
|
||
/* Read device configuration file into memory.
|
||
*
|
||
* Path is absolute.
|
||
* Returns pointer to data or NULL if file not found.
|
||
* Call mx140_release_file() to release the memory.
|
||
*/
|
||
int mx140_request_file(struct scsc_mx *mx, char *path, const struct firmware **firmp);
|
||
|
||
/* Release configuration file memory allocated with mx140_request_file()
|
||
*
|
||
* If firmp is NULL, has no effect.
|
||
*/
|
||
int mx140_release_file(struct scsc_mx *mx, const struct firmware *firmp);
|
||
|
||
/* 20 MHz clock API.
|
||
* The mx140 device uses a clock that is also required by the USB driver.
|
||
* This API allows the USB/clock driver to inform the mx140 driver that the
|
||
* clock is required and that it must boot and/or keep the clock running.
|
||
*/
|
||
|
||
enum mx140_clk20mhz_status {
|
||
MX140_CLK_SUCCESS = 0, /* Returned successfully */
|
||
MX140_CLK_STARTED, /* mx140 has started the clock */
|
||
MX140_CLK_STOPPED, /* mx140 has stopped the clock */
|
||
MX140_CLK_NOT_STARTED, /* failed to start the clock */
|
||
MX140_CLK_NOT_STOPPED, /* failed to stop the clock */
|
||
MX140_CLK_ASYNC_FAIL, /* mx140 failure, async call */
|
||
};
|
||
|
||
/* Register for 20 MHz clock API callbacks
|
||
*
|
||
* Parameters:
|
||
* client_cb:
|
||
* If client provides non-NULL client_cb, the request is asynchronous and
|
||
* the client will be called back when the clock service is started.
|
||
* If client_cb is NULL, the request is blocking.
|
||
* data:
|
||
* opaque context for the client, and will be passed back in any callback
|
||
*
|
||
* Note it is possible that the callback may be made in the context of the
|
||
* calling request/release function.
|
||
*
|
||
* Returns 0 on success
|
||
*/
|
||
int mx140_clk20mhz_register(void (*client_cb)(void *data, enum mx140_clk20mhz_status event), void *data);
|
||
|
||
/* Unregister for 20 MHz clock API callbacks.
|
||
* After this call is made, the mx140 driver will no longer call back.
|
||
*/
|
||
void mx140_clk20mhz_unregister(void);
|
||
|
||
/* Client request that the clock be available.
|
||
*
|
||
* If a callback was installed via mx140_clk20mhz_register(), the mx140 driver
|
||
* will call back when the clock is available. If no callback was installed,
|
||
* the request is blocking and will return when the clock is running.
|
||
*
|
||
* Returns:
|
||
* mx140_clk20mhz_status if a blocking attempt was made to start the clock,
|
||
* MX140_CLK_SUCCESS if the request will happen asynchronously, or,
|
||
* -ve error code on other error.
|
||
*
|
||
*/
|
||
int mx140_clk20mhz_request(void);
|
||
|
||
/* Client informs that the clock is no longer needed
|
||
*
|
||
* Returns:
|
||
* mx140_clk20mhz_status if a blocking attempt was made to stop the clock,
|
||
* MX140_CLK_SUCCESS if the request will happen asynchronously, or,
|
||
* -ve error code on other error.
|
||
*/
|
||
int mx140_clk20mhz_release(void);
|
||
|
||
/*
|
||
* for set test mode.
|
||
*
|
||
*/
|
||
bool slsi_is_rf_test_mode_enabled(void);
|
||
|
||
int mx140_log_dump(void);
|
||
|
||
/* Shared Data BT-ABOX */
|
||
struct scsc_btabox_data {
|
||
unsigned long btaboxmem_start;
|
||
size_t btaboxmem_size;
|
||
};
|
||
|
||
int mxman_register_firmware_notifier(struct notifier_block *nb);
|
||
int mxman_unregister_firmware_notifier(struct notifier_block *nb);
|
||
void mxman_get_fw_version(char *version, size_t ver_sz);
|
||
void mxman_get_driver_version(char *version, size_t ver_sz);
|
||
|
||
#endif
|