18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Low-level API for mac80211 ST-Ericsson CW1200 drivers 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2010, ST-Ericsson 68c2ecf20Sopenharmony_ci * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Based on: 98c2ecf20Sopenharmony_ci * ST-Ericsson UMAC CW1200 driver which is 108c2ecf20Sopenharmony_ci * Copyright (c) 2010, ST-Ericsson 118c2ecf20Sopenharmony_ci * Author: Ajitpal Singh <ajitpal.singh@stericsson.com> 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#ifndef CW1200_HWIO_H_INCLUDED 158c2ecf20Sopenharmony_ci#define CW1200_HWIO_H_INCLUDED 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* extern */ struct cw1200_common; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define CW1200_CUT_11_ID_STR (0x302E3830) 208c2ecf20Sopenharmony_ci#define CW1200_CUT_22_ID_STR1 (0x302e3132) 218c2ecf20Sopenharmony_ci#define CW1200_CUT_22_ID_STR2 (0x32302e30) 228c2ecf20Sopenharmony_ci#define CW1200_CUT_22_ID_STR3 (0x3335) 238c2ecf20Sopenharmony_ci#define CW1200_CUT_ID_ADDR (0xFFF17F90) 248c2ecf20Sopenharmony_ci#define CW1200_CUT2_ID_ADDR (0xFFF1FF90) 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* Download control area */ 278c2ecf20Sopenharmony_ci/* boot loader start address in SRAM */ 288c2ecf20Sopenharmony_ci#define DOWNLOAD_BOOT_LOADER_OFFSET (0x00000000) 298c2ecf20Sopenharmony_ci/* 32K, 0x4000 to 0xDFFF */ 308c2ecf20Sopenharmony_ci#define DOWNLOAD_FIFO_OFFSET (0x00004000) 318c2ecf20Sopenharmony_ci/* 32K */ 328c2ecf20Sopenharmony_ci#define DOWNLOAD_FIFO_SIZE (0x00008000) 338c2ecf20Sopenharmony_ci/* 128 bytes, 0xFF80 to 0xFFFF */ 348c2ecf20Sopenharmony_ci#define DOWNLOAD_CTRL_OFFSET (0x0000FF80) 358c2ecf20Sopenharmony_ci#define DOWNLOAD_CTRL_DATA_DWORDS (32-6) 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistruct download_cntl_t { 388c2ecf20Sopenharmony_ci /* size of whole firmware file (including Cheksum), host init */ 398c2ecf20Sopenharmony_ci u32 image_size; 408c2ecf20Sopenharmony_ci /* downloading flags */ 418c2ecf20Sopenharmony_ci u32 flags; 428c2ecf20Sopenharmony_ci /* No. of bytes put into the download, init & updated by host */ 438c2ecf20Sopenharmony_ci u32 put; 448c2ecf20Sopenharmony_ci /* last traced program counter, last ARM reg_pc */ 458c2ecf20Sopenharmony_ci u32 trace_pc; 468c2ecf20Sopenharmony_ci /* No. of bytes read from the download, host init, device updates */ 478c2ecf20Sopenharmony_ci u32 get; 488c2ecf20Sopenharmony_ci /* r0, boot losader status, host init to pending, device updates */ 498c2ecf20Sopenharmony_ci u32 status; 508c2ecf20Sopenharmony_ci /* Extra debug info, r1 to r14 if status=r0=DOWNLOAD_EXCEPTION */ 518c2ecf20Sopenharmony_ci u32 debug_data[DOWNLOAD_CTRL_DATA_DWORDS]; 528c2ecf20Sopenharmony_ci}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#define DOWNLOAD_IMAGE_SIZE_REG \ 558c2ecf20Sopenharmony_ci (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, image_size)) 568c2ecf20Sopenharmony_ci#define DOWNLOAD_FLAGS_REG \ 578c2ecf20Sopenharmony_ci (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, flags)) 588c2ecf20Sopenharmony_ci#define DOWNLOAD_PUT_REG \ 598c2ecf20Sopenharmony_ci (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, put)) 608c2ecf20Sopenharmony_ci#define DOWNLOAD_TRACE_PC_REG \ 618c2ecf20Sopenharmony_ci (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, trace_pc)) 628c2ecf20Sopenharmony_ci#define DOWNLOAD_GET_REG \ 638c2ecf20Sopenharmony_ci (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, get)) 648c2ecf20Sopenharmony_ci#define DOWNLOAD_STATUS_REG \ 658c2ecf20Sopenharmony_ci (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, status)) 668c2ecf20Sopenharmony_ci#define DOWNLOAD_DEBUG_DATA_REG \ 678c2ecf20Sopenharmony_ci (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, debug_data)) 688c2ecf20Sopenharmony_ci#define DOWNLOAD_DEBUG_DATA_LEN (108) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci#define DOWNLOAD_BLOCK_SIZE (1024) 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* For boot loader detection */ 738c2ecf20Sopenharmony_ci#define DOWNLOAD_ARE_YOU_HERE (0x87654321) 748c2ecf20Sopenharmony_ci#define DOWNLOAD_I_AM_HERE (0x12345678) 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/* Download error code */ 778c2ecf20Sopenharmony_ci#define DOWNLOAD_PENDING (0xFFFFFFFF) 788c2ecf20Sopenharmony_ci#define DOWNLOAD_SUCCESS (0) 798c2ecf20Sopenharmony_ci#define DOWNLOAD_EXCEPTION (1) 808c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_MEM_1 (2) 818c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_MEM_2 (3) 828c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_SOFTWARE (4) 838c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_FILE_SIZE (5) 848c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_CHECKSUM (6) 858c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_OVERFLOW (7) 868c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_IMAGE (8) 878c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_HOST (9) 888c2ecf20Sopenharmony_ci#define DOWNLOAD_ERR_ABORT (10) 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci#define SYS_BASE_ADDR_SILICON (0) 928c2ecf20Sopenharmony_ci#define PAC_BASE_ADDRESS_SILICON (SYS_BASE_ADDR_SILICON + 0x09000000) 938c2ecf20Sopenharmony_ci#define PAC_SHARED_MEMORY_SILICON (PAC_BASE_ADDRESS_SILICON) 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci#define CW1200_APB(addr) (PAC_SHARED_MEMORY_SILICON + (addr)) 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci/* Device register definitions */ 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci/* WBF - SPI Register Addresses */ 1008c2ecf20Sopenharmony_ci#define ST90TDS_ADDR_ID_BASE (0x0000) 1018c2ecf20Sopenharmony_ci/* 16/32 bits */ 1028c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_REG_ID (0x0000) 1038c2ecf20Sopenharmony_ci/* 16/32 bits */ 1048c2ecf20Sopenharmony_ci#define ST90TDS_CONTROL_REG_ID (0x0001) 1058c2ecf20Sopenharmony_ci/* 16 bits, Q mode W/R */ 1068c2ecf20Sopenharmony_ci#define ST90TDS_IN_OUT_QUEUE_REG_ID (0x0002) 1078c2ecf20Sopenharmony_ci/* 32 bits, AHB bus R/W */ 1088c2ecf20Sopenharmony_ci#define ST90TDS_AHB_DPORT_REG_ID (0x0003) 1098c2ecf20Sopenharmony_ci/* 16/32 bits */ 1108c2ecf20Sopenharmony_ci#define ST90TDS_SRAM_BASE_ADDR_REG_ID (0x0004) 1118c2ecf20Sopenharmony_ci/* 32 bits, APB bus R/W */ 1128c2ecf20Sopenharmony_ci#define ST90TDS_SRAM_DPORT_REG_ID (0x0005) 1138c2ecf20Sopenharmony_ci/* 32 bits, t_settle/general */ 1148c2ecf20Sopenharmony_ci#define ST90TDS_TSET_GEN_R_W_REG_ID (0x0006) 1158c2ecf20Sopenharmony_ci/* 16 bits, Q mode read, no length */ 1168c2ecf20Sopenharmony_ci#define ST90TDS_FRAME_OUT_REG_ID (0x0007) 1178c2ecf20Sopenharmony_ci#define ST90TDS_ADDR_ID_MAX (ST90TDS_FRAME_OUT_REG_ID) 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* WBF - Control register bit set */ 1208c2ecf20Sopenharmony_ci/* next o/p length, bit 11 to 0 */ 1218c2ecf20Sopenharmony_ci#define ST90TDS_CONT_NEXT_LEN_MASK (0x0FFF) 1228c2ecf20Sopenharmony_ci#define ST90TDS_CONT_WUP_BIT (BIT(12)) 1238c2ecf20Sopenharmony_ci#define ST90TDS_CONT_RDY_BIT (BIT(13)) 1248c2ecf20Sopenharmony_ci#define ST90TDS_CONT_IRQ_ENABLE (BIT(14)) 1258c2ecf20Sopenharmony_ci#define ST90TDS_CONT_RDY_ENABLE (BIT(15)) 1268c2ecf20Sopenharmony_ci#define ST90TDS_CONT_IRQ_RDY_ENABLE (BIT(14)|BIT(15)) 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci/* SPI Config register bit set */ 1298c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_FRAME_BIT (BIT(2)) 1308c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_WORD_MODE_BITS (BIT(3)|BIT(4)) 1318c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_WORD_MODE_1 (BIT(3)) 1328c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_WORD_MODE_2 (BIT(4)) 1338c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_ERROR_0_BIT (BIT(5)) 1348c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_ERROR_1_BIT (BIT(6)) 1358c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_ERROR_2_BIT (BIT(7)) 1368c2ecf20Sopenharmony_ci/* TBD: Sure??? */ 1378c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_CSN_FRAME_BIT (BIT(7)) 1388c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_ERROR_3_BIT (BIT(8)) 1398c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_ERROR_4_BIT (BIT(9)) 1408c2ecf20Sopenharmony_ci/* QueueM */ 1418c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_ACCESS_MODE_BIT (BIT(10)) 1428c2ecf20Sopenharmony_ci/* AHB bus */ 1438c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_AHB_PRFETCH_BIT (BIT(11)) 1448c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_CPU_CLK_DIS_BIT (BIT(12)) 1458c2ecf20Sopenharmony_ci/* APB bus */ 1468c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_PRFETCH_BIT (BIT(13)) 1478c2ecf20Sopenharmony_ci/* cpu reset */ 1488c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_CPU_RESET_BIT (BIT(14)) 1498c2ecf20Sopenharmony_ci#define ST90TDS_CONFIG_CLEAR_INT_BIT (BIT(15)) 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci/* For CW1200 the IRQ Enable and Ready Bits are in CONFIG register */ 1528c2ecf20Sopenharmony_ci#define ST90TDS_CONF_IRQ_ENABLE (BIT(16)) 1538c2ecf20Sopenharmony_ci#define ST90TDS_CONF_RDY_ENABLE (BIT(17)) 1548c2ecf20Sopenharmony_ci#define ST90TDS_CONF_IRQ_RDY_ENABLE (BIT(16)|BIT(17)) 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ciint cw1200_data_read(struct cw1200_common *priv, 1578c2ecf20Sopenharmony_ci void *buf, size_t buf_len); 1588c2ecf20Sopenharmony_ciint cw1200_data_write(struct cw1200_common *priv, 1598c2ecf20Sopenharmony_ci const void *buf, size_t buf_len); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ciint cw1200_reg_read(struct cw1200_common *priv, u16 addr, 1628c2ecf20Sopenharmony_ci void *buf, size_t buf_len); 1638c2ecf20Sopenharmony_ciint cw1200_reg_write(struct cw1200_common *priv, u16 addr, 1648c2ecf20Sopenharmony_ci const void *buf, size_t buf_len); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistatic inline int cw1200_reg_read_16(struct cw1200_common *priv, 1678c2ecf20Sopenharmony_ci u16 addr, u16 *val) 1688c2ecf20Sopenharmony_ci{ 1698c2ecf20Sopenharmony_ci __le32 tmp; 1708c2ecf20Sopenharmony_ci int i; 1718c2ecf20Sopenharmony_ci i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); 1728c2ecf20Sopenharmony_ci *val = le32_to_cpu(tmp) & 0xfffff; 1738c2ecf20Sopenharmony_ci return i; 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistatic inline int cw1200_reg_write_16(struct cw1200_common *priv, 1778c2ecf20Sopenharmony_ci u16 addr, u16 val) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci __le32 tmp = cpu_to_le32((u32)val); 1808c2ecf20Sopenharmony_ci return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp)); 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic inline int cw1200_reg_read_32(struct cw1200_common *priv, 1848c2ecf20Sopenharmony_ci u16 addr, u32 *val) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci __le32 tmp; 1878c2ecf20Sopenharmony_ci int i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); 1888c2ecf20Sopenharmony_ci *val = le32_to_cpu(tmp); 1898c2ecf20Sopenharmony_ci return i; 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic inline int cw1200_reg_write_32(struct cw1200_common *priv, 1938c2ecf20Sopenharmony_ci u16 addr, u32 val) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci __le32 tmp = cpu_to_le32(val); 1968c2ecf20Sopenharmony_ci return cw1200_reg_write(priv, addr, &tmp, sizeof(val)); 1978c2ecf20Sopenharmony_ci} 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ciint cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf, 2008c2ecf20Sopenharmony_ci size_t buf_len, u32 prefetch, u16 port_addr); 2018c2ecf20Sopenharmony_ciint cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf, 2028c2ecf20Sopenharmony_ci size_t buf_len); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic inline int cw1200_apb_read(struct cw1200_common *priv, u32 addr, 2058c2ecf20Sopenharmony_ci void *buf, size_t buf_len) 2068c2ecf20Sopenharmony_ci{ 2078c2ecf20Sopenharmony_ci return cw1200_indirect_read(priv, addr, buf, buf_len, 2088c2ecf20Sopenharmony_ci ST90TDS_CONFIG_PRFETCH_BIT, 2098c2ecf20Sopenharmony_ci ST90TDS_SRAM_DPORT_REG_ID); 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr, 2138c2ecf20Sopenharmony_ci void *buf, size_t buf_len) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci return cw1200_indirect_read(priv, addr, buf, buf_len, 2168c2ecf20Sopenharmony_ci ST90TDS_CONFIG_AHB_PRFETCH_BIT, 2178c2ecf20Sopenharmony_ci ST90TDS_AHB_DPORT_REG_ID); 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic inline int cw1200_apb_read_32(struct cw1200_common *priv, 2218c2ecf20Sopenharmony_ci u32 addr, u32 *val) 2228c2ecf20Sopenharmony_ci{ 2238c2ecf20Sopenharmony_ci __le32 tmp; 2248c2ecf20Sopenharmony_ci int i = cw1200_apb_read(priv, addr, &tmp, sizeof(tmp)); 2258c2ecf20Sopenharmony_ci *val = le32_to_cpu(tmp); 2268c2ecf20Sopenharmony_ci return i; 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_cistatic inline int cw1200_apb_write_32(struct cw1200_common *priv, 2308c2ecf20Sopenharmony_ci u32 addr, u32 val) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci __le32 tmp = cpu_to_le32(val); 2338c2ecf20Sopenharmony_ci return cw1200_apb_write(priv, addr, &tmp, sizeof(val)); 2348c2ecf20Sopenharmony_ci} 2358c2ecf20Sopenharmony_cistatic inline int cw1200_ahb_read_32(struct cw1200_common *priv, 2368c2ecf20Sopenharmony_ci u32 addr, u32 *val) 2378c2ecf20Sopenharmony_ci{ 2388c2ecf20Sopenharmony_ci __le32 tmp; 2398c2ecf20Sopenharmony_ci int i = cw1200_ahb_read(priv, addr, &tmp, sizeof(tmp)); 2408c2ecf20Sopenharmony_ci *val = le32_to_cpu(tmp); 2418c2ecf20Sopenharmony_ci return i; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci#endif /* CW1200_HWIO_H_INCLUDED */ 245