summaryrefslogtreecommitdiffstats
path: root/drivers/staging/csr/csr_wifi_hip_chiphelper.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/csr/csr_wifi_hip_chiphelper.h')
-rw-r--r--drivers/staging/csr/csr_wifi_hip_chiphelper.h471
1 files changed, 471 insertions, 0 deletions
diff --git a/drivers/staging/csr/csr_wifi_hip_chiphelper.h b/drivers/staging/csr/csr_wifi_hip_chiphelper.h
new file mode 100644
index 000000000000..24737ae8a2de
--- /dev/null
+++ b/drivers/staging/csr/csr_wifi_hip_chiphelper.h
@@ -0,0 +1,471 @@
+/*****************************************************************************
+
+ (c) Cambridge Silicon Radio Limited 2011
+ All rights reserved and confidential information of CSR
+
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
+
+*****************************************************************************/
+
+#ifndef CSR_WIFI_HIP_CHIPHELPER_H__
+#define CSR_WIFI_HIP_CHIPHELPER_H__
+
+
+#include <linux/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The age of the BlueCore chip. This is probably not useful, if
+ you know the age then you can probably work out the version directly. */
+enum chip_helper_bluecore_age
+{
+ chip_helper_bluecore_pre_bc7,
+ chip_helper_bluecore_bc7_or_later
+};
+
+/* We support up to three windowed regions at the moment.
+ Don't reorder these - they're used to index into an array. */
+enum chip_helper_window_index
+{
+ CHIP_HELPER_WINDOW_1 = 0,
+ CHIP_HELPER_WINDOW_2 = 1,
+ CHIP_HELPER_WINDOW_3 = 2,
+ CHIP_HELPER_WINDOW_COUNT = 3
+};
+
+/* These are the things that we can access through a window.
+ Don't reorder these - they're used to index into an array. */
+enum chip_helper_window_type
+{
+ CHIP_HELPER_WT_CODE_RAM = 0,
+ CHIP_HELPER_WT_FLASH = 1,
+ CHIP_HELPER_WT_EXT_SRAM = 2,
+ CHIP_HELPER_WT_ROM = 3,
+ CHIP_HELPER_WT_SHARED = 4,
+ CHIP_HELPER_WT_COUNT = 5
+};
+
+/* Commands to stop and start the XAP */
+enum chip_helper_dbg_emu_cmd_enum
+{
+ CHIP_HELPER_DBG_EMU_CMD_XAP_STEP_MASK = 0x0001,
+ CHIP_HELPER_DBG_EMU_CMD_XAP_RUN_B_MASK = 0x0002,
+ CHIP_HELPER_DBG_EMU_CMD_XAP_BRK_MASK = 0x0004,
+ CHIP_HELPER_DBG_EMU_CMD_XAP_WAKEUP_MASK = 0x0008
+};
+
+/* Bitmasks for Stop and sleep status: DBG_SPI_STOP_STATUS & DBG_HOST_STOP_STATUS */
+enum chip_helper_dbg_stop_status_enum
+{
+ CHIP_HELPER_DBG_STOP_STATUS_NONE_MASK = 0x0000,
+ CHIP_HELPER_DBG_STOP_STATUS_P0_MASK = 0x0001,
+ CHIP_HELPER_DBG_STOP_STATUS_P1_MASK = 0x0002,
+ CHIP_HELPER_DBG_STOP_STATUS_P2_MASK = 0x0004,
+ CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P0_MASK = 0x0008,
+ CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P1_MASK = 0x0010,
+ CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P2_MASK = 0x0020,
+ /* Legacy names/alias */
+ CHIP_HELPER_DBG_STOP_STATUS_MAC_MASK = 0x0001,
+ CHIP_HELPER_DBG_STOP_STATUS_PHY_MASK = 0x0002,
+ CHIP_HELPER_DBG_STOP_STATUS_BT_MASK = 0x0004,
+ CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_MAC_MASK = 0x0008,
+ CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_PHY_MASK = 0x0010,
+ CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_BT_MASK = 0x0020
+};
+
+/* Codes to disable the watchdog */
+enum chip_helper_watchdog_disable_enum
+{
+ CHIP_HELPER_WATCHDOG_DISABLE_CODE1 = 0x6734,
+ CHIP_HELPER_WATCHDOG_DISABLE_CODE2 = 0xD6BF,
+ CHIP_HELPER_WATCHDOG_DISABLE_CODE3 = 0xC31E
+};
+
+/* Other bits have changed between versions */
+enum chip_helper_gbl_misc_enum
+{
+ CHIP_HELPER_GBL_MISC_SPI_STOP_OUT_EN_MASK = 0x0001,
+ CHIP_HELPER_GBL_MISC_MMU_INIT_DONE_MASK = 0x0004
+};
+
+/* Coex status register, contains interrupt status and reset pullup status.
+ * CHIP_HELPER_COEX_STATUS_RST_PULLS_MSB_MASK can be used to check
+ * for WAPI on R03 chips and later. */
+enum chip_helper_coex_status_mask_enum
+{
+ CHIP_HELPER_COEX_STATUS_RST_PULLS_LSB_MASK = 0x0001,
+ CHIP_HELPER_COEX_STATUS_RST_PULLS_MSB_MASK = 0x0008,
+ CHIP_HELPER_COEX_STATUS_WL_FEC_PINS_LSB_MASK = 0x0010,
+ CHIP_HELPER_COEX_STATUS_WL_FEC_PINS_MSB_MASK = 0x0080,
+ CHIP_HELPER_COEX_STATUS_INT_UART_MASK = 0x0100,
+ CHIP_HELPER_COEX_STATUS_INT_BT_LEG_MASK = 0x0200
+};
+
+/* How to select the different CPUs */
+enum chip_helper_dbg_proc_sel_enum
+{
+ CHIP_HELPER_DBG_PROC_SEL_MAC = 0,
+ CHIP_HELPER_DBG_PROC_SEL_PHY = 1,
+ CHIP_HELPER_DBG_PROC_SEL_BT = 2,
+ CHIP_HELPER_DBG_PROC_SEL_NONE = 2,
+ CHIP_HELPER_DBG_PROC_SEL_BOTH = 3
+};
+
+/* These are the only registers that we have to know the
+ address of before we know the chip version. */
+enum chip_helper_fixed_registers
+{
+ /* This is the address of GBL_CHIP_VERISON on BC7,
+ UF105x, UF60xx and
+ anything later than that. */
+ CHIP_HELPER_UNIFI_GBL_CHIP_VERSION = 0xFE81,
+
+ CHIP_HELPER_OLD_BLUECORE_GBL_CHIP_VERSION = 0xFF9A
+
+ /* This isn't used at the moment (but might be needed
+ to distinguish the BlueCore sub version?) */
+ /* CHIP_HELPER_OLD_BLUECORE_ANA_VERSION_ID = 0xFF7D */
+};
+
+/* Address-value pairs for defining initialisation values */
+struct chip_helper_init_values
+{
+ u16 addr;
+ u16 value;
+};
+
+/* A block of data that should be written to the device */
+struct chip_helper_reset_values
+{
+ u32 gp_address;
+ u32 len;
+ const u16 *data;
+};
+
+/*
+ * This is the C API.
+ */
+
+/* opaque type */
+typedef const struct chip_device_desc_t ChipDescript;
+
+/* Return a NULL descriptor */
+ChipDescript* ChipHelper_Null(void);
+
+/* This should get the correct version for any CSR chip.
+ The two parameters are what is read from addresses
+ 0xFF9A and 0xFE81 (OLD_BLUECORE_GBL_CHIP_VERSION and
+ UNIFI_GBL_CHIP_VERSION). These should give a unique identity
+ for most (all?) chips.
+
+ FF9A is the old GBL_CHIP_VERSION register. If the high
+ eight bits are zero then the chip is a new (BC7 +) one
+ and FE81 is the _new_ GBL_CHIP_VERSION register. */
+ChipDescript* ChipHelper_GetVersionAny(u16 from_FF9A, u16 from_FE81);
+
+/* The chip is a UniFi, but we don't know which type
+ The parameter is the value of UNIFI_GBL_CHIP_VERSION (0xFE81) */
+ChipDescript* ChipHelper_GetVersionUniFi(u16 version);
+
+/* This gets the version from the SDIO device id. This only
+ gives quite a coarse grained version, so we should update once
+ we hav access to the function N registers. */
+ChipDescript* ChipHelper_GetVersionSdio(u8 sdio_version);
+
+/* The chip is some sort of BlueCore. If "age" is "pre_bc7" then
+ "version" is what was read from FF9A. If "age" is bc7_or_later
+ then "version" is read from FE81. If we don't know if we're pre
+ or post BC7 then we should use "GetVersionAny". */
+ChipDescript* ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age age,
+ u16 version);
+
+/* The main functions of this class are built with an X macro. This
+ means we can generate the C and C++ versions from the same source
+ without the two diverging.
+
+ The DEF0 functions are simple and take no parameters. The first
+ parameter to the macro is the return type. The second parameter
+ is the function name and the third parameter is where to get the
+ info from (this is hidden from the user).
+
+ The DEF1 functions take one parameter. This time the third macro
+ parameter is the type of this parameter, and the fourth macro
+ parameter is the name of the parameter. The bodies of these
+ functions are hand written. */
+#define CHIP_HELPER_LIST(m) \
+ CHIP_HELPER_DEF0(m, (const char *, FriendlyName, friendly_name)) \
+ CHIP_HELPER_DEF0(m, (const char *, MarketingName, marketing_name)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_EMU_CMD, regs->dbg_emu_cmd)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_HOST_PROC_SELECT, regs->host.dbg_proc_select)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_HOST_STOP_STATUS, regs->host.dbg_stop_status)) \
+ CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW1_PAGE, regs->host.window1_page)) \
+ CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW2_PAGE, regs->host.window2_page)) \
+ CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW3_PAGE, regs->host.window3_page)) \
+ CHIP_HELPER_DEF0(m, (u16, HOST_IO_LOG_ADDR, regs->host.io_log_addr)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_SPI_PROC_SELECT, regs->spi.dbg_proc_select)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_SPI_STOP_STATUS, regs->spi.dbg_stop_status)) \
+ CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW1_PAGE, regs->spi.window1_page)) \
+ CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW2_PAGE, regs->spi.window2_page)) \
+ CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW3_PAGE, regs->spi.window3_page)) \
+ CHIP_HELPER_DEF0(m, (u16, SPI_IO_LOG_ADDR, regs->spi.io_log_addr)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_RESET, regs->dbg_reset)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_RESET_VALUE, regs->dbg_reset_value)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_RESET_WARN, regs->dbg_reset_warn)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_RESET_WARN_VALUE, regs->dbg_reset_warn_value)) \
+ CHIP_HELPER_DEF0(m, (u16, DBG_RESET_RESULT, regs->dbg_reset_result)) \
+ CHIP_HELPER_DEF0(m, (u16, WATCHDOG_DISABLE, regs->watchdog_disable)) \
+ CHIP_HELPER_DEF0(m, (u16, PROC_PC_SNOOP, regs->proc_pc_snoop)) \
+ CHIP_HELPER_DEF0(m, (u16, GBL_CHIP_VERSION, regs->gbl_chip_version)) \
+ CHIP_HELPER_DEF0(m, (u16, GBL_MISC_ENABLES, regs->gbl_misc_enables)) \
+ CHIP_HELPER_DEF0(m, (u16, XAP_PCH, regs->xap_pch)) \
+ CHIP_HELPER_DEF0(m, (u16, XAP_PCL, regs->xap_pcl)) \
+ CHIP_HELPER_DEF0(m, (u16, MAILBOX0, regs->mailbox0)) \
+ CHIP_HELPER_DEF0(m, (u16, MAILBOX1, regs->mailbox1)) \
+ CHIP_HELPER_DEF0(m, (u16, MAILBOX2, regs->mailbox2)) \
+ CHIP_HELPER_DEF0(m, (u16, MAILBOX3, regs->mailbox3)) \
+ CHIP_HELPER_DEF0(m, (u16, SDIO_HIP_HANDSHAKE, regs->sdio_hip_handshake)) \
+ CHIP_HELPER_DEF0(m, (u16, SDIO_HOST_INT, regs->sdio_host_int)) \
+ CHIP_HELPER_DEF0(m, (u16, COEX_STATUS, regs->coex_status)) \
+ CHIP_HELPER_DEF0(m, (u16, SHARED_IO_INTERRUPT, regs->shared_io_interrupt)) \
+ CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_RAM_OFFSET, prog_offset.ram)) \
+ CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_ROM_OFFSET, prog_offset.rom)) \
+ CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_FLASH_OFFSET, prog_offset.flash)) \
+ CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_EXT_SRAM_OFFSET, prog_offset.ext_sram)) \
+ CHIP_HELPER_DEF0(m, (u16, DATA_MEMORY_RAM_OFFSET, data_offset.ram)) \
+ CHIP_HELPER_DEF0(m, (s32, HasFlash, bools.has_flash)) \
+ CHIP_HELPER_DEF0(m, (s32, HasExtSram, bools.has_ext_sram)) \
+ CHIP_HELPER_DEF0(m, (s32, HasRom, bools.has_rom)) \
+ CHIP_HELPER_DEF0(m, (s32, HasBt, bools.has_bt)) \
+ CHIP_HELPER_DEF0(m, (s32, HasWLan, bools.has_wlan)) \
+ CHIP_HELPER_DEF1(m, (u16, WINDOW_ADDRESS, enum chip_helper_window_index, window)) \
+ CHIP_HELPER_DEF1(m, (u16, WINDOW_SIZE, enum chip_helper_window_index, window)) \
+ CHIP_HELPER_DEF1(m, (u16, MapAddress_SPI2HOST, u16, addr)) \
+ CHIP_HELPER_DEF1(m, (u16, MapAddress_HOST2SPI, u16, addr)) \
+ CHIP_HELPER_DEF1(m, (u32, ClockStartupSequence, const struct chip_helper_init_values **, val)) \
+ CHIP_HELPER_DEF1(m, (u32, HostResetSequence, const struct chip_helper_reset_values **, val))
+
+/* Some magic to help the expansion */
+#define CHIP_HELPER_DEF0(a, b) \
+ CHIP_HELPER_DEF0_ ## a b
+#define CHIP_HELPER_DEF1(a, b) \
+ CHIP_HELPER_DEF1_ ## a b
+
+/* Macros so that when we expand the list we get "C" function prototypes. */
+#define CHIP_HELPER_DEF0_C_DEC(ret_type, name, info) \
+ ret_type ChipHelper_ ## name(ChipDescript * chip_help);
+#define CHIP_HELPER_DEF1_C_DEC(ret_type, name, type1, name1) \
+ ret_type ChipHelper_ ## name(ChipDescript * chip_help, type1 name1);
+
+CHIP_HELPER_LIST(C_DEC)
+
+/* FriendlyName
+ MarketingName
+
+ These two functions return human readable strings that describe
+ the chip. FriendlyName returns something that a software engineer
+ at CSR might understand. MarketingName returns something more like
+ an external name for a CSR chip.
+*/
+/* DBG_EMU_CMD
+ WATCHDOG_DISABLE
+ PROC_PC_SNOOP
+ GBL_CHIP_VERSION
+ XAP_PCH
+ XAP_PCL
+
+ These registers are used to control the XAPs.
+*/
+/* DBG_HOST_PROC_SELECT DBG_HOST_STOP_STATUS
+ HOST_WINDOW1_PAGE HOST_WINDOW2_PAGE HOST_WINDOW3_PAGE
+ HOST_IO_LOG_ADDR
+ DBG_SPI_PROC_SELECT DBG_SPI_STOP_STATUS
+ SPI_WINDOW1_PAGE SPI_WINDOW2_PAGE SPI_WINDOW3_PAGE
+ SPI_IO_LOG_ADDR
+
+ These register are used to control the XAPs and the memory
+ windows, normally while debugging the code on chip. There
+ are two versons of these registers, one for access via SPI
+ and another for access via the host interface.
+*/
+/* DBG_RESET
+ DBG_RESET_VALUE
+ DBG_RESET_WARN
+ DBG_RESET_WARN_VALUE
+ DBG_RESET_RESULT
+
+ These registers are used to reset the XAP. This can be
+ quite complex for some chips. If DBG_RESET_WARN is non
+ zero the DBG_RESET_WARN_VALUE should be written to address
+ DBG_RESET_WARN before the reset is perfeormed. DBG_RESET_VALUE
+ should then be written to DBG_RESET to make the reset happen.
+ The DBG_RESET_RESULT register should contain 0 if the reset
+ was successful.
+*/
+/* GBL_MISC_ENABLES
+
+ This register controls some special chip features. It
+ should be used with care is it changes quite a lot between
+ chip versions.
+*/
+/* MAILBOX0
+ MAILBOX1
+ MAILBOX2
+ MAILBOX3
+
+ The mailbox registers are for communication between the host
+ and the firmware. There use is described in part by the host
+ interface protcol specifcation.
+*/
+/* SDIO_HIP_HANDSHAKE
+
+ This is one of the more important SDIO HIP registers. On some
+ chips it has the same value as one of the mailbox registers
+ and on other chips it is different.
+*/
+/* SDIO_HOST_INT
+ SHARED_IO_INTERRUPT
+
+ These registers are used by some versions of the host interface
+ protocol specification. Their names should probably be changed
+ to hide the registers and to expose the functions more.
+*/
+/* COEX_STATUS
+
+ Coex status register, contains interrupt status and reset
+ pullup status. The latter is used to detect WAPI.
+*/
+/* PROGRAM_MEMORY_RAM_OFFSET
+ PROGRAM_MEMORY_ROM_OFFSET
+ PROGRAM_MEMORY_FLASH_OFFSET
+ PROGRAM_MEMORY_EXT_SRAM_OFFSET
+ DATA_MEMORY_RAM_OFFSET
+
+ These are constants that describe the offset of the different
+ memory types in the two different address spaces.
+*/
+/* HasFlash HasExtSram HasRom
+ HasBt HasWLan
+
+ These are a set of bools describing the chip.
+*/
+/* WINDOW_ADDRESS WINDOW_SIZE
+
+ These two functions return the size and address of the windows.
+ The address is the address of the lowest value in the address
+ map that is part of the window and the size is the number of
+ visible words.
+
+ Some of the windows have thier lowest portion covered by
+ registers. For these windows address is the first address
+ after the registers and size is the siave excluding the part
+ covered by registers.
+*/
+/* MapAddress_SPI2HOST
+ MapAddress_HOST2SPI
+
+ The debugging interface is duplicated on UniFi and later chips
+ so that there are two versions - one over the SPI interaface and
+ the other over the SDIO interface. These functions map the
+ registers between these two interfaces.
+*/
+/* ClockStartupSequence
+
+ This function returns the list of register value pairs that
+ should be forced into UniFi to enable SPI communication. This
+ set of registers is not needed if the firmware is running, but
+ will be needed if the device is being booted from cold. These
+ register writes enable the clocks and setup the PLL to a basic
+ working state. SPI access might be unreliable until these writes
+ have occured (And they may take mulitple goes).
+*/
+/* HostResetSequence
+
+ This returns a number of chunks of data and generic pointers.
+ All of the XAPs should be stopped. The data should be written
+ to the generic pointers. The instruction pointer for the MAC
+ should then be set to the start of program memory and then the
+ MAC should be "go"d. This will reset the chip in a reliable
+ and orderly manner without resetting the SDIO interface. It
+ is therefore not needed if the chip is being accessed by the
+ SPI interface (the DBG_RESET_ mechanism can be used instead).
+*/
+
+/* The Decode Window function is more complex. For the window
+ 'window' it tries to return the address and page register
+ value needed to see offset 'offset' of memory type 'type'.
+
+ It return 1 on success and 0 on failure. 'page' is what
+ should be written to the page register. 'addr' is the
+ address in the XAPs 16 address map to read from. 'len'
+ is the length that we can read without having to change
+ the page registers. */
+s32 ChipHelper_DecodeWindow(ChipDescript *chip_help,
+ enum chip_helper_window_index window,
+ enum chip_helper_window_type type,
+ u32 offset,
+ u16 *page, u16 *addr, u32 *len);
+
+#ifdef __cplusplus
+/* Close the extern "C" */
+}
+
+/*
+ * This is the C++ API.
+ */
+
+class ChipHelper
+{
+public:
+ /* If this constructor is used then a GetVersionXXX function
+ should be called next. */
+ ChipHelper();
+
+ /* copy constructor */
+ ChipHelper(ChipDescript * desc);
+
+ /* The default constructor assume a BC7 / UF105x series chip
+ and that the number given is the value of UNIFI_GBL_CHIP_VERSION
+ (0xFE81) */
+ ChipHelper(u16 version);
+
+ /* This returns the C interface magic token from a C++ instance. */
+ ChipDescript* GetDescript() const
+ {
+ return m_desc;
+ }
+
+
+ /* Clear out theis class (set it to the null token). */
+ void ClearVersion();
+
+ /* Load this class with data for a specific chip. */
+ void GetVersionAny(u16 from_FF9A, u16 from_FE81);
+ void GetVersionUniFi(u16 version);
+ void GetVersionBlueCore(chip_helper_bluecore_age age, u16 version);
+ void GetVersionSdio(u8 sdio_version);
+
+ /* Helpers to build the definitions of the member functions. */
+#define CHIP_HELPER_DEF0_CPP_DEC(ret_type, name, info) \
+ ret_type name() const;
+#define CHIP_HELPER_DEF1_CPP_DEC(ret_type, name, type1, name1) \
+ ret_type name(type1 name1) const;
+
+ CHIP_HELPER_LIST(CPP_DEC)
+
+
+ /* The DecodeWindow function, see the description of the C version. */
+ s32 DecodeWindow(chip_helper_window_index window,
+ chip_helper_window_type type,
+ u32 offset,
+ u16 &page, u16 &addr, u32 &len) const;
+
+private:
+ ChipDescript *m_desc;
+};
+
+#endif /* __cplusplus */
+
+#endif