1 /*****************************************************************************
3 (c) Cambridge Silicon Radio Limited 2011
4 All rights reserved and confidential information of CSR
6 Refer to LICENSE.txt included with this source for details
9 *****************************************************************************/
11 #ifndef CSR_WIFI_HIP_CHIPHELPER_H__
12 #define CSR_WIFI_HIP_CHIPHELPER_H__
15 #include <linux/types.h>
21 /* The age of the BlueCore chip. This is probably not useful, if
22 you know the age then you can probably work out the version directly. */
23 enum chip_helper_bluecore_age
25 chip_helper_bluecore_pre_bc7,
26 chip_helper_bluecore_bc7_or_later
29 /* We support up to three windowed regions at the moment.
30 Don't reorder these - they're used to index into an array. */
31 enum chip_helper_window_index
33 CHIP_HELPER_WINDOW_1 = 0,
34 CHIP_HELPER_WINDOW_2 = 1,
35 CHIP_HELPER_WINDOW_3 = 2,
36 CHIP_HELPER_WINDOW_COUNT = 3
39 /* These are the things that we can access through a window.
40 Don't reorder these - they're used to index into an array. */
41 enum chip_helper_window_type
43 CHIP_HELPER_WT_CODE_RAM = 0,
44 CHIP_HELPER_WT_FLASH = 1,
45 CHIP_HELPER_WT_EXT_SRAM = 2,
46 CHIP_HELPER_WT_ROM = 3,
47 CHIP_HELPER_WT_SHARED = 4,
48 CHIP_HELPER_WT_COUNT = 5
51 /* Commands to stop and start the XAP */
52 enum chip_helper_dbg_emu_cmd_enum
54 CHIP_HELPER_DBG_EMU_CMD_XAP_STEP_MASK = 0x0001,
55 CHIP_HELPER_DBG_EMU_CMD_XAP_RUN_B_MASK = 0x0002,
56 CHIP_HELPER_DBG_EMU_CMD_XAP_BRK_MASK = 0x0004,
57 CHIP_HELPER_DBG_EMU_CMD_XAP_WAKEUP_MASK = 0x0008
60 /* Bitmasks for Stop and sleep status: DBG_SPI_STOP_STATUS & DBG_HOST_STOP_STATUS */
61 enum chip_helper_dbg_stop_status_enum
63 CHIP_HELPER_DBG_STOP_STATUS_NONE_MASK = 0x0000,
64 CHIP_HELPER_DBG_STOP_STATUS_P0_MASK = 0x0001,
65 CHIP_HELPER_DBG_STOP_STATUS_P1_MASK = 0x0002,
66 CHIP_HELPER_DBG_STOP_STATUS_P2_MASK = 0x0004,
67 CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P0_MASK = 0x0008,
68 CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P1_MASK = 0x0010,
69 CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P2_MASK = 0x0020,
70 /* Legacy names/alias */
71 CHIP_HELPER_DBG_STOP_STATUS_MAC_MASK = 0x0001,
72 CHIP_HELPER_DBG_STOP_STATUS_PHY_MASK = 0x0002,
73 CHIP_HELPER_DBG_STOP_STATUS_BT_MASK = 0x0004,
74 CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_MAC_MASK = 0x0008,
75 CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_PHY_MASK = 0x0010,
76 CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_BT_MASK = 0x0020
79 /* Codes to disable the watchdog */
80 enum chip_helper_watchdog_disable_enum
82 CHIP_HELPER_WATCHDOG_DISABLE_CODE1 = 0x6734,
83 CHIP_HELPER_WATCHDOG_DISABLE_CODE2 = 0xD6BF,
84 CHIP_HELPER_WATCHDOG_DISABLE_CODE3 = 0xC31E
87 /* Other bits have changed between versions */
88 enum chip_helper_gbl_misc_enum
90 CHIP_HELPER_GBL_MISC_SPI_STOP_OUT_EN_MASK = 0x0001,
91 CHIP_HELPER_GBL_MISC_MMU_INIT_DONE_MASK = 0x0004
94 /* Coex status register, contains interrupt status and reset pullup status.
95 * CHIP_HELPER_COEX_STATUS_RST_PULLS_MSB_MASK can be used to check
96 * for WAPI on R03 chips and later. */
97 enum chip_helper_coex_status_mask_enum
99 CHIP_HELPER_COEX_STATUS_RST_PULLS_LSB_MASK = 0x0001,
100 CHIP_HELPER_COEX_STATUS_RST_PULLS_MSB_MASK = 0x0008,
101 CHIP_HELPER_COEX_STATUS_WL_FEC_PINS_LSB_MASK = 0x0010,
102 CHIP_HELPER_COEX_STATUS_WL_FEC_PINS_MSB_MASK = 0x0080,
103 CHIP_HELPER_COEX_STATUS_INT_UART_MASK = 0x0100,
104 CHIP_HELPER_COEX_STATUS_INT_BT_LEG_MASK = 0x0200
107 /* How to select the different CPUs */
108 enum chip_helper_dbg_proc_sel_enum
110 CHIP_HELPER_DBG_PROC_SEL_MAC = 0,
111 CHIP_HELPER_DBG_PROC_SEL_PHY = 1,
112 CHIP_HELPER_DBG_PROC_SEL_BT = 2,
113 CHIP_HELPER_DBG_PROC_SEL_NONE = 2,
114 CHIP_HELPER_DBG_PROC_SEL_BOTH = 3
117 /* These are the only registers that we have to know the
118 address of before we know the chip version. */
119 enum chip_helper_fixed_registers
121 /* This is the address of GBL_CHIP_VERISON on BC7,
123 anything later than that. */
124 CHIP_HELPER_UNIFI_GBL_CHIP_VERSION = 0xFE81,
126 CHIP_HELPER_OLD_BLUECORE_GBL_CHIP_VERSION = 0xFF9A
128 /* This isn't used at the moment (but might be needed
129 to distinguish the BlueCore sub version?) */
130 /* CHIP_HELPER_OLD_BLUECORE_ANA_VERSION_ID = 0xFF7D */
133 /* Address-value pairs for defining initialisation values */
134 struct chip_helper_init_values
140 /* A block of data that should be written to the device */
141 struct chip_helper_reset_values
153 typedef const struct chip_device_desc_t ChipDescript;
155 /* Return a NULL descriptor */
156 ChipDescript* ChipHelper_Null(void);
158 /* This should get the correct version for any CSR chip.
159 The two parameters are what is read from addresses
160 0xFF9A and 0xFE81 (OLD_BLUECORE_GBL_CHIP_VERSION and
161 UNIFI_GBL_CHIP_VERSION). These should give a unique identity
162 for most (all?) chips.
164 FF9A is the old GBL_CHIP_VERSION register. If the high
165 eight bits are zero then the chip is a new (BC7 +) one
166 and FE81 is the _new_ GBL_CHIP_VERSION register. */
167 ChipDescript* ChipHelper_GetVersionAny(u16 from_FF9A, u16 from_FE81);
169 /* The chip is a UniFi, but we don't know which type
170 The parameter is the value of UNIFI_GBL_CHIP_VERSION (0xFE81) */
171 ChipDescript* ChipHelper_GetVersionUniFi(u16 version);
173 /* This gets the version from the SDIO device id. This only
174 gives quite a coarse grained version, so we should update once
175 we hav access to the function N registers. */
176 ChipDescript* ChipHelper_GetVersionSdio(u8 sdio_version);
178 /* The chip is some sort of BlueCore. If "age" is "pre_bc7" then
179 "version" is what was read from FF9A. If "age" is bc7_or_later
180 then "version" is read from FE81. If we don't know if we're pre
181 or post BC7 then we should use "GetVersionAny". */
182 ChipDescript* ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age age,
185 /* The main functions of this class are built with an X macro. This
186 means we can generate the C and C++ versions from the same source
187 without the two diverging.
189 The DEF0 functions are simple and take no parameters. The first
190 parameter to the macro is the return type. The second parameter
191 is the function name and the third parameter is where to get the
192 info from (this is hidden from the user).
194 The DEF1 functions take one parameter. This time the third macro
195 parameter is the type of this parameter, and the fourth macro
196 parameter is the name of the parameter. The bodies of these
197 functions are hand written. */
198 #define CHIP_HELPER_LIST(m) \
199 CHIP_HELPER_DEF0(m, (const char *, FriendlyName, friendly_name)) \
200 CHIP_HELPER_DEF0(m, (const char *, MarketingName, marketing_name)) \
201 CHIP_HELPER_DEF0(m, (u16, DBG_EMU_CMD, regs->dbg_emu_cmd)) \
202 CHIP_HELPER_DEF0(m, (u16, DBG_HOST_PROC_SELECT, regs->host.dbg_proc_select)) \
203 CHIP_HELPER_DEF0(m, (u16, DBG_HOST_STOP_STATUS, regs->host.dbg_stop_status)) \
204 CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW1_PAGE, regs->host.window1_page)) \
205 CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW2_PAGE, regs->host.window2_page)) \
206 CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW3_PAGE, regs->host.window3_page)) \
207 CHIP_HELPER_DEF0(m, (u16, HOST_IO_LOG_ADDR, regs->host.io_log_addr)) \
208 CHIP_HELPER_DEF0(m, (u16, DBG_SPI_PROC_SELECT, regs->spi.dbg_proc_select)) \
209 CHIP_HELPER_DEF0(m, (u16, DBG_SPI_STOP_STATUS, regs->spi.dbg_stop_status)) \
210 CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW1_PAGE, regs->spi.window1_page)) \
211 CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW2_PAGE, regs->spi.window2_page)) \
212 CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW3_PAGE, regs->spi.window3_page)) \
213 CHIP_HELPER_DEF0(m, (u16, SPI_IO_LOG_ADDR, regs->spi.io_log_addr)) \
214 CHIP_HELPER_DEF0(m, (u16, DBG_RESET, regs->dbg_reset)) \
215 CHIP_HELPER_DEF0(m, (u16, DBG_RESET_VALUE, regs->dbg_reset_value)) \
216 CHIP_HELPER_DEF0(m, (u16, DBG_RESET_WARN, regs->dbg_reset_warn)) \
217 CHIP_HELPER_DEF0(m, (u16, DBG_RESET_WARN_VALUE, regs->dbg_reset_warn_value)) \
218 CHIP_HELPER_DEF0(m, (u16, DBG_RESET_RESULT, regs->dbg_reset_result)) \
219 CHIP_HELPER_DEF0(m, (u16, WATCHDOG_DISABLE, regs->watchdog_disable)) \
220 CHIP_HELPER_DEF0(m, (u16, PROC_PC_SNOOP, regs->proc_pc_snoop)) \
221 CHIP_HELPER_DEF0(m, (u16, GBL_CHIP_VERSION, regs->gbl_chip_version)) \
222 CHIP_HELPER_DEF0(m, (u16, GBL_MISC_ENABLES, regs->gbl_misc_enables)) \
223 CHIP_HELPER_DEF0(m, (u16, XAP_PCH, regs->xap_pch)) \
224 CHIP_HELPER_DEF0(m, (u16, XAP_PCL, regs->xap_pcl)) \
225 CHIP_HELPER_DEF0(m, (u16, MAILBOX0, regs->mailbox0)) \
226 CHIP_HELPER_DEF0(m, (u16, MAILBOX1, regs->mailbox1)) \
227 CHIP_HELPER_DEF0(m, (u16, MAILBOX2, regs->mailbox2)) \
228 CHIP_HELPER_DEF0(m, (u16, MAILBOX3, regs->mailbox3)) \
229 CHIP_HELPER_DEF0(m, (u16, SDIO_HIP_HANDSHAKE, regs->sdio_hip_handshake)) \
230 CHIP_HELPER_DEF0(m, (u16, SDIO_HOST_INT, regs->sdio_host_int)) \
231 CHIP_HELPER_DEF0(m, (u16, COEX_STATUS, regs->coex_status)) \
232 CHIP_HELPER_DEF0(m, (u16, SHARED_IO_INTERRUPT, regs->shared_io_interrupt)) \
233 CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_RAM_OFFSET, prog_offset.ram)) \
234 CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_ROM_OFFSET, prog_offset.rom)) \
235 CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_FLASH_OFFSET, prog_offset.flash)) \
236 CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_EXT_SRAM_OFFSET, prog_offset.ext_sram)) \
237 CHIP_HELPER_DEF0(m, (u16, DATA_MEMORY_RAM_OFFSET, data_offset.ram)) \
238 CHIP_HELPER_DEF0(m, (s32, HasFlash, bools.has_flash)) \
239 CHIP_HELPER_DEF0(m, (s32, HasExtSram, bools.has_ext_sram)) \
240 CHIP_HELPER_DEF0(m, (s32, HasRom, bools.has_rom)) \
241 CHIP_HELPER_DEF0(m, (s32, HasBt, bools.has_bt)) \
242 CHIP_HELPER_DEF0(m, (s32, HasWLan, bools.has_wlan)) \
243 CHIP_HELPER_DEF1(m, (u16, WINDOW_ADDRESS, enum chip_helper_window_index, window)) \
244 CHIP_HELPER_DEF1(m, (u16, WINDOW_SIZE, enum chip_helper_window_index, window)) \
245 CHIP_HELPER_DEF1(m, (u16, MapAddress_SPI2HOST, u16, addr)) \
246 CHIP_HELPER_DEF1(m, (u16, MapAddress_HOST2SPI, u16, addr)) \
247 CHIP_HELPER_DEF1(m, (u32, ClockStartupSequence, const struct chip_helper_init_values **, val)) \
248 CHIP_HELPER_DEF1(m, (u32, HostResetSequence, const struct chip_helper_reset_values **, val))
250 /* Some magic to help the expansion */
251 #define CHIP_HELPER_DEF0(a, b) \
252 CHIP_HELPER_DEF0_ ## a b
253 #define CHIP_HELPER_DEF1(a, b) \
254 CHIP_HELPER_DEF1_ ## a b
256 /* Macros so that when we expand the list we get "C" function prototypes. */
257 #define CHIP_HELPER_DEF0_C_DEC(ret_type, name, info) \
258 ret_type ChipHelper_ ## name(ChipDescript * chip_help);
259 #define CHIP_HELPER_DEF1_C_DEC(ret_type, name, type1, name1) \
260 ret_type ChipHelper_ ## name(ChipDescript * chip_help, type1 name1);
262 CHIP_HELPER_LIST(C_DEC)
267 These two functions return human readable strings that describe
268 the chip. FriendlyName returns something that a software engineer
269 at CSR might understand. MarketingName returns something more like
270 an external name for a CSR chip.
279 These registers are used to control the XAPs.
281 /* DBG_HOST_PROC_SELECT DBG_HOST_STOP_STATUS
282 HOST_WINDOW1_PAGE HOST_WINDOW2_PAGE HOST_WINDOW3_PAGE
284 DBG_SPI_PROC_SELECT DBG_SPI_STOP_STATUS
285 SPI_WINDOW1_PAGE SPI_WINDOW2_PAGE SPI_WINDOW3_PAGE
288 These register are used to control the XAPs and the memory
289 windows, normally while debugging the code on chip. There
290 are two versons of these registers, one for access via SPI
291 and another for access via the host interface.
299 These registers are used to reset the XAP. This can be
300 quite complex for some chips. If DBG_RESET_WARN is non
301 zero the DBG_RESET_WARN_VALUE should be written to address
302 DBG_RESET_WARN before the reset is perfeormed. DBG_RESET_VALUE
303 should then be written to DBG_RESET to make the reset happen.
304 The DBG_RESET_RESULT register should contain 0 if the reset
309 This register controls some special chip features. It
310 should be used with care is it changes quite a lot between
318 The mailbox registers are for communication between the host
319 and the firmware. There use is described in part by the host
320 interface protcol specifcation.
322 /* SDIO_HIP_HANDSHAKE
324 This is one of the more important SDIO HIP registers. On some
325 chips it has the same value as one of the mailbox registers
326 and on other chips it is different.
331 These registers are used by some versions of the host interface
332 protocol specification. Their names should probably be changed
333 to hide the registers and to expose the functions more.
337 Coex status register, contains interrupt status and reset
338 pullup status. The latter is used to detect WAPI.
340 /* PROGRAM_MEMORY_RAM_OFFSET
341 PROGRAM_MEMORY_ROM_OFFSET
342 PROGRAM_MEMORY_FLASH_OFFSET
343 PROGRAM_MEMORY_EXT_SRAM_OFFSET
344 DATA_MEMORY_RAM_OFFSET
346 These are constants that describe the offset of the different
347 memory types in the two different address spaces.
349 /* HasFlash HasExtSram HasRom
352 These are a set of bools describing the chip.
354 /* WINDOW_ADDRESS WINDOW_SIZE
356 These two functions return the size and address of the windows.
357 The address is the address of the lowest value in the address
358 map that is part of the window and the size is the number of
361 Some of the windows have thier lowest portion covered by
362 registers. For these windows address is the first address
363 after the registers and size is the siave excluding the part
364 covered by registers.
366 /* MapAddress_SPI2HOST
369 The debugging interface is duplicated on UniFi and later chips
370 so that there are two versions - one over the SPI interaface and
371 the other over the SDIO interface. These functions map the
372 registers between these two interfaces.
374 /* ClockStartupSequence
376 This function returns the list of register value pairs that
377 should be forced into UniFi to enable SPI communication. This
378 set of registers is not needed if the firmware is running, but
379 will be needed if the device is being booted from cold. These
380 register writes enable the clocks and setup the PLL to a basic
381 working state. SPI access might be unreliable until these writes
382 have occured (And they may take mulitple goes).
386 This returns a number of chunks of data and generic pointers.
387 All of the XAPs should be stopped. The data should be written
388 to the generic pointers. The instruction pointer for the MAC
389 should then be set to the start of program memory and then the
390 MAC should be "go"d. This will reset the chip in a reliable
391 and orderly manner without resetting the SDIO interface. It
392 is therefore not needed if the chip is being accessed by the
393 SPI interface (the DBG_RESET_ mechanism can be used instead).
396 /* The Decode Window function is more complex. For the window
397 'window' it tries to return the address and page register
398 value needed to see offset 'offset' of memory type 'type'.
400 It return 1 on success and 0 on failure. 'page' is what
401 should be written to the page register. 'addr' is the
402 address in the XAPs 16 address map to read from. 'len'
403 is the length that we can read without having to change
404 the page registers. */
405 s32 ChipHelper_DecodeWindow(ChipDescript *chip_help,
406 enum chip_helper_window_index window,
407 enum chip_helper_window_type type,
409 u16 *page, u16 *addr, u32 *len);
412 /* Close the extern "C" */
416 * This is the C++ API.
422 /* If this constructor is used then a GetVersionXXX function
423 should be called next. */
426 /* copy constructor */
427 ChipHelper(ChipDescript * desc);
429 /* The default constructor assume a BC7 / UF105x series chip
430 and that the number given is the value of UNIFI_GBL_CHIP_VERSION
432 ChipHelper(u16 version);
434 /* This returns the C interface magic token from a C++ instance. */
435 ChipDescript* GetDescript() const
441 /* Clear out theis class (set it to the null token). */
444 /* Load this class with data for a specific chip. */
445 void GetVersionAny(u16 from_FF9A, u16 from_FE81);
446 void GetVersionUniFi(u16 version);
447 void GetVersionBlueCore(chip_helper_bluecore_age age, u16 version);
448 void GetVersionSdio(u8 sdio_version);
450 /* Helpers to build the definitions of the member functions. */
451 #define CHIP_HELPER_DEF0_CPP_DEC(ret_type, name, info) \
452 ret_type name() const;
453 #define CHIP_HELPER_DEF1_CPP_DEC(ret_type, name, type1, name1) \
454 ret_type name(type1 name1) const;
456 CHIP_HELPER_LIST(CPP_DEC)
459 /* The DecodeWindow function, see the description of the C version. */
460 s32 DecodeWindow(chip_helper_window_index window,
461 chip_helper_window_type type,
463 u16 &page, u16 &addr, u32 &len) const;
466 ChipDescript *m_desc;
469 #endif /* __cplusplus */