15e3dd157SKalle Valo /* 25e3dd157SKalle Valo * Copyright (c) 2005-2011 Atheros Communications Inc. 38b1083d6SKalle Valo * Copyright (c) 2011-2015,2017 Qualcomm Atheros, Inc. 45e3dd157SKalle Valo * 55e3dd157SKalle Valo * Permission to use, copy, modify, and/or distribute this software for any 65e3dd157SKalle Valo * purpose with or without fee is hereby granted, provided that the above 75e3dd157SKalle Valo * copyright notice and this permission notice appear in all copies. 85e3dd157SKalle Valo * 95e3dd157SKalle Valo * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 105e3dd157SKalle Valo * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 115e3dd157SKalle Valo * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 125e3dd157SKalle Valo * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 135e3dd157SKalle Valo * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 145e3dd157SKalle Valo * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 155e3dd157SKalle Valo * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 165e3dd157SKalle Valo */ 175e3dd157SKalle Valo 185e3dd157SKalle Valo #ifndef _BMI_H_ 195e3dd157SKalle Valo #define _BMI_H_ 205e3dd157SKalle Valo 215e3dd157SKalle Valo #include "core.h" 225e3dd157SKalle Valo 235e3dd157SKalle Valo /* 245e3dd157SKalle Valo * Bootloader Messaging Interface (BMI) 255e3dd157SKalle Valo * 265e3dd157SKalle Valo * BMI is a very simple messaging interface used during initialization 275e3dd157SKalle Valo * to read memory, write memory, execute code, and to define an 285e3dd157SKalle Valo * application entry PC. 295e3dd157SKalle Valo * 305e3dd157SKalle Valo * It is used to download an application to QCA988x, to provide 315e3dd157SKalle Valo * patches to code that is already resident on QCA988x, and generally 325e3dd157SKalle Valo * to examine and modify state. The Host has an opportunity to use 335e3dd157SKalle Valo * BMI only once during bootup. Once the Host issues a BMI_DONE 345e3dd157SKalle Valo * command, this opportunity ends. 355e3dd157SKalle Valo * 365e3dd157SKalle Valo * The Host writes BMI requests to mailbox0, and reads BMI responses 375e3dd157SKalle Valo * from mailbox0. BMI requests all begin with a command 385e3dd157SKalle Valo * (see below for specific commands), and are followed by 395e3dd157SKalle Valo * command-specific data. 405e3dd157SKalle Valo * 415e3dd157SKalle Valo * Flow control: 425e3dd157SKalle Valo * The Host can only issue a command once the Target gives it a 435e3dd157SKalle Valo * "BMI Command Credit", using AR8K Counter #4. As soon as the 445e3dd157SKalle Valo * Target has completed a command, it issues another BMI Command 455e3dd157SKalle Valo * Credit (so the Host can issue the next command). 465e3dd157SKalle Valo * 475e3dd157SKalle Valo * BMI handles all required Target-side cache flushing. 485e3dd157SKalle Valo */ 495e3dd157SKalle Valo 505e3dd157SKalle Valo /* Maximum data size used for BMI transfers */ 515e3dd157SKalle Valo #define BMI_MAX_DATA_SIZE 256 525e3dd157SKalle Valo 535e3dd157SKalle Valo /* len = cmd + addr + length */ 545e3dd157SKalle Valo #define BMI_MAX_CMDBUF_SIZE (BMI_MAX_DATA_SIZE + \ 555e3dd157SKalle Valo sizeof(u32) + \ 565e3dd157SKalle Valo sizeof(u32) + \ 575e3dd157SKalle Valo sizeof(u32)) 585e3dd157SKalle Valo 595e3dd157SKalle Valo /* BMI Commands */ 605e3dd157SKalle Valo 615e3dd157SKalle Valo enum bmi_cmd_id { 625e3dd157SKalle Valo BMI_NO_COMMAND = 0, 635e3dd157SKalle Valo BMI_DONE = 1, 645e3dd157SKalle Valo BMI_READ_MEMORY = 2, 655e3dd157SKalle Valo BMI_WRITE_MEMORY = 3, 665e3dd157SKalle Valo BMI_EXECUTE = 4, 675e3dd157SKalle Valo BMI_SET_APP_START = 5, 685e3dd157SKalle Valo BMI_READ_SOC_REGISTER = 6, 695e3dd157SKalle Valo BMI_READ_SOC_WORD = 6, 705e3dd157SKalle Valo BMI_WRITE_SOC_REGISTER = 7, 715e3dd157SKalle Valo BMI_WRITE_SOC_WORD = 7, 725e3dd157SKalle Valo BMI_GET_TARGET_ID = 8, 735e3dd157SKalle Valo BMI_GET_TARGET_INFO = 8, 745e3dd157SKalle Valo BMI_ROMPATCH_INSTALL = 9, 755e3dd157SKalle Valo BMI_ROMPATCH_UNINSTALL = 10, 765e3dd157SKalle Valo BMI_ROMPATCH_ACTIVATE = 11, 775e3dd157SKalle Valo BMI_ROMPATCH_DEACTIVATE = 12, 785e3dd157SKalle Valo BMI_LZ_STREAM_START = 13, /* should be followed by LZ_DATA */ 795e3dd157SKalle Valo BMI_LZ_DATA = 14, 805e3dd157SKalle Valo BMI_NVRAM_PROCESS = 15, 815e3dd157SKalle Valo }; 825e3dd157SKalle Valo 835e3dd157SKalle Valo #define BMI_NVRAM_SEG_NAME_SZ 16 845e3dd157SKalle Valo 85db0984e5SManikanta Pubbisetty #define BMI_PARAM_GET_EEPROM_BOARD_ID 0x10 86a9f5f287SAnilkumar Kolli #define BMI_PARAM_GET_FLASH_BOARD_ID 0x8000 87a9f5f287SAnilkumar Kolli #define BMI_PARAM_FLASH_SECTION_ALL 0x10000 88db0984e5SManikanta Pubbisetty 8931324d17SSathishkumar Muruganandam /* Dual-band Extended Board ID */ 9031324d17SSathishkumar Muruganandam #define BMI_PARAM_GET_EXT_BOARD_ID 0x40000 9131324d17SSathishkumar Muruganandam #define ATH10K_BMI_EXT_BOARD_ID_SUPPORT 0x40000 9231324d17SSathishkumar Muruganandam 93db0984e5SManikanta Pubbisetty #define ATH10K_BMI_BOARD_ID_FROM_OTP_MASK 0x7c00 94db0984e5SManikanta Pubbisetty #define ATH10K_BMI_BOARD_ID_FROM_OTP_LSB 10 95db0984e5SManikanta Pubbisetty 96db0984e5SManikanta Pubbisetty #define ATH10K_BMI_CHIP_ID_FROM_OTP_MASK 0x18000 97db0984e5SManikanta Pubbisetty #define ATH10K_BMI_CHIP_ID_FROM_OTP_LSB 15 98db0984e5SManikanta Pubbisetty 99db0984e5SManikanta Pubbisetty #define ATH10K_BMI_BOARD_ID_STATUS_MASK 0xff 10031324d17SSathishkumar Muruganandam #define ATH10K_BMI_EBOARD_ID_STATUS_MASK 0xff 101db0984e5SManikanta Pubbisetty 1025e3dd157SKalle Valo struct bmi_cmd { 1035e3dd157SKalle Valo __le32 id; /* enum bmi_cmd_id */ 1045e3dd157SKalle Valo union { 1055e3dd157SKalle Valo struct { 1065e3dd157SKalle Valo } done; 1075e3dd157SKalle Valo struct { 1085e3dd157SKalle Valo __le32 addr; 1095e3dd157SKalle Valo __le32 len; 1105e3dd157SKalle Valo } read_mem; 1115e3dd157SKalle Valo struct { 1125e3dd157SKalle Valo __le32 addr; 1135e3dd157SKalle Valo __le32 len; 1145e3dd157SKalle Valo u8 payload[0]; 1155e3dd157SKalle Valo } write_mem; 1165e3dd157SKalle Valo struct { 1175e3dd157SKalle Valo __le32 addr; 1185e3dd157SKalle Valo __le32 param; 1195e3dd157SKalle Valo } execute; 1205e3dd157SKalle Valo struct { 1215e3dd157SKalle Valo __le32 addr; 1225e3dd157SKalle Valo } set_app_start; 1235e3dd157SKalle Valo struct { 1245e3dd157SKalle Valo __le32 addr; 1255e3dd157SKalle Valo } read_soc_reg; 1265e3dd157SKalle Valo struct { 1275e3dd157SKalle Valo __le32 addr; 1285e3dd157SKalle Valo __le32 value; 1295e3dd157SKalle Valo } write_soc_reg; 1305e3dd157SKalle Valo struct { 1315e3dd157SKalle Valo } get_target_info; 1325e3dd157SKalle Valo struct { 1335e3dd157SKalle Valo __le32 rom_addr; 1345e3dd157SKalle Valo __le32 ram_addr; /* or value */ 1355e3dd157SKalle Valo __le32 size; 1365e3dd157SKalle Valo __le32 activate; /* 0=install, but dont activate */ 1375e3dd157SKalle Valo } rompatch_install; 1385e3dd157SKalle Valo struct { 1395e3dd157SKalle Valo __le32 patch_id; 1405e3dd157SKalle Valo } rompatch_uninstall; 1415e3dd157SKalle Valo struct { 1425e3dd157SKalle Valo __le32 count; 1435e3dd157SKalle Valo __le32 patch_ids[0]; /* length of @count */ 1445e3dd157SKalle Valo } rompatch_activate; 1455e3dd157SKalle Valo struct { 1465e3dd157SKalle Valo __le32 count; 1475e3dd157SKalle Valo __le32 patch_ids[0]; /* length of @count */ 1485e3dd157SKalle Valo } rompatch_deactivate; 1495e3dd157SKalle Valo struct { 1505e3dd157SKalle Valo __le32 addr; 1515e3dd157SKalle Valo } lz_start; 1525e3dd157SKalle Valo struct { 1535e3dd157SKalle Valo __le32 len; /* max BMI_MAX_DATA_SIZE */ 1545e3dd157SKalle Valo u8 payload[0]; /* length of @len */ 1555e3dd157SKalle Valo } lz_data; 1565e3dd157SKalle Valo struct { 1575e3dd157SKalle Valo u8 name[BMI_NVRAM_SEG_NAME_SZ]; 1585e3dd157SKalle Valo } nvram_process; 1595e3dd157SKalle Valo u8 payload[BMI_MAX_CMDBUF_SIZE]; 1605e3dd157SKalle Valo }; 1615e3dd157SKalle Valo } __packed; 1625e3dd157SKalle Valo 1635e3dd157SKalle Valo union bmi_resp { 1645e3dd157SKalle Valo struct { 1655e3dd157SKalle Valo u8 payload[0]; 1665e3dd157SKalle Valo } read_mem; 1675e3dd157SKalle Valo struct { 1685e3dd157SKalle Valo __le32 result; 1695e3dd157SKalle Valo } execute; 1705e3dd157SKalle Valo struct { 1715e3dd157SKalle Valo __le32 value; 1725e3dd157SKalle Valo } read_soc_reg; 1735e3dd157SKalle Valo struct { 1745e3dd157SKalle Valo __le32 len; 1755e3dd157SKalle Valo __le32 version; 1765e3dd157SKalle Valo __le32 type; 1775e3dd157SKalle Valo } get_target_info; 1785e3dd157SKalle Valo struct { 1795e3dd157SKalle Valo __le32 patch_id; 1805e3dd157SKalle Valo } rompatch_install; 1815e3dd157SKalle Valo struct { 1825e3dd157SKalle Valo __le32 patch_id; 1835e3dd157SKalle Valo } rompatch_uninstall; 1845e3dd157SKalle Valo struct { 1855e3dd157SKalle Valo /* 0 = nothing executed 18637ff1b0dSMarcin Rokicki * otherwise = NVRAM segment return value 18737ff1b0dSMarcin Rokicki */ 1885e3dd157SKalle Valo __le32 result; 1895e3dd157SKalle Valo } nvram_process; 1905e3dd157SKalle Valo u8 payload[BMI_MAX_CMDBUF_SIZE]; 1915e3dd157SKalle Valo } __packed; 1925e3dd157SKalle Valo 1935e3dd157SKalle Valo struct bmi_target_info { 1945e3dd157SKalle Valo u32 version; 1955e3dd157SKalle Valo u32 type; 1965e3dd157SKalle Valo }; 1975e3dd157SKalle Valo 19839501ea6SCarl Huang struct bmi_segmented_file_header { 19939501ea6SCarl Huang __le32 magic_num; 20039501ea6SCarl Huang __le32 file_flags; 20139501ea6SCarl Huang u8 data[]; 20239501ea6SCarl Huang }; 20339501ea6SCarl Huang 20439501ea6SCarl Huang struct bmi_segmented_metadata { 20539501ea6SCarl Huang __le32 addr; 20639501ea6SCarl Huang __le32 length; 20739501ea6SCarl Huang u8 data[]; 20839501ea6SCarl Huang }; 20939501ea6SCarl Huang 21039501ea6SCarl Huang #define BMI_SGMTFILE_MAGIC_NUM 0x544d4753 /* "SGMT" */ 21139501ea6SCarl Huang #define BMI_SGMTFILE_FLAG_COMPRESS 1 21239501ea6SCarl Huang 21339501ea6SCarl Huang /* Special values for bmi_segmented_metadata.length (all have high bit set) */ 21439501ea6SCarl Huang 21539501ea6SCarl Huang /* end of segmented data */ 21639501ea6SCarl Huang #define BMI_SGMTFILE_DONE 0xffffffff 21739501ea6SCarl Huang 21839501ea6SCarl Huang /* Board Data segment */ 21939501ea6SCarl Huang #define BMI_SGMTFILE_BDDATA 0xfffffffe 22039501ea6SCarl Huang 22139501ea6SCarl Huang /* set beginning address */ 22239501ea6SCarl Huang #define BMI_SGMTFILE_BEGINADDR 0xfffffffd 22339501ea6SCarl Huang 22439501ea6SCarl Huang /* immediate function execution */ 22539501ea6SCarl Huang #define BMI_SGMTFILE_EXEC 0xfffffffc 22639501ea6SCarl Huang 22713c3b26aSBen Greear /* in jiffies */ 22813c3b26aSBen Greear #define BMI_COMMUNICATION_TIMEOUT_HZ (3 * HZ) 2295e3dd157SKalle Valo 2305e3dd157SKalle Valo #define BMI_CE_NUM_TO_TARG 0 2315e3dd157SKalle Valo #define BMI_CE_NUM_TO_HOST 1 2325e3dd157SKalle Valo 23364d151d4SMichal Kazior void ath10k_bmi_start(struct ath10k *ar); 2345e3dd157SKalle Valo int ath10k_bmi_done(struct ath10k *ar); 2355e3dd157SKalle Valo int ath10k_bmi_get_target_info(struct ath10k *ar, 2365e3dd157SKalle Valo struct bmi_target_info *target_info); 23734dd398aSErik Stromdahl int ath10k_bmi_get_target_info_sdio(struct ath10k *ar, 23834dd398aSErik Stromdahl struct bmi_target_info *target_info); 2395e3dd157SKalle Valo int ath10k_bmi_read_memory(struct ath10k *ar, u32 address, 2405e3dd157SKalle Valo void *buffer, u32 length); 2415e3dd157SKalle Valo int ath10k_bmi_write_memory(struct ath10k *ar, u32 address, 2425e3dd157SKalle Valo const void *buffer, u32 length); 2435e3dd157SKalle Valo 2445e3dd157SKalle Valo #define ath10k_bmi_read32(ar, item, val) \ 2455e3dd157SKalle Valo ({ \ 2465e3dd157SKalle Valo int ret; \ 2475e3dd157SKalle Valo u32 addr; \ 2485e3dd157SKalle Valo __le32 tmp; \ 2495e3dd157SKalle Valo \ 2505e3dd157SKalle Valo addr = host_interest_item_address(HI_ITEM(item)); \ 2515e3dd157SKalle Valo ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \ 252afe5b7b4SFrederic Danis if (!ret) \ 2535e3dd157SKalle Valo *val = __le32_to_cpu(tmp); \ 2545e3dd157SKalle Valo ret; \ 2555e3dd157SKalle Valo }) 2565e3dd157SKalle Valo 2575e3dd157SKalle Valo #define ath10k_bmi_write32(ar, item, val) \ 2585e3dd157SKalle Valo ({ \ 2595e3dd157SKalle Valo int ret; \ 2605e3dd157SKalle Valo u32 address; \ 2615e3dd157SKalle Valo __le32 v = __cpu_to_le32(val); \ 2625e3dd157SKalle Valo \ 2635e3dd157SKalle Valo address = host_interest_item_address(HI_ITEM(item)); \ 2645e3dd157SKalle Valo ret = ath10k_bmi_write_memory(ar, address, \ 2655e3dd157SKalle Valo (u8 *)&v, sizeof(v)); \ 2665e3dd157SKalle Valo ret; \ 2675e3dd157SKalle Valo }) 2685e3dd157SKalle Valo 269d6d4a58dSKalle Valo int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result); 2705e3dd157SKalle Valo int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address); 2715e3dd157SKalle Valo int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length); 2725e3dd157SKalle Valo int ath10k_bmi_fast_download(struct ath10k *ar, u32 address, 2735e3dd157SKalle Valo const void *buffer, u32 length); 274583a6629SRyan Hsu int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val); 275583a6629SRyan Hsu int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val); 27639501ea6SCarl Huang int ath10k_bmi_set_start(struct ath10k *ar, u32 address); 27739501ea6SCarl Huang 2785e3dd157SKalle Valo #endif /* _BMI_H_ */ 279