2013-06-13 01:52:10 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
2017-12-23 00:31:13 +08:00
|
|
|
* Copyright (c) 2011-2015,2017 Qualcomm Atheros, Inc.
|
2013-06-13 01:52:10 +08:00
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _BMI_H_
|
|
|
|
#define _BMI_H_
|
|
|
|
|
|
|
|
#include "core.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Bootloader Messaging Interface (BMI)
|
|
|
|
*
|
|
|
|
* BMI is a very simple messaging interface used during initialization
|
|
|
|
* to read memory, write memory, execute code, and to define an
|
|
|
|
* application entry PC.
|
|
|
|
*
|
|
|
|
* It is used to download an application to QCA988x, to provide
|
|
|
|
* patches to code that is already resident on QCA988x, and generally
|
|
|
|
* to examine and modify state. The Host has an opportunity to use
|
|
|
|
* BMI only once during bootup. Once the Host issues a BMI_DONE
|
|
|
|
* command, this opportunity ends.
|
|
|
|
*
|
|
|
|
* The Host writes BMI requests to mailbox0, and reads BMI responses
|
|
|
|
* from mailbox0. BMI requests all begin with a command
|
|
|
|
* (see below for specific commands), and are followed by
|
|
|
|
* command-specific data.
|
|
|
|
*
|
|
|
|
* Flow control:
|
|
|
|
* The Host can only issue a command once the Target gives it a
|
|
|
|
* "BMI Command Credit", using AR8K Counter #4. As soon as the
|
|
|
|
* Target has completed a command, it issues another BMI Command
|
|
|
|
* Credit (so the Host can issue the next command).
|
|
|
|
*
|
|
|
|
* BMI handles all required Target-side cache flushing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Maximum data size used for BMI transfers */
|
|
|
|
#define BMI_MAX_DATA_SIZE 256
|
|
|
|
|
|
|
|
/* len = cmd + addr + length */
|
|
|
|
#define BMI_MAX_CMDBUF_SIZE (BMI_MAX_DATA_SIZE + \
|
|
|
|
sizeof(u32) + \
|
|
|
|
sizeof(u32) + \
|
|
|
|
sizeof(u32))
|
|
|
|
|
|
|
|
/* BMI Commands */
|
|
|
|
|
|
|
|
enum bmi_cmd_id {
|
|
|
|
BMI_NO_COMMAND = 0,
|
|
|
|
BMI_DONE = 1,
|
|
|
|
BMI_READ_MEMORY = 2,
|
|
|
|
BMI_WRITE_MEMORY = 3,
|
|
|
|
BMI_EXECUTE = 4,
|
|
|
|
BMI_SET_APP_START = 5,
|
|
|
|
BMI_READ_SOC_REGISTER = 6,
|
|
|
|
BMI_READ_SOC_WORD = 6,
|
|
|
|
BMI_WRITE_SOC_REGISTER = 7,
|
|
|
|
BMI_WRITE_SOC_WORD = 7,
|
|
|
|
BMI_GET_TARGET_ID = 8,
|
|
|
|
BMI_GET_TARGET_INFO = 8,
|
|
|
|
BMI_ROMPATCH_INSTALL = 9,
|
|
|
|
BMI_ROMPATCH_UNINSTALL = 10,
|
|
|
|
BMI_ROMPATCH_ACTIVATE = 11,
|
|
|
|
BMI_ROMPATCH_DEACTIVATE = 12,
|
|
|
|
BMI_LZ_STREAM_START = 13, /* should be followed by LZ_DATA */
|
|
|
|
BMI_LZ_DATA = 14,
|
|
|
|
BMI_NVRAM_PROCESS = 15,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define BMI_NVRAM_SEG_NAME_SZ 16
|
|
|
|
|
2015-10-09 16:55:59 +08:00
|
|
|
#define BMI_PARAM_GET_EEPROM_BOARD_ID 0x10
|
2017-05-31 19:21:27 +08:00
|
|
|
#define BMI_PARAM_GET_FLASH_BOARD_ID 0x8000
|
|
|
|
#define BMI_PARAM_FLASH_SECTION_ALL 0x10000
|
2015-10-09 16:55:59 +08:00
|
|
|
|
ath10k: support extended board data download for dual-band QCA9984
To support dual-band variant of QCA9984, new extended board data (eBDF)
is introduced since existing board data ran out of space.
Below is the brief implementation & design detail,
----------------------------------------------------
1. New OTP changes to inform eBDF support in existing OTP download to
fetch board ID and chip ID. This is backward compatible and older
card sends 0 by default for eBDF support bit (bit 18 of OTP response) we
check in ath10k driver.
2. If eBDF is supported, then we need to fetch eBDF ID which is bundled
in downloaded board data. So again OTP is executed for knowing the eBDF ID.
This is done once we set 'board_data_initialized' bit. If eBDF ID
returned is zero, we continue booting with previous board data downloaded.
3. Based on the eBDF ID fetched, ath10k driver tries to download the
extended board data to a new offset ahead of already downloaded board
data address.
4. A new BD IE type, ATH10K_BD_IE_BOARD_EXT is added to differentiate in
bundling eBDF separately in board-2.bin and also to parse through
board bundle for eBDF download in ath10k boot.
5. If eBDF is not present in the board-2.bin bundle or when board ID is
zero, we do a fallback boot to "eboard.bin" in the same QCA9984/hw1.0 dir.
This is same as done to existing "board.bin" if board ID is not present
in board-2.bin bundle.
Current design is that eBDF size will be 2KB and eBDF ID will be
byte value.
Tested the above changes with dual-band variant of QCA9984 card. OTP
update needed for the test will be part of next FW release 10.4-3.6-xxxx.
Below are the logs with ath10k BOOT debugs enabled.
First OTP response :
---------------------
..
boot upload otp to 0x1234 len 9478 for board id
boot get otp board id result 0x00040400 board_id 1 chip_id 0 ext_bid_support 1
..
Second OTP response :
---------------------
..
boot upload otp to 0x1234 len 9478 for ext board id
boot get otp ext board id result 0x00000005 ext_board_id 5
boot using eboard name 'bus=pci,bmi-chip-id=0,bmi-eboard-id=5'
..
Extended board data download:
------------------------------
..
board name
00000000: 62 75 73 3d 70 63 69 2c 62 6d 69 2d 63 68 69 70 bus=pci,bmi-chip
00000010: 2d 69 64 3d 30 2c 62 6d 69 2d 65 62 6f 61 72 64 -id=0,bmi-eboard
00000020: 2d 69 64 3d 35 -id=5
boot found match for name 'bus=pci,bmi-chip-id=0,bmi-eboard-id=5'
boot found eboard data for 'bus=pci,bmi-chip-id=0,bmi-eboard-id=5'
using board api 2
boot writing ext board data to addr 0xc3000
..
Fallback Extended board data download from "eboard.bin":
---------------------------------------------------------
..
board name
00000000: 62 75 73 3d 70 63 69 2c 62 6d 69 2d 63 68 69 70 bus=pci,bmi-chip
00000010: 2d 69 64 3d 30 2c 62 6d 69 2d 62 6f 61 72 64 2d -id=0,bmi-board-
00000020: 69 64 3d 31 30 id=10
failed to fetch board data for bus=pci,bmi-chip-id=0,bmi-eboard-id=5 from ath10k/QCA9984/hw1.0/board-2.bin
boot fw request 'ath10k/QCA9984/hw1.0/eboard.bin': 0
using board api 1
boot writing ext board data to addr 0xc3000
..
Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-09-04 01:07:53 +08:00
|
|
|
/* Dual-band Extended Board ID */
|
|
|
|
#define BMI_PARAM_GET_EXT_BOARD_ID 0x40000
|
|
|
|
#define ATH10K_BMI_EXT_BOARD_ID_SUPPORT 0x40000
|
|
|
|
|
2015-10-09 16:55:59 +08:00
|
|
|
#define ATH10K_BMI_BOARD_ID_FROM_OTP_MASK 0x7c00
|
|
|
|
#define ATH10K_BMI_BOARD_ID_FROM_OTP_LSB 10
|
|
|
|
|
|
|
|
#define ATH10K_BMI_CHIP_ID_FROM_OTP_MASK 0x18000
|
|
|
|
#define ATH10K_BMI_CHIP_ID_FROM_OTP_LSB 15
|
|
|
|
|
|
|
|
#define ATH10K_BMI_BOARD_ID_STATUS_MASK 0xff
|
ath10k: support extended board data download for dual-band QCA9984
To support dual-band variant of QCA9984, new extended board data (eBDF)
is introduced since existing board data ran out of space.
Below is the brief implementation & design detail,
----------------------------------------------------
1. New OTP changes to inform eBDF support in existing OTP download to
fetch board ID and chip ID. This is backward compatible and older
card sends 0 by default for eBDF support bit (bit 18 of OTP response) we
check in ath10k driver.
2. If eBDF is supported, then we need to fetch eBDF ID which is bundled
in downloaded board data. So again OTP is executed for knowing the eBDF ID.
This is done once we set 'board_data_initialized' bit. If eBDF ID
returned is zero, we continue booting with previous board data downloaded.
3. Based on the eBDF ID fetched, ath10k driver tries to download the
extended board data to a new offset ahead of already downloaded board
data address.
4. A new BD IE type, ATH10K_BD_IE_BOARD_EXT is added to differentiate in
bundling eBDF separately in board-2.bin and also to parse through
board bundle for eBDF download in ath10k boot.
5. If eBDF is not present in the board-2.bin bundle or when board ID is
zero, we do a fallback boot to "eboard.bin" in the same QCA9984/hw1.0 dir.
This is same as done to existing "board.bin" if board ID is not present
in board-2.bin bundle.
Current design is that eBDF size will be 2KB and eBDF ID will be
byte value.
Tested the above changes with dual-band variant of QCA9984 card. OTP
update needed for the test will be part of next FW release 10.4-3.6-xxxx.
Below are the logs with ath10k BOOT debugs enabled.
First OTP response :
---------------------
..
boot upload otp to 0x1234 len 9478 for board id
boot get otp board id result 0x00040400 board_id 1 chip_id 0 ext_bid_support 1
..
Second OTP response :
---------------------
..
boot upload otp to 0x1234 len 9478 for ext board id
boot get otp ext board id result 0x00000005 ext_board_id 5
boot using eboard name 'bus=pci,bmi-chip-id=0,bmi-eboard-id=5'
..
Extended board data download:
------------------------------
..
board name
00000000: 62 75 73 3d 70 63 69 2c 62 6d 69 2d 63 68 69 70 bus=pci,bmi-chip
00000010: 2d 69 64 3d 30 2c 62 6d 69 2d 65 62 6f 61 72 64 -id=0,bmi-eboard
00000020: 2d 69 64 3d 35 -id=5
boot found match for name 'bus=pci,bmi-chip-id=0,bmi-eboard-id=5'
boot found eboard data for 'bus=pci,bmi-chip-id=0,bmi-eboard-id=5'
using board api 2
boot writing ext board data to addr 0xc3000
..
Fallback Extended board data download from "eboard.bin":
---------------------------------------------------------
..
board name
00000000: 62 75 73 3d 70 63 69 2c 62 6d 69 2d 63 68 69 70 bus=pci,bmi-chip
00000010: 2d 69 64 3d 30 2c 62 6d 69 2d 62 6f 61 72 64 2d -id=0,bmi-board-
00000020: 69 64 3d 31 30 id=10
failed to fetch board data for bus=pci,bmi-chip-id=0,bmi-eboard-id=5 from ath10k/QCA9984/hw1.0/board-2.bin
boot fw request 'ath10k/QCA9984/hw1.0/eboard.bin': 0
using board api 1
boot writing ext board data to addr 0xc3000
..
Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-09-04 01:07:53 +08:00
|
|
|
#define ATH10K_BMI_EBOARD_ID_STATUS_MASK 0xff
|
2015-10-09 16:55:59 +08:00
|
|
|
|
2013-06-13 01:52:10 +08:00
|
|
|
struct bmi_cmd {
|
|
|
|
__le32 id; /* enum bmi_cmd_id */
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
} done;
|
|
|
|
struct {
|
|
|
|
__le32 addr;
|
|
|
|
__le32 len;
|
|
|
|
} read_mem;
|
|
|
|
struct {
|
|
|
|
__le32 addr;
|
|
|
|
__le32 len;
|
|
|
|
u8 payload[0];
|
|
|
|
} write_mem;
|
|
|
|
struct {
|
|
|
|
__le32 addr;
|
|
|
|
__le32 param;
|
|
|
|
} execute;
|
|
|
|
struct {
|
|
|
|
__le32 addr;
|
|
|
|
} set_app_start;
|
|
|
|
struct {
|
|
|
|
__le32 addr;
|
|
|
|
} read_soc_reg;
|
|
|
|
struct {
|
|
|
|
__le32 addr;
|
|
|
|
__le32 value;
|
|
|
|
} write_soc_reg;
|
|
|
|
struct {
|
|
|
|
} get_target_info;
|
|
|
|
struct {
|
|
|
|
__le32 rom_addr;
|
|
|
|
__le32 ram_addr; /* or value */
|
|
|
|
__le32 size;
|
|
|
|
__le32 activate; /* 0=install, but dont activate */
|
|
|
|
} rompatch_install;
|
|
|
|
struct {
|
|
|
|
__le32 patch_id;
|
|
|
|
} rompatch_uninstall;
|
|
|
|
struct {
|
|
|
|
__le32 count;
|
|
|
|
__le32 patch_ids[0]; /* length of @count */
|
|
|
|
} rompatch_activate;
|
|
|
|
struct {
|
|
|
|
__le32 count;
|
|
|
|
__le32 patch_ids[0]; /* length of @count */
|
|
|
|
} rompatch_deactivate;
|
|
|
|
struct {
|
|
|
|
__le32 addr;
|
|
|
|
} lz_start;
|
|
|
|
struct {
|
|
|
|
__le32 len; /* max BMI_MAX_DATA_SIZE */
|
|
|
|
u8 payload[0]; /* length of @len */
|
|
|
|
} lz_data;
|
|
|
|
struct {
|
|
|
|
u8 name[BMI_NVRAM_SEG_NAME_SZ];
|
|
|
|
} nvram_process;
|
|
|
|
u8 payload[BMI_MAX_CMDBUF_SIZE];
|
|
|
|
};
|
|
|
|
} __packed;
|
|
|
|
|
|
|
|
union bmi_resp {
|
|
|
|
struct {
|
|
|
|
u8 payload[0];
|
|
|
|
} read_mem;
|
|
|
|
struct {
|
|
|
|
__le32 result;
|
|
|
|
} execute;
|
|
|
|
struct {
|
|
|
|
__le32 value;
|
|
|
|
} read_soc_reg;
|
|
|
|
struct {
|
|
|
|
__le32 len;
|
|
|
|
__le32 version;
|
|
|
|
__le32 type;
|
|
|
|
} get_target_info;
|
|
|
|
struct {
|
|
|
|
__le32 patch_id;
|
|
|
|
} rompatch_install;
|
|
|
|
struct {
|
|
|
|
__le32 patch_id;
|
|
|
|
} rompatch_uninstall;
|
|
|
|
struct {
|
|
|
|
/* 0 = nothing executed
|
2017-02-20 22:38:50 +08:00
|
|
|
* otherwise = NVRAM segment return value
|
|
|
|
*/
|
2013-06-13 01:52:10 +08:00
|
|
|
__le32 result;
|
|
|
|
} nvram_process;
|
|
|
|
u8 payload[BMI_MAX_CMDBUF_SIZE];
|
|
|
|
} __packed;
|
|
|
|
|
|
|
|
struct bmi_target_info {
|
|
|
|
u32 version;
|
|
|
|
u32 type;
|
|
|
|
};
|
|
|
|
|
2018-09-04 18:00:51 +08:00
|
|
|
struct bmi_segmented_file_header {
|
|
|
|
__le32 magic_num;
|
|
|
|
__le32 file_flags;
|
|
|
|
u8 data[];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct bmi_segmented_metadata {
|
|
|
|
__le32 addr;
|
|
|
|
__le32 length;
|
|
|
|
u8 data[];
|
|
|
|
};
|
|
|
|
|
|
|
|
#define BMI_SGMTFILE_MAGIC_NUM 0x544d4753 /* "SGMT" */
|
|
|
|
#define BMI_SGMTFILE_FLAG_COMPRESS 1
|
|
|
|
|
|
|
|
/* Special values for bmi_segmented_metadata.length (all have high bit set) */
|
|
|
|
|
|
|
|
/* end of segmented data */
|
|
|
|
#define BMI_SGMTFILE_DONE 0xffffffff
|
|
|
|
|
|
|
|
/* Board Data segment */
|
|
|
|
#define BMI_SGMTFILE_BDDATA 0xfffffffe
|
|
|
|
|
|
|
|
/* set beginning address */
|
|
|
|
#define BMI_SGMTFILE_BEGINADDR 0xfffffffd
|
|
|
|
|
|
|
|
/* immediate function execution */
|
|
|
|
#define BMI_SGMTFILE_EXEC 0xfffffffc
|
|
|
|
|
2017-05-31 19:21:19 +08:00
|
|
|
/* in jiffies */
|
|
|
|
#define BMI_COMMUNICATION_TIMEOUT_HZ (3 * HZ)
|
2013-06-13 01:52:10 +08:00
|
|
|
|
|
|
|
#define BMI_CE_NUM_TO_TARG 0
|
|
|
|
#define BMI_CE_NUM_TO_HOST 1
|
|
|
|
|
2013-07-16 15:38:53 +08:00
|
|
|
void ath10k_bmi_start(struct ath10k *ar);
|
2013-06-13 01:52:10 +08:00
|
|
|
int ath10k_bmi_done(struct ath10k *ar);
|
|
|
|
int ath10k_bmi_get_target_info(struct ath10k *ar,
|
|
|
|
struct bmi_target_info *target_info);
|
2017-04-26 17:17:57 +08:00
|
|
|
int ath10k_bmi_get_target_info_sdio(struct ath10k *ar,
|
|
|
|
struct bmi_target_info *target_info);
|
2013-06-13 01:52:10 +08:00
|
|
|
int ath10k_bmi_read_memory(struct ath10k *ar, u32 address,
|
|
|
|
void *buffer, u32 length);
|
|
|
|
int ath10k_bmi_write_memory(struct ath10k *ar, u32 address,
|
|
|
|
const void *buffer, u32 length);
|
|
|
|
|
|
|
|
#define ath10k_bmi_read32(ar, item, val) \
|
|
|
|
({ \
|
|
|
|
int ret; \
|
|
|
|
u32 addr; \
|
|
|
|
__le32 tmp; \
|
|
|
|
\
|
|
|
|
addr = host_interest_item_address(HI_ITEM(item)); \
|
|
|
|
ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \
|
2014-05-23 16:04:49 +08:00
|
|
|
if (!ret) \
|
|
|
|
*val = __le32_to_cpu(tmp); \
|
2013-06-13 01:52:10 +08:00
|
|
|
ret; \
|
|
|
|
})
|
|
|
|
|
|
|
|
#define ath10k_bmi_write32(ar, item, val) \
|
|
|
|
({ \
|
|
|
|
int ret; \
|
|
|
|
u32 address; \
|
|
|
|
__le32 v = __cpu_to_le32(val); \
|
|
|
|
\
|
|
|
|
address = host_interest_item_address(HI_ITEM(item)); \
|
|
|
|
ret = ath10k_bmi_write_memory(ar, address, \
|
|
|
|
(u8 *)&v, sizeof(v)); \
|
|
|
|
ret; \
|
|
|
|
})
|
|
|
|
|
2014-03-11 23:33:19 +08:00
|
|
|
int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result);
|
2013-06-13 01:52:10 +08:00
|
|
|
int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address);
|
|
|
|
int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);
|
|
|
|
int ath10k_bmi_fast_download(struct ath10k *ar, u32 address,
|
|
|
|
const void *buffer, u32 length);
|
2017-03-08 19:52:04 +08:00
|
|
|
int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val);
|
|
|
|
int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val);
|
2018-09-04 18:00:51 +08:00
|
|
|
int ath10k_bmi_set_start(struct ath10k *ar, u32 address);
|
|
|
|
|
2013-06-13 01:52:10 +08:00
|
|
|
#endif /* _BMI_H_ */
|