Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / build / magpie_1_1 / sboot / cmnos / sflash / src / cmnos_sflash.c
1 #include "sys_cfg.h"
2 #include "athos_api.h"
3
4 #if SYSTEM_MODULE_SFLASH
5
6 #include "reg_defs.h"
7 #include "sflash_api.h"
8
9 /*******************************************
10  * Definitions of module internal constant *
11  *******************************************/
12
13 /* Definitions of base address and Flash sise -> Project dependent */
14 #define ZM_SPI_REGISTER_BASE            SPI_REG_BASE_ADDRESS    /* 0x0005B000 */
15 #define ZM_SPI_FLASH_BASE               SPI_FLASH_BASE          /* 0x0F000000 */
16 #define ZM_SPI_FLASH_MAX_ADDR           SPI_FLASH_MAX_ADDR      /* 0x0FFFFFFF */
17 #define ZM_SPI_FLASH_MAX_SIZE           SPI_FLASH_MAX_SIZE      /* 0x01000000 */
18
19 /*
20  * Base address of Clock and Reset Control Registers is 0x00050000
21  * Offset of Clock Control Register is 0x40
22  * SPI_SEL (bit 8) : Switch the function of I/O pin 19~22 between GPIO and SPI.
23  *                   0 -> act as GPIO5~8;
24  *                   1 -> act as SPI pins.
25  */
26 #define ZM_SPI_CLK_CTRL_ADDR            0x00050040
27 #define ZM_SPI_SPI_SEL_BIT              0x100
28
29 /* Definitions of Serial Flash constants -> According to standard or vendor dependent */
30 #define ZM_SFLASH_PAGE_SIZE             256
31
32 /* Definitions of OP Code -> According to standard or vendor dependent */
33 #define ZM_SFLASH_OP_READ               0x03    /* Read Data Bytes */
34 #define ZM_SFLASH_OP_FAST_READ          0x0B    /* Read Data Bytes at Higher Speed */
35 /*
36  * For MXIC,     sector erase : Command 0x20, size 4K bytes
37  *               block erase  : Command 0xD8, size 64K bytes
38  *               chip earse   : command 0x60 or 0xC7
39  * For Spansion, sector erase : Command 0x20 or 0xD8, size 64K bytes (For 64 KB sector devices, either command is valid and performs the same function.)
40  *               block erase  : Command 0xD8, size 256K bytes
41  *               chip earse   : command 0x60 or 0xC7, Uniform 64 KB Sector Product (For 64 KB sector devices, either command is valid and performs the same function.)
42  *                                      0xC7, Uniform 256 KB Sector Product
43  */
44 #define ZM_SFLASH_OP_SE                 0x20    /* Sector Erase */
45 #define ZM_SFLASH_OP_BE                 0xD8    /* Block Erase */
46 #define ZM_SFLASH_OP_CE                 0xC7    /* Chip Erase */
47 #define ZM_SFLASH_OP_PP                 0x02    /* Page Program */
48 #define ZM_SFLASH_OP_RDSR               0x05    /* Read from Status Register */
49 #define ZM_SFLASH_OP_WRSR               0x01    /* Write to Status Register */
50 #define ZM_SFLASH_OP_WREN               0x06    /* Write Enable */
51 #define ZM_SFLASH_OP_WRDI               0x04    /* Write Disable */
52 #define ZM_SFLASH_OP_RDID               0x9F    /* Read Identification */
53 #define ZM_SFLASH_OP_DP                 0xB9    /* Deep Power Down */
54 #define ZM_SFLASH_OP_RES                0xAB    /* Release from Deep Power Down, Release from Deep Power Down and Read Electronic Signature */
55
56 /* Definitions of Status Register -> According to standard or vendor dependent */
57 /* Write in progress bit
58  *  1 = Device Busy. A Write Status Register, program, or erase operation is in progress
59  *  0 = Ready. Device is in standby mode and can accept commands.
60  */
61 #define ZM_SFLASH_STATUS_REG_WIP        (1<<0)
62 /* Write enable latch bit
63  *  1 = Device accepts Write Status Register, program, or erase commands
64  *  0 = Ignores Write Status Register, program, or erase commands
65  */
66 #define ZM_SFLASH_STATUS_REG_WEL        (1<<1)
67 /* Status register write disable bit
68  *  1 = Protects when WP#/ACC is low
69  *  0 = No protection, even when WP#/ACC is low
70  */
71 #define ZM_SFLASH_STATUS_REG_SRWD       (1<<7)
72
73 /* Definitions of SPI Flash Controller -> SPI Flash Controller dependent */
74 /* SPI Flash Controller used in K2 project is part of Falcon's "Driver Support Logic" (DSL) block */
75 /*
76  *  Offset                              Register
77  *  ======      ==========================================================
78  *  0x0000      SPI control/status register (SPI_CS)
79  *  0x0004      SPI address/opcode register (SPI_AO)
80  *  0x0008      SPI data register (SPI_D)
81  */
82
83 /*
84  *  SPI control/status register (SPI_CS)
85  *  Access: R/W
86  *  Cold reset: (See field descriptions)
87  *  Warm reset: (Same as cold reset)
88  *  Notes:
89  *
90  *  3:0   - Transmit byte count.  Determines the number of bytes
91  *      transmitted from Falcon to the SPI device.  Values of 1-8 are
92  *      valid; other values are illegal.  See the 'Notes' section below
93  *      for details on how to use this field.  Resets to an undefined
94  *      value.
95  *  7:4   - Receive byte count.  Determines the number of bytes received
96  *      from the SPI device into Falcon.  Values of 0-8 are valid;
97  *      other values are illegal.  See the 'Notes' section below for
98  *      details on how to use this field.  Resets to an undefined
99  *      value.
100  *  8     - SPI transaction start.  Only writes to this field are
101  *      meaningful; reads always return 0.  Resets to 0x0.  For writes:
102  *        * A write of '1' starts the SPI transaction defined by the
103  *          transmit byte count, receive byte count, SPI_AO, and SPI_D
104  *          registers.
105  *        * A write of '0' has no effect
106  *  9     - SPI chip select 1 enable.  Resets to 0x0.  See bug 12540.
107  *            0 - SP0 is enabled and SP1 is forced inactive.
108  *            1 - SP1 is enabled and SP0 is forced inactive.
109  *  15:10 - Reserved
110  *  16    - Transaction busy indication.  Read-only; writes to this bit are
111  *      ignored.  Resets to 0x0.
112  *        0 - No SPI transaction is ongoing.  Software may start a new
113  *        SPI transaction by writing to the 'SPI transaction start'
114  *        bit within this register.
115  *        1 - An SPI transaction presently is underway.  Software must
116  *        not try to start a new SPI transaction, nor may software
117  *        alter the value of any field of the SPI_CS, SPI_AO, or
118  *        SPI_D registers.
119  *  18:17 - Automatically-determined SPI address size.  Read-only; writes
120  *      to this bit are ignored.  Resets to an undefined value, but
121  *      then is updated after the autosizing process completes.
122  *        0 - SPI address size was determined to be 16 bits
123  *        1 - SPI address size was determined to be 24 bits
124  *        2 - Reserved
125  *        3 - Automatic SPI address size determination failed.  Typical
126  *        causes of this result:
127  *          * The SPI device is missing
128  *          * The SPI device is unprogrammed
129  *          * The SPI device is programmed with an incorrect
130  *            SPI_MAGIC value
131  *  20:19 - SPI autosize override.  Resets to 0x0.
132  *        0 - Use automatically-determined SPI address size (see bits
133  *        [18:17] of this register)
134  *        1 - Force SPI address size to 16 bits
135  *        2 - Force SPI address size to 24 bits
136  *        3 - Reserved
137  *  31:21 - Reserved
138  */
139
140 #define SPI_CS_ADDRESS                      MAGPIE_REG_SPI_CS_ADDR //(ZM_SPI_REGISTER_BASE + 0x00000000)
141 /* 3:0 - Transmit byte count, values of 1-8 are valid */
142 #define SPI_CS_TXBCNT_MSB                   3
143 #define SPI_CS_TXBCNT_LSB                   0
144 #define SPI_CS_TXBCNT_MASK                  0x0000000f
145 #define SPI_CS_TXBCNT_GET(x)                (((x) & SPI_CS_TXBCNT_MASK) >> SPI_CS_TXBCNT_LSB)
146 #define SPI_CS_TXBCNT_SET(x)                (((0x0 | (x)) << SPI_CS_TXBCNT_LSB) & SPI_CS_TXBCNT_MASK)
147
148 /* 7:4 - Receive byte count, values of 1-8 are valid */
149 #define SPI_CS_RXBCNT_MSB                   7
150 #define SPI_CS_RXBCNT_LSB                   4
151 #define SPI_CS_RXBCNT_MASK                  0x000000f0
152 #define SPI_CS_RXBCNT_GET(x)                (((x) & SPI_CS_RXBCNT_MASK) >> SPI_CS_RXBCNT_LSB)
153 #define SPI_CS_RXBCNT_SET(x)                (((0x0 | (x)) << SPI_CS_RXBCNT_LSB) & SPI_CS_RXBCNT_MASK)
154
155 /* 8 - SPI transaction start */
156 #define SPI_CS_XCNSTART_MSB                 8
157 #define SPI_CS_XCNSTART_LSB                 8
158 #define SPI_CS_XCNSTART_MASK                0x00000100
159 #define SPI_CS_XCNSTART_GET(x)              0x0
160 #define SPI_CS_XCNSTART_SET(x)              (((0x0 | (x)) << SPI_CS_XCNSTART_LSB) & SPI_CS_XCNSTART_MASK)
161 #define SPI_CS_XCNSTART_RESET               0x0
162
163 /* 9 - SPI chip select */
164 #define SPI_CS_CS_MSB                       9
165 #define SPI_CS_CS_LSB                       9
166 #define SPI_CS_CS_MASK                      0x00000200
167 #define SPI_CS_CS_GET(x)                    (((x) & SPI_CS_CS_MASK) >> SPI_CS_CS_LSB)
168 #define SPI_CS_CS_SET(x)                    (((0x0 | (x)) << SPI_CS_CS_LSB) & SPI_CS_CS_MASK)
169 #define SPI_CS_CS_RESET                     0x0
170
171 /* 16 - Transaction busy indication */
172 #define SPI_CS_BUSY_MSB                     16
173 #define SPI_CS_BUSY_LSB                     16
174 #define SPI_CS_BUSY_MASK                    0x00010000
175 #define SPI_CS_BUSY_GET(x)                  (((x) & SPI_CS_BUSY_MASK) >> SPI_CS_BUSY_LSB)
176 #define SPI_CS_BUSY_SET(x)                  (((0x0 | (x)) << SPI_CS_BUSY_LSB) & SPI_CS_BUSY_MASK)
177 #define SPI_CS_BUSY_RESET                   0x0
178
179 /* 18:17 - Automatically-determined SPI address size */
180 #define SPI_CS_AUTOSIZ_MSB                  18
181 #define SPI_CS_AUTOSIZ_LSB                  17
182 #define SPI_CS_AUTOSIZ_MASK                 0x00060000
183 #define SPI_CS_AUTOSIZ_GET(x)               (((x) & SPI_CS_AUTOSIZ_MASK) >> SPI_CS_AUTOSIZ_LSB)
184 #define SPI_CS_AUTOSIZ_SET(x)               (((0x0 | (x)) << SPI_CS_AUTOSIZ_LSB) & SPI_CS_AUTOSIZ_MASK)
185
186 /* 20:19 - SPI autosize override */
187 #define SPI_CS_AUTOSIZ_OVR_MSB              20
188 #define SPI_CS_AUTOSIZ_OVR_LSB              19
189 #define SPI_CS_AUTOSIZ_OVR_MASK             0x00180000
190 #define SPI_CS_AUTOSIZ_OVR_GET(x)           (((x) & SPI_CS_AUTOSIZ_OVR_MASK) >> SPI_CS_AUTOSIZ_OVR_LSB)
191 #define SPI_CS_AUTOSIZ_OVR_SET(x)           (((0x0 | (x)) << SPI_CS_AUTOSIZ_OVR_LSB) & SPI_CS_AUTOSIZ_OVR_MASK)
192 #define SPI_CS_AUTOSIZ_OVR_RESET            0x0
193
194 #define SPI_CS_RESET                        (0x0 | \
195                                             SPI_CS_AUTOSIZ_OVR_SET(SPI_CS_AUTOSIZ_OVR_RESET) | \
196                                             SPI_CS_BUSY_SET(SPI_CS_BUSY_RESET) | \
197                                             SPI_CS_CS_SET(SPI_CS_CS_RESET) | \
198                                             SPI_CS_XCNSTART_SET(SPI_CS_XCNSTART_RESET))
199
200 /*
201  *  SPI address/opcode register (SPI_AO)
202  *  Access: R/W
203  *  Cold reset: (See field descriptions)
204  *  Warm reset: (Same as cold reset)
205  *  Notes:
206  *
207  *  7:0   - SPI opcode.  Usually this field specifies the 8-bit opcode
208  *      (aka "instruction") to transmit to the SPI device as the first
209  *      part of an SPI transaction.  See the 'Notes' section below for
210  *      more details. Resets to an undefined value.
211  *  31:8  - Address.  Usually this field specifies the 24-bit address to
212  *      transmit to the SPI device. See the 'Notes' section below for
213  *      more details. Resets to an undefined value.
214  */
215
216 #define SPI_AO_ADDRESS                      MAGPIE_REG_SPI_AO_ADDR //(ZM_SPI_REGISTER_BASE + 0x00000004)
217 /* 7:0 - SPI opcode */
218 #define SPI_AO_OPC_MSB                      7
219 #define SPI_AO_OPC_LSB                      0
220 #define SPI_AO_OPC_MASK                     0x000000ff
221 #define SPI_AO_OPC_GET(x)                   (((x) & SPI_AO_OPC_MASK) >> SPI_AO_OPC_LSB)
222 #define SPI_AO_OPC_SET(x)                   (((0x0 | (x)) << SPI_AO_OPC_LSB) & SPI_AO_OPC_MASK)
223 /* 31:8 - Address */
224 #define SPI_AO_ADDR_MSB                     31
225 #define SPI_AO_ADDR_LSB                     8
226 #define SPI_AO_ADDR_MASK                    0xffffff00
227 #define SPI_AO_ADDR_GET(x)                  (((x) & SPI_AO_ADDR_MASK) >> SPI_AO_ADDR_LSB)
228 #define SPI_AO_ADDR_SET(x)                  (((0x0 | (x)) << SPI_AO_ADDR_LSB)& SPI_AO_ADDR_MASK)
229
230 /*
231  *  SPI data register (SPI_D)
232  *  Access: R/W
233  *  Cold reset: (See field descriptions)
234  *  Warm reset: (Same as cold reset)
235  *  Notes:
236  *
237  *  31:0  - SPI data.  Usually this register specifies a series of up to
238  *      four data bytes to transmit to or receive from the SPI device.
239  *      See the 'Notes' section below for more details.  Resets to an
240  *      undefined value.
241  */
242
243 #define SPI_D_ADDRESS                       MAGPIE_REG_SPI_D_ADDR //(ZM_SPI_REGISTER_BASE + 0x00000008)
244 /* 31:0 - SPI data */
245 #define SPI_D_DATA_MSB                      31
246 #define SPI_D_DATA_LSB                      0
247 #define SPI_D_DATA_MASK                     0xffffffff
248 #define SPI_D_DATA_GET(x)                   (((x) & SPI_D_DATA_MASK) >> SPI_D_DATA_LSB)
249 #define SPI_D_DATA_SET(x)                   (((0x0 | (x)) << SPI_D_DATA_LSB) & SPI_D_DATA_MASK)
250
251 /*
252  *  SPI clock division register (SPI_CLKDIV)
253  *  Access: R/W
254  *  Cold reset: (See field descriptions)
255  *  Warm reset: (Same as cold reset)
256  *  Notes:
257  *
258  *  17:16  - 0b00(fastest), 0b01, 0b10, 0b11(slowest)
259  */
260 #define SPI_CLKDIV_ADDRESS                  MAGPIE_REG_SPI_CLKDIV_ADDR //SPI_BASE_ADDRESS + 0x0000001c
261 #define SPI_CLKDIV_MSB                      17
262 #define SPI_CLKDIV_LSB                      16
263 #define SPI_CLKDIV_MASK                     0x00030000
264 #define SPI_CLKDIV_GET(x)                   (((x) & SPI_CLKDIV_MASK) >> SPI_CLKDIV_LSB)
265 #define SPI_CLKDIV_SET(x)                   (((0x0 | (x)) << SPI_CLKDIV_LSB) & SPI_CLKDIV_MASK) // read-then-write
266 #define SPI_CLKDIV_RESET                    0x3
267
268 /*
269  *  Notes
270  *  -----
271  *  * Background
272  *      An SPI transaction consists of three phases: an opcode transmit
273  *      phase (always a single byte), followed by an optional address
274  *      transmit phase of 0-3 bytes, followed by an optional data transmit
275  *      or receive phase of 0-4 bytes.
276  *
277  *  Combined, then, an SPI transaction consists of a 1- to 8-byte
278  *  transmit phase from Falcon to the SPI device, followed by a 0- to
279  *  8-byte receive phase from the SPI device into Falcon.
280  *
281  *  The 'transmit byte count' field in the SPI_CS register controls the
282  *  size (number of bytes) of the transmit phase.  The source of each
283  *  of the bytes transmitted is fixed:
284  *
285  *    Byte            Source
286  *    ----  -----------------------------------------------------------
287  *     0     SPI_AO[7:0] (the 'SPI opcode' field)
288  *     1     SPI_AO[31:24] (the high byte of the 'SPI address' field)
289  *     2     SPI_AO[23:16] (the middle byte of the 'SPI address' field)
290  *     3     SPI_AO[15:8] (the low byte of the 'SPI address' field)
291  *     4     SPI_D[7:0] (the low byte of the 'SPI data' register)
292  *     5     SPI_D[15:8] (the next byte of the 'SPI data' register)
293  *     6     SPI_D[23:16] (the next  byte of the 'SPI data' register)
294  *     7     SPI_D[31:24] (the high byte of the 'SPI data' register)
295  *
296  *
297  *  The 'receive byte count' field in the SPI_CS register controls the
298  *  size (number of bytes) of the receive phase.  The destination of
299  *  each of the bytes received is fixed:
300  *
301  *    Byte             Destination
302  *    ----  -----------------------------------------------------------
303  *     0     SPI_D[7:0] (the low byte of the 'SPI data' register)
304  *     1     SPI_D[15:8] (the next byte of the 'SPI data' register)
305  *     2     SPI_D[23:16] (the next  byte of the 'SPI data' register)
306  *     3     SPI_D[31:24] (the high byte of the 'SPI data' register)
307  *     4     SPI_AO[7:0] (the 'SPI opcode' field)
308  *     5     SPI_AO[15:8] (the low byte of the 'SPI address' field)
309  *     6     SPI_AO[23:16] (the middle byte of the 'SPI address' field)
310  *     7     SPI_AO[31:24] (the high byte of the 'SPI address' field)
311  *
312  *
313  *  * To perform an SPI transaction:
314  *    Write the appropriate values into the SPI_AO and SPI_D registers
315  *  * Write the appropriate values into the 'transmit byte count' and
316  *    'received byte count' fields of the SPI_CS register.
317  *  * Write a '1' to the 'SPI transaction start' bit of the SPI_CS
318  *    register (this step can be combined with the one above if desired
319  *    so that only a single SPI_CS write is needed).
320  *  * Poll the 'transaction busy indication' bit in the SPI_CS register
321  *    until it is clear, indicating that the SPI transaction has
322  *    completed.
323  *  * If the transaction included a receive phase, then retrieve the
324  *    received data by reading the appropriate bytes from the SPI_D and
325  *    SPI_AO registers.
326  *
327  *
328  *  * Examples:
329  *      * A "write disable" (WRDI) transaction:
330  *      * Opcode (SPI_AO[7:0]): 0x04 (for STMicro; varies by
331  *        manufacturer and device type)
332  *      * Address (SPI_AO[31:8]): don't care (not used)
333  *      * Data (SPI_D[31:0]): don't care (not used)
334  *      * Transmission byte count: 1
335  *      * Receive byte count: 0
336  *
337  *      * A "read status register" (RDSR) transaction:
338  *      * Opcode (SPI_AO[7:0]): 0x05 (for STMicro; varies by
339  *        manufacturer and device type)
340  *      * Address (SPI_AO[31:8]): don't care (not used)
341  *      * Data (SPI_D[31:0]): don't care (not used)
342  *      * Transmission byte count: 1
343  *      * Receive byte count: 1
344  *      * Read SPI_D[7:0] to retrieve status register value
345  *
346  *      * A "page program" (PP) transaction to write a value of 0xdeadbeef
347  *        to address 0x123456:
348  *      * Opcode (SPI_AO[7:0]): 0x02 (for STMicro; varies by
349  *        manufacturer and device type)
350  *      * Address (SPI_AO[31:8]): 0x123456
351  *      * Data (SPI_D[31:0]): 0xdeadbeef
352  *      * Transmission byte count: 8
353  *      * Receive byte count: 0
354  */
355
356 /* Wait till Transaction busy indication bit in SPI control/status register of Falcon's SPI Flash Controller is clear */
357 LOCAL void
358 _cmnos_sflash_WaitTillTransactionOver(void)
359 {
360     A_UINT32        poldata;
361     A_UINT32        flg;
362
363     do
364     {
365         poldata = HAL_WORD_REG_READ(SPI_CS_ADDRESS);
366
367         flg = SPI_CS_BUSY_GET(poldata);
368     } while (flg != 0x0);
369 }
370
371 /* Wait till Write In Progress bit in Status Register of Serial Flash is clear */
372 LOCAL void
373 _cmnos_sflash_WaitTillNotWriteInProcess(void)
374 {
375     A_UINT32        poldata;
376     A_UINT32        flg;
377
378     do
379     {
380         _cmnos_sflash_WaitTillTransactionOver();
381
382         HAL_WORD_REG_WRITE( SPI_AO_ADDRESS, SPI_AO_OPC_SET(ZM_SFLASH_OP_RDSR) );
383         HAL_WORD_REG_WRITE( SPI_CS_ADDRESS, SPI_CS_TXBCNT_SET(1) | SPI_CS_RXBCNT_SET(1) | SPI_CS_XCNSTART_SET(1) );
384
385         _cmnos_sflash_WaitTillTransactionOver();
386
387         poldata = HAL_WORD_REG_READ(SPI_D_ADDRESS);
388         flg = poldata & ZM_SFLASH_STATUS_REG_WIP;
389
390     } while (flg != 0x0);
391 }
392
393 /************************************************************************/
394 /* Function to Send WREN(Write Enable) Operation                        */
395 /************************************************************************/
396 LOCAL void
397 _cmnos_sflash_WriteEnable()
398 {
399     _cmnos_sflash_WaitTillNotWriteInProcess();
400
401     HAL_WORD_REG_WRITE( SPI_AO_ADDRESS, SPI_AO_OPC_SET(ZM_SFLASH_OP_WREN) );
402     HAL_WORD_REG_WRITE( SPI_CS_ADDRESS, SPI_CS_TXBCNT_SET(1) | SPI_CS_RXBCNT_SET(0) | SPI_CS_XCNSTART_SET(1) );
403
404     _cmnos_sflash_WaitTillTransactionOver();
405 }
406
407 /************************************************************************/
408 /* Function to In       itialize SPI Flash Controller                          */
409 /************************************************************************/
410 LOCAL void
411 cmnos_sflash_init(void)
412 {
413 #if defined(PROJECT_K2)
414     /* Switch the function of I/O pin 19~22 to act as SPI pins */
415     HAL_WORD_REG_WRITE( MAGPIE_REG_CLOCK_CTRL_ADDR, HAL_WORD_REG_READ(MAGPIE_REG_CLOCK_CTRL_ADDR)|BIT8 );
416 #endif
417
418     /* "Autosize-determination of the address size of serial flash" is obsolete according to Brian Yang's mail :
419      *    The designers reached an conclusion that the spi master (the apb_spi interface control) will be
420      *    modified as ¡§presuming the attached flash model to be 24-bit addressing¡¨, i.e., no more
421      *    auto-size detection!
422      *    Hence you are free to force the 24-bit addressing in the *.c test code.
423      */
424
425     /* Force SPI address size to 24 bits */
426     HAL_WORD_REG_WRITE( SPI_CS_ADDRESS, SPI_CS_AUTOSIZ_OVR_SET(2) );
427 }
428
429 /************************************************************************/
430 /* Function to Send Sector/Block/Chip Erase Operation                   */
431 /************************************************************************/
432 LOCAL void
433 cmnos_sflash_erase(A_UINT32 erase_type, A_UINT32 addr)
434 {
435     A_UINT32    erase_opcode;
436     A_UINT32    tx_len;
437
438     if (erase_type == ZM_SFLASH_SECTOR_ERASE)
439     {
440         erase_opcode = ZM_SFLASH_OP_SE;
441         tx_len = 4;
442     }
443     else if (erase_type == ZM_SFLASH_BLOCK_ERASE)
444     {
445         erase_opcode = ZM_SFLASH_OP_BE;
446         tx_len = 4;
447     }
448     else
449     {
450         erase_opcode = ZM_SFLASH_OP_CE;
451         tx_len = 1;
452     }
453
454     _cmnos_sflash_WriteEnable();
455     _cmnos_sflash_WaitTillNotWriteInProcess();
456
457     HAL_WORD_REG_WRITE( SPI_AO_ADDRESS, SPI_AO_OPC_SET(erase_opcode) | SPI_AO_ADDR_SET(addr) );
458     HAL_WORD_REG_WRITE( SPI_CS_ADDRESS, SPI_CS_TXBCNT_SET(tx_len) | SPI_CS_RXBCNT_SET(0) | SPI_CS_XCNSTART_SET(1) );
459
460 #if 0
461     /* Do not wait(let it be completed in background) */
462     _cmnos_sflash_WaitTillTransactionOver();
463 #else
464     /* Wait till completion */
465     _cmnos_sflash_WaitTillNotWriteInProcess(); /* Chip Erase takes 80 - 200 seconds to complete */
466 #endif
467 }
468
469 /************************************************************************/
470 /* Function to Perform Page Program Operation                           */
471 /*      Notes:                                                          */
472 /*      Serial Flash has the following characteristics :                */
473 /*      1) In datasheet, 1-256 data bytes can be sent at a time, but    */
474 /*         Falcon supports only 4 bytes at a time.                      */
475 /*      2) If the eight least significant address bits(A7-A0) are not   */
476 /*         all 0, all transmitted data which goes beyond the end of the */
477 /*         current page are programmed from the start address in the    */
478 /*         same page.                                                   */
479 /*      This API hides the complexity of the above.                     */
480 /************************************************************************/
481 LOCAL void
482 cmnos_sflash_program(A_UINT32 addr, A_UINT32 len, A_UINT8 *buf)
483 {
484     A_UINT32    s_addr, e_addr;
485     A_UINT32    reminder, write_byte;
486     A_UINT32    data_offset;
487     A_UINT32    next_page_base;
488     A_UINT32    t_word_data;
489
490     e_addr = addr + len;
491     for (s_addr = addr; s_addr < e_addr; )
492     {
493         next_page_base  = (s_addr - s_addr%ZM_SFLASH_PAGE_SIZE) + ZM_SFLASH_PAGE_SIZE;
494
495         reminder = e_addr - s_addr;
496
497         write_byte = next_page_base - s_addr;
498
499         if (write_byte >= 4)
500             write_byte = 4;
501
502         if (write_byte > reminder)
503             write_byte = reminder;
504
505         data_offset = s_addr - addr;
506
507         A_MEMCPY(&t_word_data, buf + data_offset, write_byte);
508
509         _cmnos_sflash_WriteEnable();
510         _cmnos_sflash_WaitTillNotWriteInProcess();
511
512         HAL_WORD_REG_WRITE( SPI_AO_ADDRESS, SPI_AO_OPC_SET(ZM_SFLASH_OP_PP) | SPI_AO_ADDR_SET(s_addr) );
513         HAL_WORD_REG_WRITE( SPI_D_ADDRESS, SPI_D_DATA_SET(t_word_data) );
514         HAL_WORD_REG_WRITE( SPI_CS_ADDRESS, SPI_CS_TXBCNT_SET(4 + write_byte) | SPI_CS_RXBCNT_SET(0) | SPI_CS_XCNSTART_SET(1) );
515
516         _cmnos_sflash_WaitTillTransactionOver();
517
518         s_addr += write_byte;
519     }
520 }
521
522 /************************************************************************/
523 /* Function to Send Read/Fast Read Data Operation                       */
524 /************************************************************************/
525 LOCAL void
526 cmnos_sflash_read(A_UINT32 fast, A_UINT32 addr, A_UINT32 len, A_UINT8 *buf)
527 {
528     A_UINT32    read_opcode;
529     A_UINT32    i;
530     A_UINT32    read_cnt, remainder;
531     A_UINT32    write_byte, read_byte;
532
533     if (fast)
534     {
535         read_opcode = ZM_SFLASH_OP_FAST_READ;
536         write_byte  = 5;
537     }
538     else
539     {
540         read_opcode = ZM_SFLASH_OP_READ;
541         write_byte  = 4;
542     }
543
544     read_cnt  = len/4;
545     remainder = len%4;
546     if (remainder)
547         read_cnt++;
548
549     read_byte = 4;
550     for (i = 0; i < read_cnt; i ++)
551     {
552         if (i == read_cnt-1 && remainder)
553             read_byte = remainder;
554
555         _cmnos_sflash_WaitTillNotWriteInProcess();
556
557         HAL_WORD_REG_WRITE( SPI_AO_ADDRESS, SPI_AO_OPC_SET(read_opcode) | SPI_AO_ADDR_SET(addr + i*4) );
558         HAL_WORD_REG_WRITE( SPI_CS_ADDRESS, SPI_CS_TXBCNT_SET(write_byte) | SPI_CS_RXBCNT_SET(read_byte) | SPI_CS_XCNSTART_SET(1) );
559
560         _cmnos_sflash_WaitTillTransactionOver();
561
562         A_MEMCPY(buf + i*4, (A_UINT8 *)(SPI_D_ADDRESS), read_byte);
563     }
564 }
565
566 /************************************************************************/
567 /* Function to Read Flash Status Register                               */
568 /************************************************************************/
569 LOCAL A_UINT32
570 cmnos_sflash_rdsr(void)
571 {
572     A_UINT32    word_data;
573
574     _cmnos_sflash_WaitTillTransactionOver();
575
576     HAL_WORD_REG_WRITE( SPI_AO_ADDRESS, SPI_AO_OPC_SET(ZM_SFLASH_OP_RDSR) );
577     HAL_WORD_REG_WRITE( SPI_CS_ADDRESS, SPI_CS_TXBCNT_SET(1) | SPI_CS_RXBCNT_SET(1) | SPI_CS_XCNSTART_SET(1) );
578
579     _cmnos_sflash_WaitTillTransactionOver();
580
581     word_data = HAL_WORD_REG_READ(SPI_D_ADDRESS) & 0x000000FF;
582
583     return word_data;
584 }
585
586 void
587 cmnos_sflash_module_install(struct sflash_api *tbl)
588 {
589     /* Indispensable functions */
590     tbl->_sflash_init       = cmnos_sflash_init;
591     tbl->_sflash_erase      = cmnos_sflash_erase;
592     tbl->_sflash_program    = cmnos_sflash_program;
593     tbl->_sflash_read       = cmnos_sflash_read;
594
595     /* Dispensable functions */
596     tbl->_sflash_rdsr       = cmnos_sflash_rdsr;
597 }
598
599 #endif /* SYSTEM_MODULE_SFLASH */
600