1*d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2a910e4a9SSolomon Peachy /* 3a910e4a9SSolomon Peachy * Low-level API for mac80211 ST-Ericsson CW1200 drivers 4a910e4a9SSolomon Peachy * 5a910e4a9SSolomon Peachy * Copyright (c) 2010, ST-Ericsson 6a910e4a9SSolomon Peachy * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no> 7a910e4a9SSolomon Peachy * 8a910e4a9SSolomon Peachy * Based on: 9a910e4a9SSolomon Peachy * ST-Ericsson UMAC CW1200 driver which is 10a910e4a9SSolomon Peachy * Copyright (c) 2010, ST-Ericsson 11a910e4a9SSolomon Peachy * Author: Ajitpal Singh <ajitpal.singh@stericsson.com> 12a910e4a9SSolomon Peachy */ 13a910e4a9SSolomon Peachy 14a910e4a9SSolomon Peachy #ifndef CW1200_HWIO_H_INCLUDED 15a910e4a9SSolomon Peachy #define CW1200_HWIO_H_INCLUDED 16a910e4a9SSolomon Peachy 17a910e4a9SSolomon Peachy /* extern */ struct cw1200_common; 18a910e4a9SSolomon Peachy 19a910e4a9SSolomon Peachy #define CW1200_CUT_11_ID_STR (0x302E3830) 20a910e4a9SSolomon Peachy #define CW1200_CUT_22_ID_STR1 (0x302e3132) 21a910e4a9SSolomon Peachy #define CW1200_CUT_22_ID_STR2 (0x32302e30) 22a910e4a9SSolomon Peachy #define CW1200_CUT_22_ID_STR3 (0x3335) 23a910e4a9SSolomon Peachy #define CW1200_CUT_ID_ADDR (0xFFF17F90) 24a910e4a9SSolomon Peachy #define CW1200_CUT2_ID_ADDR (0xFFF1FF90) 25a910e4a9SSolomon Peachy 26a910e4a9SSolomon Peachy /* Download control area */ 27a910e4a9SSolomon Peachy /* boot loader start address in SRAM */ 28a910e4a9SSolomon Peachy #define DOWNLOAD_BOOT_LOADER_OFFSET (0x00000000) 29a910e4a9SSolomon Peachy /* 32K, 0x4000 to 0xDFFF */ 30a910e4a9SSolomon Peachy #define DOWNLOAD_FIFO_OFFSET (0x00004000) 31a910e4a9SSolomon Peachy /* 32K */ 32a910e4a9SSolomon Peachy #define DOWNLOAD_FIFO_SIZE (0x00008000) 33a910e4a9SSolomon Peachy /* 128 bytes, 0xFF80 to 0xFFFF */ 34a910e4a9SSolomon Peachy #define DOWNLOAD_CTRL_OFFSET (0x0000FF80) 35a910e4a9SSolomon Peachy #define DOWNLOAD_CTRL_DATA_DWORDS (32-6) 36a910e4a9SSolomon Peachy 37a910e4a9SSolomon Peachy struct download_cntl_t { 38a910e4a9SSolomon Peachy /* size of whole firmware file (including Cheksum), host init */ 39a910e4a9SSolomon Peachy u32 image_size; 40a910e4a9SSolomon Peachy /* downloading flags */ 41a910e4a9SSolomon Peachy u32 flags; 42a910e4a9SSolomon Peachy /* No. of bytes put into the download, init & updated by host */ 43a910e4a9SSolomon Peachy u32 put; 44a910e4a9SSolomon Peachy /* last traced program counter, last ARM reg_pc */ 45a910e4a9SSolomon Peachy u32 trace_pc; 46a910e4a9SSolomon Peachy /* No. of bytes read from the download, host init, device updates */ 47a910e4a9SSolomon Peachy u32 get; 48a910e4a9SSolomon Peachy /* r0, boot losader status, host init to pending, device updates */ 49a910e4a9SSolomon Peachy u32 status; 50a910e4a9SSolomon Peachy /* Extra debug info, r1 to r14 if status=r0=DOWNLOAD_EXCEPTION */ 51a910e4a9SSolomon Peachy u32 debug_data[DOWNLOAD_CTRL_DATA_DWORDS]; 52a910e4a9SSolomon Peachy }; 53a910e4a9SSolomon Peachy 54a910e4a9SSolomon Peachy #define DOWNLOAD_IMAGE_SIZE_REG \ 55a910e4a9SSolomon Peachy (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, image_size)) 56a910e4a9SSolomon Peachy #define DOWNLOAD_FLAGS_REG \ 57a910e4a9SSolomon Peachy (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, flags)) 58a910e4a9SSolomon Peachy #define DOWNLOAD_PUT_REG \ 59a910e4a9SSolomon Peachy (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, put)) 60a910e4a9SSolomon Peachy #define DOWNLOAD_TRACE_PC_REG \ 61a910e4a9SSolomon Peachy (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, trace_pc)) 62a910e4a9SSolomon Peachy #define DOWNLOAD_GET_REG \ 63a910e4a9SSolomon Peachy (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, get)) 64a910e4a9SSolomon Peachy #define DOWNLOAD_STATUS_REG \ 65a910e4a9SSolomon Peachy (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, status)) 66a910e4a9SSolomon Peachy #define DOWNLOAD_DEBUG_DATA_REG \ 67a910e4a9SSolomon Peachy (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, debug_data)) 68a910e4a9SSolomon Peachy #define DOWNLOAD_DEBUG_DATA_LEN (108) 69a910e4a9SSolomon Peachy 70a910e4a9SSolomon Peachy #define DOWNLOAD_BLOCK_SIZE (1024) 71a910e4a9SSolomon Peachy 72a910e4a9SSolomon Peachy /* For boot loader detection */ 73a910e4a9SSolomon Peachy #define DOWNLOAD_ARE_YOU_HERE (0x87654321) 74a910e4a9SSolomon Peachy #define DOWNLOAD_I_AM_HERE (0x12345678) 75a910e4a9SSolomon Peachy 76a910e4a9SSolomon Peachy /* Download error code */ 77a910e4a9SSolomon Peachy #define DOWNLOAD_PENDING (0xFFFFFFFF) 78a910e4a9SSolomon Peachy #define DOWNLOAD_SUCCESS (0) 79a910e4a9SSolomon Peachy #define DOWNLOAD_EXCEPTION (1) 80a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_MEM_1 (2) 81a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_MEM_2 (3) 82a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_SOFTWARE (4) 83a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_FILE_SIZE (5) 84a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_CHECKSUM (6) 85a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_OVERFLOW (7) 86a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_IMAGE (8) 87a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_HOST (9) 88a910e4a9SSolomon Peachy #define DOWNLOAD_ERR_ABORT (10) 89a910e4a9SSolomon Peachy 90a910e4a9SSolomon Peachy 91a910e4a9SSolomon Peachy #define SYS_BASE_ADDR_SILICON (0) 92a910e4a9SSolomon Peachy #define PAC_BASE_ADDRESS_SILICON (SYS_BASE_ADDR_SILICON + 0x09000000) 93a910e4a9SSolomon Peachy #define PAC_SHARED_MEMORY_SILICON (PAC_BASE_ADDRESS_SILICON) 94a910e4a9SSolomon Peachy 95a910e4a9SSolomon Peachy #define CW1200_APB(addr) (PAC_SHARED_MEMORY_SILICON + (addr)) 96a910e4a9SSolomon Peachy 978b3e7be4SSolomon Peachy /* Device register definitions */ 988b3e7be4SSolomon Peachy 99a910e4a9SSolomon Peachy /* WBF - SPI Register Addresses */ 100a910e4a9SSolomon Peachy #define ST90TDS_ADDR_ID_BASE (0x0000) 101a910e4a9SSolomon Peachy /* 16/32 bits */ 102a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_REG_ID (0x0000) 103a910e4a9SSolomon Peachy /* 16/32 bits */ 104a910e4a9SSolomon Peachy #define ST90TDS_CONTROL_REG_ID (0x0001) 105a910e4a9SSolomon Peachy /* 16 bits, Q mode W/R */ 106a910e4a9SSolomon Peachy #define ST90TDS_IN_OUT_QUEUE_REG_ID (0x0002) 107a910e4a9SSolomon Peachy /* 32 bits, AHB bus R/W */ 108a910e4a9SSolomon Peachy #define ST90TDS_AHB_DPORT_REG_ID (0x0003) 109a910e4a9SSolomon Peachy /* 16/32 bits */ 110a910e4a9SSolomon Peachy #define ST90TDS_SRAM_BASE_ADDR_REG_ID (0x0004) 111a910e4a9SSolomon Peachy /* 32 bits, APB bus R/W */ 112a910e4a9SSolomon Peachy #define ST90TDS_SRAM_DPORT_REG_ID (0x0005) 113a910e4a9SSolomon Peachy /* 32 bits, t_settle/general */ 114a910e4a9SSolomon Peachy #define ST90TDS_TSET_GEN_R_W_REG_ID (0x0006) 115a910e4a9SSolomon Peachy /* 16 bits, Q mode read, no length */ 116a910e4a9SSolomon Peachy #define ST90TDS_FRAME_OUT_REG_ID (0x0007) 117a910e4a9SSolomon Peachy #define ST90TDS_ADDR_ID_MAX (ST90TDS_FRAME_OUT_REG_ID) 118a910e4a9SSolomon Peachy 119a910e4a9SSolomon Peachy /* WBF - Control register bit set */ 120a910e4a9SSolomon Peachy /* next o/p length, bit 11 to 0 */ 121a910e4a9SSolomon Peachy #define ST90TDS_CONT_NEXT_LEN_MASK (0x0FFF) 122a910e4a9SSolomon Peachy #define ST90TDS_CONT_WUP_BIT (BIT(12)) 123a910e4a9SSolomon Peachy #define ST90TDS_CONT_RDY_BIT (BIT(13)) 124a910e4a9SSolomon Peachy #define ST90TDS_CONT_IRQ_ENABLE (BIT(14)) 125a910e4a9SSolomon Peachy #define ST90TDS_CONT_RDY_ENABLE (BIT(15)) 126a910e4a9SSolomon Peachy #define ST90TDS_CONT_IRQ_RDY_ENABLE (BIT(14)|BIT(15)) 127a910e4a9SSolomon Peachy 128a910e4a9SSolomon Peachy /* SPI Config register bit set */ 129a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_FRAME_BIT (BIT(2)) 130a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_WORD_MODE_BITS (BIT(3)|BIT(4)) 131a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_WORD_MODE_1 (BIT(3)) 132a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_WORD_MODE_2 (BIT(4)) 133a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_ERROR_0_BIT (BIT(5)) 134a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_ERROR_1_BIT (BIT(6)) 135a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_ERROR_2_BIT (BIT(7)) 136a910e4a9SSolomon Peachy /* TBD: Sure??? */ 137a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_CSN_FRAME_BIT (BIT(7)) 138a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_ERROR_3_BIT (BIT(8)) 139a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_ERROR_4_BIT (BIT(9)) 140a910e4a9SSolomon Peachy /* QueueM */ 141a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_ACCESS_MODE_BIT (BIT(10)) 142a910e4a9SSolomon Peachy /* AHB bus */ 143a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_AHB_PRFETCH_BIT (BIT(11)) 144a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_CPU_CLK_DIS_BIT (BIT(12)) 145a910e4a9SSolomon Peachy /* APB bus */ 146a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_PRFETCH_BIT (BIT(13)) 147a910e4a9SSolomon Peachy /* cpu reset */ 148a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_CPU_RESET_BIT (BIT(14)) 149a910e4a9SSolomon Peachy #define ST90TDS_CONFIG_CLEAR_INT_BIT (BIT(15)) 150a910e4a9SSolomon Peachy 151a910e4a9SSolomon Peachy /* For CW1200 the IRQ Enable and Ready Bits are in CONFIG register */ 152a910e4a9SSolomon Peachy #define ST90TDS_CONF_IRQ_ENABLE (BIT(16)) 153a910e4a9SSolomon Peachy #define ST90TDS_CONF_RDY_ENABLE (BIT(17)) 154a910e4a9SSolomon Peachy #define ST90TDS_CONF_IRQ_RDY_ENABLE (BIT(16)|BIT(17)) 155a910e4a9SSolomon Peachy 156a910e4a9SSolomon Peachy int cw1200_data_read(struct cw1200_common *priv, 157a910e4a9SSolomon Peachy void *buf, size_t buf_len); 158a910e4a9SSolomon Peachy int cw1200_data_write(struct cw1200_common *priv, 159a910e4a9SSolomon Peachy const void *buf, size_t buf_len); 160a910e4a9SSolomon Peachy 161a910e4a9SSolomon Peachy int cw1200_reg_read(struct cw1200_common *priv, u16 addr, 162a910e4a9SSolomon Peachy void *buf, size_t buf_len); 163a910e4a9SSolomon Peachy int cw1200_reg_write(struct cw1200_common *priv, u16 addr, 164a910e4a9SSolomon Peachy const void *buf, size_t buf_len); 165a910e4a9SSolomon Peachy 166a910e4a9SSolomon Peachy static inline int cw1200_reg_read_16(struct cw1200_common *priv, 167a910e4a9SSolomon Peachy u16 addr, u16 *val) 168a910e4a9SSolomon Peachy { 1697258416cSSolomon Peachy __le32 tmp; 170a910e4a9SSolomon Peachy int i; 171a910e4a9SSolomon Peachy i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); 1727258416cSSolomon Peachy *val = le32_to_cpu(tmp) & 0xfffff; 173a910e4a9SSolomon Peachy return i; 174a910e4a9SSolomon Peachy } 175a910e4a9SSolomon Peachy 176a910e4a9SSolomon Peachy static inline int cw1200_reg_write_16(struct cw1200_common *priv, 177a910e4a9SSolomon Peachy u16 addr, u16 val) 178a910e4a9SSolomon Peachy { 1797258416cSSolomon Peachy __le32 tmp = cpu_to_le32((u32)val); 180a910e4a9SSolomon Peachy return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp)); 181a910e4a9SSolomon Peachy } 182a910e4a9SSolomon Peachy 183a910e4a9SSolomon Peachy static inline int cw1200_reg_read_32(struct cw1200_common *priv, 184a910e4a9SSolomon Peachy u16 addr, u32 *val) 185a910e4a9SSolomon Peachy { 1867258416cSSolomon Peachy __le32 tmp; 1877258416cSSolomon Peachy int i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); 1887258416cSSolomon Peachy *val = le32_to_cpu(tmp); 189a910e4a9SSolomon Peachy return i; 190a910e4a9SSolomon Peachy } 191a910e4a9SSolomon Peachy 192a910e4a9SSolomon Peachy static inline int cw1200_reg_write_32(struct cw1200_common *priv, 193a910e4a9SSolomon Peachy u16 addr, u32 val) 194a910e4a9SSolomon Peachy { 1957258416cSSolomon Peachy __le32 tmp = cpu_to_le32(val); 1967258416cSSolomon Peachy return cw1200_reg_write(priv, addr, &tmp, sizeof(val)); 197a910e4a9SSolomon Peachy } 198a910e4a9SSolomon Peachy 199a910e4a9SSolomon Peachy int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf, 200a910e4a9SSolomon Peachy size_t buf_len, u32 prefetch, u16 port_addr); 201a910e4a9SSolomon Peachy int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf, 202a910e4a9SSolomon Peachy size_t buf_len); 203a910e4a9SSolomon Peachy 204a910e4a9SSolomon Peachy static inline int cw1200_apb_read(struct cw1200_common *priv, u32 addr, 205a910e4a9SSolomon Peachy void *buf, size_t buf_len) 206a910e4a9SSolomon Peachy { 207a910e4a9SSolomon Peachy return cw1200_indirect_read(priv, addr, buf, buf_len, 208a910e4a9SSolomon Peachy ST90TDS_CONFIG_PRFETCH_BIT, 209a910e4a9SSolomon Peachy ST90TDS_SRAM_DPORT_REG_ID); 210a910e4a9SSolomon Peachy } 211a910e4a9SSolomon Peachy 212a910e4a9SSolomon Peachy static inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr, 213a910e4a9SSolomon Peachy void *buf, size_t buf_len) 214a910e4a9SSolomon Peachy { 215a910e4a9SSolomon Peachy return cw1200_indirect_read(priv, addr, buf, buf_len, 216a910e4a9SSolomon Peachy ST90TDS_CONFIG_AHB_PRFETCH_BIT, 217a910e4a9SSolomon Peachy ST90TDS_AHB_DPORT_REG_ID); 218a910e4a9SSolomon Peachy } 219a910e4a9SSolomon Peachy 220a910e4a9SSolomon Peachy static inline int cw1200_apb_read_32(struct cw1200_common *priv, 221a910e4a9SSolomon Peachy u32 addr, u32 *val) 222a910e4a9SSolomon Peachy { 2237258416cSSolomon Peachy __le32 tmp; 2247258416cSSolomon Peachy int i = cw1200_apb_read(priv, addr, &tmp, sizeof(tmp)); 2257258416cSSolomon Peachy *val = le32_to_cpu(tmp); 226a910e4a9SSolomon Peachy return i; 227a910e4a9SSolomon Peachy } 228a910e4a9SSolomon Peachy 229a910e4a9SSolomon Peachy static inline int cw1200_apb_write_32(struct cw1200_common *priv, 230a910e4a9SSolomon Peachy u32 addr, u32 val) 231a910e4a9SSolomon Peachy { 2327258416cSSolomon Peachy __le32 tmp = cpu_to_le32(val); 2337258416cSSolomon Peachy return cw1200_apb_write(priv, addr, &tmp, sizeof(val)); 234a910e4a9SSolomon Peachy } 235a910e4a9SSolomon Peachy static inline int cw1200_ahb_read_32(struct cw1200_common *priv, 236a910e4a9SSolomon Peachy u32 addr, u32 *val) 237a910e4a9SSolomon Peachy { 2387258416cSSolomon Peachy __le32 tmp; 2397258416cSSolomon Peachy int i = cw1200_ahb_read(priv, addr, &tmp, sizeof(tmp)); 2407258416cSSolomon Peachy *val = le32_to_cpu(tmp); 241a910e4a9SSolomon Peachy return i; 242a910e4a9SSolomon Peachy } 243a910e4a9SSolomon Peachy 244a910e4a9SSolomon Peachy #endif /* CW1200_HWIO_H_INCLUDED */ 245