• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef HIFMC100_H
17 #define HIFMC100_H
18 
19 #include "hdf_base.h"
20 #include "mtd_spi_common.h"
21 #include "osal_mutex.h"
22 #include "osal_io.h"
23 #include "hisoc/flash.h"
24 
25 struct HifmcCntlr {
26     volatile void *regBase;
27     uint32_t regBasePhy;
28     uint32_t regSize;
29     volatile uint8_t *memBase;
30     uint32_t memBasePhy;
31     uint32_t memSize;
32     uint8_t *buffer;
33     uint8_t *dmaBuffer;
34     size_t bufferSize;
35     int32_t chipNum;
36     unsigned int flashType;
37     struct OsalMutex mutex;
38     size_t pageSize;
39     size_t oobSize;
40     int eccType;
41     struct SpiFlash *curDev;
42     unsigned int cfg;
43     const struct DeviceResourceNode *drsNode;
44 };
45 
46 #define HIFMC_SPI_NOR_CS_NUM                     0
47 
48 #define HIFMC_DMA_ALIGN_SIZE                     (CACHE_ALIGNED_SIZE)
49 #define HIFMC_DMA_ALIGN_MASK                     (HIFMC_DMA_ALIGN_SIZE - 1)
50 #define HIFMC_DMA_MAX_SIZE                       4096
51 #define HIFMC_DMA_MAX_MASK                       (HIFMC_DMA_MAX_SIZE - 1)
52 
53 #define HIFMC_REG_READ(_cntlr, _reg) \
54     OSAL_READL((uintptr_t)((uint8_t *)(_cntlr)->regBase + (_reg)))
55 
56 #define HIFMC_REG_WRITE(_cntlr, _value, _reg) \
57     OSAL_WRITEL((unsigned long)(_value), (uintptr_t)((uint8_t *)(_cntlr)->regBase + (_reg)))
58 
59 // ********* 0x0000 FMC_CFG ****************************************************************
60 #define HIFMC_CFG_REG_OFF                            0x00
61 #define HIFMC_CFG_SPI_NAND_SEL(type)                 (((type) & 0x3) << 11)
62 #define HIFMC_CFG_SPI_NOR_ADDR_MODE(mode)            ((mode) << 10)
63 #define HIFMC_CFG_BLOCK_SIZE(size)                   (((size) & 0x3) << 8)
64 #define HIFMC_CFG_OP_MODE(mode)                      ((mode) & 0x1)
65 
66 #define HIFMC_SPI_NOR_ADDR_MODE_SHIFT                10
67 #define HIFMC_SPI_NOR_ADDR_MODE_MASK                 (0x1 << HIFMC_SPI_NOR_ADDR_MODE_SHIFT)
68 
69 // option mode
70 #define HIFMC_OP_MODE_BOOT                           0x0
71 #define HIFMC_OP_MODE_NORMAL                         0x1
72 #define HIFMC_OP_MODE_MASK                           0x1
73 
74 // page config
75 #define HIFMC_PAGE_SIZE_SHIFT                        3
76 #define HIFMC_PAGE_SIZE_MASK                         (0x3 << HIFMC_PAGE_SIZE_SHIFT)
77 #define HIFMC_CFG_PAGE_SIZE(size)                    (((size) & 0x3) << HIFMC_PAGE_SIZE_SHIFT)
78 
79 // ecc config
80 #define HIFMC_ECC_TYPE_SHIFT                         5
81 #define HIFMC_ECC_TYPE_MASK                          (0x7 << HIFMC_ECC_TYPE_SHIFT)
82 #define HIFMC_CFG_ECC_TYPE(type)                     (((type) & 0x7) << 5)
83 
84 // others
85 #define HIFMC_CFG_TYPE_SHIFT                         1
86 #define HIFMC_CFG_TYPE_MASK                          (0x3 << HIFMC_CFG_TYPE_SHIFT)
87 #define HIFMC_CFG_TYPE_SEL(type)                     (((type) & 0x3) << HIFMC_CFG_TYPE_SHIFT)
88 #define HIFMC_CFG_TYPE_SPI_NOR                       0x0
89 #define HIFMC_CFG_TYPE_SPI_NAND                      0x1
90 #define HIFMC_CFG_TYPE_NAND                          0x2
91 #define HIFMC_CFG_TYPE_DEFAULT                       0x3
92 
93 enum HifmcPageSizeRegConfig {
94     HIFMC_PAGE_SIZE_2K    = 0x0,
95     HIFMC_PAGE_SIZE_4K    = 0x1,
96     HIFMC_PAGE_SIZE_8K    = 0x2,
97     HIFMC_PAGE_SIZE_16K   = 0x3,
98 };
99 
100 enum HifmcEccTypeRegConfig {
101     HIFMC_ECC_0BIT     = 0x00,
102     HIFMC_ECC_8BIT     = 0x01,
103     HIFMC_ECC_16BIT    = 0x02,
104     HIFMC_ECC_24BIT    = 0x03,
105     HIFMC_ECC_28BIT    = 0x04,
106     HIFMC_ECC_40BIT    = 0x05,
107     HIFMC_ECC_64BIT    = 0x06,
108 };
109 
110 // ********* 0x0004 GLOBAL_CFG ************************************************************
111 #define HIFMC_GLOBAL_CFG_REG_OFF                     0x4
112 #define HIFMC_GLOBAL_CFG_WP_ENABLE                   (1 << 6)
113 
114 // ********* 0x0008 TIMING_SPI_CFG ********************************************************
115 #define HIFMC_SPI_TIMING_CFG_REG_OFF                 0x08
116 #define HIFMC_SPI_TIMING_CFG_TCSH(n)                 (((n) & 0xf) << 8)
117 #define HIFMC_SPI_TIMING_CFG_TCSS(n)                 (((n) & 0xf) << 4)
118 #define HIFMC_SPI_TIMING_CFG_TSHSL(n)                ((n) & 0xf)
119 #define HIFMC_SPI_CFG_CS_HOLD                        0x6
120 #define HIFMC_SPI_CFG_CS_SETUP                       0x6
121 #define HIFMC_SPI_CFG_CS_DESELECT                    0xf
122 
123 // ********* 0x0018 FMC_INT ***************************************************************
124 #define HIFMC_INT_REG_OFF                            0x18
125 #define HIFMC_INT_AHB_OP                             (1 << 7)
126 #define HIFMC_INT_WR_LOCK                            (1 << 6)
127 #define HIFMC_INT_DMA_ERR                            (1 << 5)
128 #define HIFMC_INT_ERR_ALARM                          (1 << 4)
129 #define HIFMC_INT_ERR_INVALID                        (1 << 3)
130 #define HIFMC_INT_ERR_VALID                          (1 << 2)
131 #define HIFMC_INT_OP_FAIL                            (1 << 1)
132 #define HIFMC_INT_OP_DONE                            (1 << 0)
133 
134 // ********* 0x001c FMC_INT_EN ************************************************************
135 #define HIFMC_INT_EN_REG_OFF                         0x1c
136 #define HIFMC_INT_EN_AHB_OP                          (1 << 7)
137 #define HIFMC_INT_EN_WR_LOCK                         (1 << 6)
138 #define HIFMC_INT_EN_DMA_ERR                         (1 << 5)
139 #define HIFMC_INT_EN_ERR_ALARM                       (1 << 4)
140 #define HIFMC_INT_EN_ERR_INVALID                     (1 << 3)
141 #define HIFMC_INT_EN_ERR_VALID                       (1 << 2)
142 #define HIFMC_INT_EN_OP_FAIL                         (1 << 1)
143 #define HIFMC_INT_EN_OP_DONE                         (1 << 0)
144 
145 // ********* 0x0020 FMC_INT_CLR ***********************************************************
146 #define HIFMC_INT_CLR_REG_OFF                        0x20
147 #define HIFMC_INT_CLR_AHB_OP                         (1 << 7)
148 #define HIFMC_INT_CLR_WR_LOCK                        (1 << 6)
149 #define HIFMC_INT_CLR_DMA_ERR                        (1 << 5)
150 #define HIFMC_INT_CLR_ERR_ALARM                      (1 << 4)
151 #define HIFMC_INT_CLR_ERR_INVALID                    (1 << 3)
152 #define HIFMC_INT_CLR_ERR_VALID                      (1 << 2)
153 #define HIFMC_INT_CLR_OP_FAIL                        (1 << 1)
154 #define HIFMC_INT_CLR_OP_DONE                        (1 << 0)
155 #define HIFMC_INT_CLR_ALL                            0xff
156 
157 // ********* 0x0024 FMC_CMD ***************************************************************
158 #define HIFMC_CMD_REG_OFF                            0x24
159 #define HIFMC_CMD_CMD1(cmd)                          ((cmd) & 0xff)
160 #define HIFMC_CMD_CMD2(cmd)                          (((cmd) & 0xff) << 8)
161 
162 // ********* 0x0028 FMC_ADDRH *************************************************************
163 #define HIFMC_ADDRH_REG_OFF                          0x28
164 // ********* 0x002c FMC_ADDRL *************************************************************
165 #define HIFMC_ADDRL_REG_OFF                          0x2c
166 
167 // ********* 0x0030 FMC_OP_CFG ************************************************************
168 #define HIFMC_OP_CFG_REG_OFF                         0x30
169 #define HIFMC_OP_CFG_FM_CS(cs)                       ((cs) << 11)
170 #define HIFMC_OP_CFG_FORCE_CS_EN(en)                 ((en) << 10)
171 #define HIFMC_OP_CFG_MEM_IF_TYPE(type)               (((type) & 0x7) << 7)
172 #define HIFMC_OP_CFG_ADDR_NUM(addr)                  (((addr) & 0x7) << 4)
173 #define HIFMC_OP_CFG_DUMMY_NUM(dummy)                ((dummy) & 0xf)
174 
175 // ********* 0x0034 SPI_OP_ADDR ***********************************************************
176 #define HIFMC_SPI_OP_ADDR_REG_OFF                    0x34
177 
178 // ********* 0x0038 FMC_DATA_NUM **********************************************************
179 #define HIFMC_DATA_NUM_REG_OFF                       0x38
180 #define HIFMC_DATA_NUM_CNT(n)                        ((n) & 0x3fff)
181 
182 // ********* 0x003c FMC_OP ****************************************************************
183 #define HIFMC_OP_REG_OFF                             0x3c
184 #define HIFMC_OP_DUMMY_EN(en)                        ((en) << 8)
185 #define HIFMC_OP_CMD1_EN(en)                         ((en) << 7)
186 #define HIFMC_OP_ADDR_EN(en)                         ((en) << 6)
187 #define HIFMC_OP_WRITE_DATA_EN(en)                   ((en) << 5)
188 #define HIFMC_OP_CMD2_EN(en)                         ((en) << 4)
189 #define HIFMC_OP_WAIT_READY_EN(en)                   ((en) << 3)
190 #define HIFMC_OP_READ_DATA_EN(en)                    ((en) << 2)
191 #define HIFMC_OP_READ_STATUS_EN(en)                  ((en) << 1)
192 #define HIFMC_OP_REG_OP_START                        1
193 
194 // ********* 0x0040 FMC_DATA_LEN **********************************************************
195 #define HIFMC_DMA_LEN_REG_OFF                        0x40
196 #define HIFMC_DMA_LEN_SET(len)                       ((len) & 0x0fffffff)
197 
198 // ********* 0x0048 FMC_DMA_AHB_CTRL ******************************************************
199 #define HIFMC_DMA_AHB_CTRL_REG_OFF                   0x48
200 #define HIFMC_DMA_AHB_CTRL_DMA_PP_EN                 (1 << 3)
201 #define HIFMC_DMA_AHB_CTRL_BURST16_EN                (1 << 2)
202 #define HIFMC_DMA_AHB_CTRL_BURST8_EN                 (1 << 1)
203 #define HIFMC_DMA_AHB_CTRL_BURST4_EN                 (1 << 0)
204 #define HIFMC_ALL_BURST_ENABLE                       (HIFMC_DMA_AHB_CTRL_BURST16_EN \
205                                                      | HIFMC_DMA_AHB_CTRL_BURST8_EN \
206                                                      | HIFMC_DMA_AHB_CTRL_BURST4_EN)
207 
208 // ********* 0x004c FMC_DMA_SADDR_D0 ******************************************************
209 #define HIFMC_DMA_SADDR_D0_REG_OFF                   0x4c
210 #define HIFMC_DMA_SADDRH_D0                          0x200
211 #define HIFMC_DMA_SADDRH_OOB_OOFSET                  0x210
212 #define HIFMC_DMA_ADDR_OFFSET                        4096
213 
214 // ********* 0x005c FMC_DMA_SADDR_OOB *****************************************************
215 #define HIFMC_DMA_SADDR_OOB_REG_OFF                  0x5c
216 
217 // ********* 0x0068 FMC_OP_CTRL ***********************************************************
218 #define HIFMC_OP_CTRL_REG_OFF                        0x68
219 #define HIFMC_OP_CTRL_RD_OPCODE(code)                (((code) & 0xff) << 16)
220 #define HIFMC_OP_CTRL_WR_OPCODE(code)                (((code) & 0xff) << 8)
221 #define HIFMC_OP_CTRL_RW_OP(op)                      ((op) << 1)
222 #define HIFMC_OP_CTRL_RD_OP_SEL(op)                  (((op) & 0x3) << 4)
223 #define HIFMC_OP_CTRL_DMA_OP(type)                   ((type) << 2)
224 #define HIFMC_OP_CTRL_DMA_OP_READY                   1
225 #define HIFMC_OP_CTRL_TYPE_DMA                       0
226 #define HIFMC_OP_CTRL_TYPE_REG                       1
227 #define HIFMC_OP_CTRL_OP_READ                        0
228 #define HIFMC_OP_CTRL_OP_WRITE                       1
229 
230 // ********* 0x006c FMC_TIMEOUT_WR ********************************************************
231 
232 // ********* 0x0070 FMC_OP_PARA ***********************************************************
233 #define HIFMC_OP_PARA_REG_OFF                        0x70
234 #define HIFMC_OP_PARA_RD_OOB_ONLY                    (1 << 1)
235 
236 // ********* 0x0074 FMC_BOOT_SEL **********************************************************
237 #define HIFMC_BOOT_SET_REG_OFF                       0x74
238 #define HIFMC_BOOT_SET_DEVICE_ECC_EN                 (1 << 3)
239 #define HIFMC_BOOT_SET_BOOT_QUAD_EN                  (1 << 1)
240 
241 // ********* 0x0078 FMC_LP_CTRL ***********************************************************
242 
243 // ********* 0x00a8 FMC_ERR_THD ***********************************************************
244 
245 // ********* 0x00ac FMC_FLASH_INFO ********************************************************
246 #define HIFMC_FLASH_INFO_REG_OFF                     0xac
247 
248 // ********* 0x00bc FMC_VERSION ***********************************************************
249 #define HIFMC_VERSION_REG_OFF                        0xbc
250 
251 // ********* 0x00c0 FMC_ERR_NUM0_BUF0 *****************************************************
252 
253 // ********* 0x00d0 FMC_ERR_ALARM_ADDRH ***************************************************
254 
255 // ********* 0x00d4 FMC_ERR_ALARM_ADDRL ***************************************************
256 
257 // ********* 0x00d8 FMC_ECC_INVALID_ADDRH *************************************************
258 
259 // ********* 0x00dc FMC_ECC_INVALID_ADDRL *************************************************
260 
261 #define HIFMC_CPU_WAIT_TIMEOUT                       0x800000
262 #define HIFMC_DMA_WAIT_TIMEOUT                       0xf0000000
263 
264 #define HIFMC_CMD_WAIT_CPU_FINISH(cntlr) \
265     do { \
266         unsigned int regval, timeout = HIFMC_CPU_WAIT_TIMEOUT; \
267         do { \
268             regval = HIFMC_REG_READ((cntlr), HIFMC_OP_REG_OFF); \
269             --timeout; \
270         } while ((regval & HIFMC_OP_REG_OP_START) && timeout); \
271         if (!timeout) \
272             HDF_LOGE("%s: wait cmd cpu finish timeout(0x%x)", __func__, regval); \
273     } while (0)
274 
275 
276 #define HIFMC_DMA_WAIT_INT_FINISH(cntlr) \
277     do { \
278         unsigned int regval, timeout = HIFMC_DMA_WAIT_TIMEOUT; \
279         do { \
280             regval = HIFMC_REG_READ((cntlr), HIFMC_INT_REG_OFF); \
281             --timeout; \
282         } while (!(regval & HIFMC_INT_OP_DONE) && timeout); \
283         if (!timeout) \
284             HDF_LOGE("%s: wait dma int finish timeout(0x%x)", __func__, regval); \
285     } while (0)
286 
287 #define HIFMC_DMA_WAIT_CPU_FINISH(cntlr) \
288     do { \
289         unsigned long regval, timeout = HIFMC_CPU_WAIT_TIMEOUT; \
290         do { \
291             regval = HIFMC_REG_READ((cntlr), HIFMC_OP_CTRL_REG_OFF); \
292             --timeout; \
293         } while ((regval & HIFMC_OP_CTRL_DMA_OP_READY) && timeout); \
294         if (!timeout) \
295             HDF_LOGE("%s: wait dma cpu finish timeout(0x%x)", __func__, regval); \
296     } while (0)
297 
298 uint8_t HifmcCntlrReadDevReg(struct HifmcCntlr *cntlr, struct SpiFlash *spi, uint8_t cmd);
299 
300 void HifmcCntlrSet4AddrMode(struct HifmcCntlr *cntlr, int enable);
301 
302 const struct DeviceResourceNode *HifmcCntlrGetDevTableNode(struct HifmcCntlr *cntlr);
303 
304 int32_t HifmcCntlrReadSpiOp(struct MtdSpiConfig *cfg, const struct DeviceResourceNode *node);
305 
HifmcCntlrSetSysClock(struct HifmcCntlr * cntlr,unsigned int clock,int clkEn)306 static inline int32_t HifmcCntlrSetSysClock(struct HifmcCntlr *cntlr, unsigned int clock, int clkEn)
307 {
308     (void)cntlr;
309     hifmc100_set_system_clock(clock, clkEn);
310     return HDF_SUCCESS;
311 }
312 
313 void MtdDmaCacheClean(void *addr, size_t size);
314 
315 void MtdDmaCacheInv(void *addr, size_t size);
316 
317 #endif /* HIFMC100_H */
318