Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: ISC */
0002 /*
0003  * Copyright (c) 2005-2011 Atheros Communications Inc.
0004  * Copyright (c) 2011-2015,2017 Qualcomm Atheros, Inc.
0005  */
0006 
0007 #ifndef _BMI_H_
0008 #define _BMI_H_
0009 
0010 #include "core.h"
0011 
0012 /*
0013  * Bootloader Messaging Interface (BMI)
0014  *
0015  * BMI is a very simple messaging interface used during initialization
0016  * to read memory, write memory, execute code, and to define an
0017  * application entry PC.
0018  *
0019  * It is used to download an application to QCA988x, to provide
0020  * patches to code that is already resident on QCA988x, and generally
0021  * to examine and modify state.  The Host has an opportunity to use
0022  * BMI only once during bootup.  Once the Host issues a BMI_DONE
0023  * command, this opportunity ends.
0024  *
0025  * The Host writes BMI requests to mailbox0, and reads BMI responses
0026  * from mailbox0.   BMI requests all begin with a command
0027  * (see below for specific commands), and are followed by
0028  * command-specific data.
0029  *
0030  * Flow control:
0031  * The Host can only issue a command once the Target gives it a
0032  * "BMI Command Credit", using AR8K Counter #4.  As soon as the
0033  * Target has completed a command, it issues another BMI Command
0034  * Credit (so the Host can issue the next command).
0035  *
0036  * BMI handles all required Target-side cache flushing.
0037  */
0038 
0039 /* Maximum data size used for BMI transfers */
0040 #define BMI_MAX_DATA_SIZE   256
0041 
0042 /* len = cmd + addr + length */
0043 #define BMI_MAX_CMDBUF_SIZE (BMI_MAX_DATA_SIZE + \
0044             sizeof(u32) + \
0045             sizeof(u32) + \
0046             sizeof(u32))
0047 
0048 /* Maximum data size used for large BMI transfers */
0049 #define BMI_MAX_LARGE_DATA_SIZE 2048
0050 
0051 /* len = cmd + addr + length */
0052 #define BMI_MAX_LARGE_CMDBUF_SIZE (BMI_MAX_LARGE_DATA_SIZE + \
0053             sizeof(u32) + \
0054             sizeof(u32) + \
0055             sizeof(u32))
0056 
0057 /* BMI Commands */
0058 
0059 enum bmi_cmd_id {
0060     BMI_NO_COMMAND          = 0,
0061     BMI_DONE                = 1,
0062     BMI_READ_MEMORY         = 2,
0063     BMI_WRITE_MEMORY        = 3,
0064     BMI_EXECUTE             = 4,
0065     BMI_SET_APP_START       = 5,
0066     BMI_READ_SOC_REGISTER   = 6,
0067     BMI_READ_SOC_WORD       = 6,
0068     BMI_WRITE_SOC_REGISTER  = 7,
0069     BMI_WRITE_SOC_WORD      = 7,
0070     BMI_GET_TARGET_ID       = 8,
0071     BMI_GET_TARGET_INFO     = 8,
0072     BMI_ROMPATCH_INSTALL    = 9,
0073     BMI_ROMPATCH_UNINSTALL  = 10,
0074     BMI_ROMPATCH_ACTIVATE   = 11,
0075     BMI_ROMPATCH_DEACTIVATE = 12,
0076     BMI_LZ_STREAM_START     = 13, /* should be followed by LZ_DATA */
0077     BMI_LZ_DATA             = 14,
0078     BMI_NVRAM_PROCESS       = 15,
0079 };
0080 
0081 #define BMI_NVRAM_SEG_NAME_SZ 16
0082 
0083 #define BMI_PARAM_GET_EEPROM_BOARD_ID 0x10
0084 #define BMI_PARAM_GET_FLASH_BOARD_ID 0x8000
0085 #define BMI_PARAM_FLASH_SECTION_ALL 0x10000
0086 
0087 /* Dual-band Extended Board ID */
0088 #define BMI_PARAM_GET_EXT_BOARD_ID 0x40000
0089 #define ATH10K_BMI_EXT_BOARD_ID_SUPPORT 0x40000
0090 
0091 #define ATH10K_BMI_BOARD_ID_FROM_OTP_MASK   0x7c00
0092 #define ATH10K_BMI_BOARD_ID_FROM_OTP_LSB    10
0093 
0094 #define ATH10K_BMI_CHIP_ID_FROM_OTP_MASK    0x18000
0095 #define ATH10K_BMI_CHIP_ID_FROM_OTP_LSB     15
0096 
0097 #define ATH10K_BMI_BOARD_ID_STATUS_MASK 0xff
0098 #define ATH10K_BMI_EBOARD_ID_STATUS_MASK 0xff
0099 
0100 struct bmi_cmd {
0101     __le32 id; /* enum bmi_cmd_id */
0102     union {
0103         struct {
0104         } done;
0105         struct {
0106             __le32 addr;
0107             __le32 len;
0108         } read_mem;
0109         struct {
0110             __le32 addr;
0111             __le32 len;
0112             u8 payload[];
0113         } write_mem;
0114         struct {
0115             __le32 addr;
0116             __le32 param;
0117         } execute;
0118         struct {
0119             __le32 addr;
0120         } set_app_start;
0121         struct {
0122             __le32 addr;
0123         } read_soc_reg;
0124         struct {
0125             __le32 addr;
0126             __le32 value;
0127         } write_soc_reg;
0128         struct {
0129         } get_target_info;
0130         struct {
0131             __le32 rom_addr;
0132             __le32 ram_addr; /* or value */
0133             __le32 size;
0134             __le32 activate; /* 0=install, but dont activate */
0135         } rompatch_install;
0136         struct {
0137             __le32 patch_id;
0138         } rompatch_uninstall;
0139         struct {
0140             __le32 count;
0141             __le32 patch_ids[]; /* length of @count */
0142         } rompatch_activate;
0143         struct {
0144             __le32 count;
0145             __le32 patch_ids[]; /* length of @count */
0146         } rompatch_deactivate;
0147         struct {
0148             __le32 addr;
0149         } lz_start;
0150         struct {
0151             __le32 len; /* max BMI_MAX_DATA_SIZE */
0152             u8 payload[]; /* length of @len */
0153         } lz_data;
0154         struct {
0155             u8 name[BMI_NVRAM_SEG_NAME_SZ];
0156         } nvram_process;
0157         u8 payload[BMI_MAX_CMDBUF_SIZE];
0158     };
0159 } __packed;
0160 
0161 union bmi_resp {
0162     struct {
0163         DECLARE_FLEX_ARRAY(u8, payload);
0164     } read_mem;
0165     struct {
0166         __le32 result;
0167     } execute;
0168     struct {
0169         __le32 value;
0170     } read_soc_reg;
0171     struct {
0172         __le32 len;
0173         __le32 version;
0174         __le32 type;
0175     } get_target_info;
0176     struct {
0177         __le32 patch_id;
0178     } rompatch_install;
0179     struct {
0180         __le32 patch_id;
0181     } rompatch_uninstall;
0182     struct {
0183         /* 0 = nothing executed
0184          * otherwise = NVRAM segment return value
0185          */
0186         __le32 result;
0187     } nvram_process;
0188     u8 payload[BMI_MAX_CMDBUF_SIZE];
0189 } __packed;
0190 
0191 struct bmi_target_info {
0192     u32 version;
0193     u32 type;
0194 };
0195 
0196 struct bmi_segmented_file_header {
0197     __le32 magic_num;
0198     __le32 file_flags;
0199     u8 data[];
0200 };
0201 
0202 struct bmi_segmented_metadata {
0203     __le32 addr;
0204     __le32 length;
0205     u8 data[];
0206 };
0207 
0208 #define BMI_SGMTFILE_MAGIC_NUM          0x544d4753 /* "SGMT" */
0209 #define BMI_SGMTFILE_FLAG_COMPRESS      1
0210 
0211 /* Special values for bmi_segmented_metadata.length (all have high bit set) */
0212 
0213 /* end of segmented data */
0214 #define BMI_SGMTFILE_DONE               0xffffffff
0215 
0216 /* Board Data segment */
0217 #define BMI_SGMTFILE_BDDATA             0xfffffffe
0218 
0219 /* set beginning address */
0220 #define BMI_SGMTFILE_BEGINADDR          0xfffffffd
0221 
0222 /* immediate function execution */
0223 #define BMI_SGMTFILE_EXEC               0xfffffffc
0224 
0225 /* in jiffies */
0226 #define BMI_COMMUNICATION_TIMEOUT_HZ (3 * HZ)
0227 
0228 #define BMI_CE_NUM_TO_TARG 0
0229 #define BMI_CE_NUM_TO_HOST 1
0230 
0231 void ath10k_bmi_start(struct ath10k *ar);
0232 int ath10k_bmi_done(struct ath10k *ar);
0233 int ath10k_bmi_get_target_info(struct ath10k *ar,
0234                    struct bmi_target_info *target_info);
0235 int ath10k_bmi_get_target_info_sdio(struct ath10k *ar,
0236                     struct bmi_target_info *target_info);
0237 int ath10k_bmi_read_memory(struct ath10k *ar, u32 address,
0238                void *buffer, u32 length);
0239 int ath10k_bmi_write_memory(struct ath10k *ar, u32 address,
0240                 const void *buffer, u32 length);
0241 
0242 #define ath10k_bmi_read32(ar, item, val)                \
0243     ({                              \
0244         int ret;                        \
0245         u32 addr;                       \
0246         __le32 tmp;                     \
0247                                     \
0248         addr = host_interest_item_address(HI_ITEM(item));   \
0249         ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \
0250         if (!ret)                       \
0251             *val = __le32_to_cpu(tmp);          \
0252         ret;                            \
0253      })
0254 
0255 #define ath10k_bmi_write32(ar, item, val)               \
0256     ({                              \
0257         int ret;                        \
0258         u32 address;                        \
0259         __le32 v = __cpu_to_le32(val);              \
0260                                     \
0261         address = host_interest_item_address(HI_ITEM(item));    \
0262         ret = ath10k_bmi_write_memory(ar, address,      \
0263                           (u8 *)&v, sizeof(v)); \
0264         ret;                            \
0265     })
0266 
0267 int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result);
0268 int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address);
0269 int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);
0270 
0271 int ath10k_bmi_fast_download(struct ath10k *ar, u32 address,
0272                  const void *buffer, u32 length);
0273 int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val);
0274 int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val);
0275 int ath10k_bmi_set_start(struct ath10k *ar, u32 address);
0276 
0277 #endif /* _BMI_H_ */