1 /*******************************************************************************
2 Copyright (C) Marvell International Ltd. and its affiliates
4 This software file (the "File") is owned and distributed by Marvell
5 International Ltd. and/or its affiliates ("Marvell") under the following
6 alternative licensing terms. Once you have made an election to distribute the
7 File under one of the following license alternatives, please (i) delete this
8 introductory statement regarding license alternatives, (ii) delete the two
9 license alternatives that you have not elected to use and (iii) preserve the
10 Marvell copyright notice above.
12 ********************************************************************************
13 Marvell Commercial License Option
15 If you received this File from Marvell and you have entered into a commercial
16 license agreement (a "Commercial License") with Marvell, the File is licensed
17 to you under the terms of the applicable Commercial License.
19 ********************************************************************************
20 Marvell GPL License Option
22 If you received this File from Marvell, you may opt to use, redistribute and/or
23 modify this File in accordance with the terms and conditions of the General
24 Public License Version 2, June 1991 (the "GPL License"), a copy of which is
25 available along with the File in the license.txt file or by writing to the Free
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27 on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
29 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31 DISCLAIMED. The GPL License provides additional details about this warranty
33 ********************************************************************************
34 Marvell BSD License Option
36 If you received this File from Marvell, you may opt to use, redistribute and/or
37 modify this File under the following licensing terms.
38 Redistribution and use in source and binary forms, with or without modification,
39 are permitted provided that the following conditions are met:
41 * Redistributions of source code must retain the above copyright notice,
42 this list of conditions and the following disclaimer.
44 * Redistributions in binary form must reproduce the above copyright
45 notice, this list of conditions and the following disclaimer in the
46 documentation and/or other materials provided with the distribution.
48 * Neither the name of Marvell nor the names of its contributors may be
49 used to endorse or promote products derived from this software without
50 specific prior written permission.
52 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
56 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 *******************************************************************************/
65 #include "sflash/mvSFlash.h"
66 #include "sflash/mvSFlashSpec.h"
67 #include "spi/mvSpi.h"
68 #include "spi/mvSpiCmnd.h"
69 #include "ctrlEnv/mvCtrlEnvLib.h"
79 static MV_SFLASH_DEVICE_PARAMS sflash
[] = {
80 /* ST M25P32 SPI flash, 4MB, 64 sectors of 64K each */
82 MV_M25P_WREN_CMND_OPCD
,
83 MV_M25P_WRDI_CMND_OPCD
,
84 MV_M25P_RDID_CMND_OPCD
,
85 MV_M25P_RDSR_CMND_OPCD
,
86 MV_M25P_WRSR_CMND_OPCD
,
87 MV_M25P_READ_CMND_OPCD
,
88 MV_M25P_FAST_RD_CMND_OPCD
,
92 MV_M25P_RES_CMND_OPCD
,
93 MV_SFLASH_NO_SPECIFIC_OPCD
, /* power save not supported */
94 MV_M25P32_SECTOR_SIZE
,
95 MV_M25P32_SECTOR_NUMBER
,
98 MV_M25PXXX_ST_MANF_ID
,
100 MV_M25P32_MAX_SPI_FREQ
,
101 MV_M25P32_MAX_FAST_SPI_FREQ
,
102 MV_M25P32_FAST_READ_DUMMY_BYTES
104 /* ST M25P64 SPI flash, 8MB, 128 sectors of 64K each */
106 MV_M25P_WREN_CMND_OPCD
,
107 MV_M25P_WRDI_CMND_OPCD
,
108 MV_M25P_RDID_CMND_OPCD
,
109 MV_M25P_RDSR_CMND_OPCD
,
110 MV_M25P_WRSR_CMND_OPCD
,
111 MV_M25P_READ_CMND_OPCD
,
112 MV_M25P_FAST_RD_CMND_OPCD
,
113 MV_M25P_PP_CMND_OPCD
,
114 MV_M25P_SE_CMND_OPCD
,
115 MV_M25P_BE_CMND_OPCD
,
116 MV_M25P_RES_CMND_OPCD
,
117 MV_SFLASH_NO_SPECIFIC_OPCD
, /* power save not supported */
118 MV_M25P64_SECTOR_SIZE
,
119 MV_M25P64_SECTOR_NUMBER
,
122 MV_M25PXXX_ST_MANF_ID
,
124 MV_M25P64_MAX_SPI_FREQ
,
125 MV_M25P64_MAX_FAST_SPI_FREQ
,
126 MV_M25P64_FAST_READ_DUMMY_BYTES
128 /* ST M25P128 SPI flash, 16MB, 64 sectors of 256K each */
130 MV_M25P_WREN_CMND_OPCD
,
131 MV_M25P_WRDI_CMND_OPCD
,
132 MV_M25P_RDID_CMND_OPCD
,
133 MV_M25P_RDSR_CMND_OPCD
,
134 MV_M25P_WRSR_CMND_OPCD
,
135 MV_M25P_READ_CMND_OPCD
,
136 MV_M25P_FAST_RD_CMND_OPCD
,
137 MV_M25P_PP_CMND_OPCD
,
138 MV_M25P_SE_CMND_OPCD
,
139 MV_M25P_BE_CMND_OPCD
,
140 MV_M25P_RES_CMND_OPCD
,
141 MV_SFLASH_NO_SPECIFIC_OPCD
, /* power save not supported */
142 MV_M25P128_SECTOR_SIZE
,
143 MV_M25P128_SECTOR_NUMBER
,
146 MV_M25PXXX_ST_MANF_ID
,
147 MV_M25P128_DEVICE_ID
,
148 MV_M25P128_MAX_SPI_FREQ
,
149 MV_M25P128_MAX_FAST_SPI_FREQ
,
150 MV_M25P128_FAST_READ_DUMMY_BYTES
152 /* Macronix MXIC MX25L6405 SPI flash, 8MB, 128 sectors of 64K each */
154 MV_MX25L_WREN_CMND_OPCD
,
155 MV_MX25L_WRDI_CMND_OPCD
,
156 MV_MX25L_RDID_CMND_OPCD
,
157 MV_MX25L_RDSR_CMND_OPCD
,
158 MV_MX25L_WRSR_CMND_OPCD
,
159 MV_MX25L_READ_CMND_OPCD
,
160 MV_MX25L_FAST_RD_CMND_OPCD
,
161 MV_MX25L_PP_CMND_OPCD
,
162 MV_MX25L_SE_CMND_OPCD
,
163 MV_MX25L_BE_CMND_OPCD
,
164 MV_MX25L_RES_CMND_OPCD
,
165 MV_MX25L_DP_CMND_OPCD
,
166 MV_MX25L6405_SECTOR_SIZE
,
167 MV_MX25L6405_SECTOR_NUMBER
,
171 MV_MX25L6405_DEVICE_ID
,
172 MV_MX25L6405_MAX_SPI_FREQ
,
173 MV_MX25L6405_MAX_FAST_SPI_FREQ
,
174 MV_MX25L6405_FAST_READ_DUMMY_BYTES
176 /* SPANSION S25FL128P SPI flash, 16MB, 64 sectors of 256K each */
178 MV_S25FL_WREN_CMND_OPCD
,
179 MV_S25FL_WRDI_CMND_OPCD
,
180 MV_S25FL_RDID_CMND_OPCD
,
181 MV_S25FL_RDSR_CMND_OPCD
,
182 MV_S25FL_WRSR_CMND_OPCD
,
183 MV_S25FL_READ_CMND_OPCD
,
184 MV_S25FL_FAST_RD_CMND_OPCD
,
185 MV_S25FL_PP_CMND_OPCD
,
186 MV_S25FL_SE_CMND_OPCD
,
187 MV_S25FL_BE_CMND_OPCD
,
188 MV_S25FL_RES_CMND_OPCD
,
189 MV_S25FL_DP_CMND_OPCD
,
190 MV_S25FL128_SECTOR_SIZE
,
191 MV_S25FL128_SECTOR_NUMBER
,
195 MV_S25FL128_DEVICE_ID
,
196 MV_S25FL128_MAX_SPI_FREQ
,
197 MV_M25P128_MAX_FAST_SPI_FREQ
,
198 MV_M25P128_FAST_READ_DUMMY_BYTES
202 /* Static Functions */
203 static MV_STATUS
mvWriteEnable (MV_SFLASH_INFO
* pFlinfo
);
204 static MV_STATUS
mvStatusRegGet (MV_SFLASH_INFO
* pFlinfo
, MV_U8
* pStatReg
);
205 static MV_STATUS
mvStatusRegSet (MV_SFLASH_INFO
* pFlinfo
, MV_U8 sr
);
206 static MV_STATUS
mvWaitOnWipClear(MV_SFLASH_INFO
* pFlinfo
);
207 static MV_STATUS
mvSFlashPageWr (MV_SFLASH_INFO
* pFlinfo
, MV_U32 offset
, \
208 MV_U8
* pPageBuff
, MV_U32 buffSize
);
209 static MV_STATUS
mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO
* pFlinfo
, \
210 MV_U8
* manId
, MV_U16
* devId
);
212 /*******************************************************************************
213 * mvWriteEnable - serialize the write enable sequence
216 * transmit the sequence for write enable
218 ********************************************************************************/
219 static MV_STATUS
mvWriteEnable(MV_SFLASH_INFO
* pFlinfo
)
221 MV_U8 cmd
[MV_SFLASH_WREN_CMND_LENGTH
];
224 cmd
[0] = sflash
[pFlinfo
->index
].opcdWREN
;
226 return mvSpiWriteThenRead(cmd
, MV_SFLASH_WREN_CMND_LENGTH
, NULL
, 0, 0);
229 /*******************************************************************************
230 * mvStatusRegGet - Retrieve the value of the status register
233 * perform the RDSR sequence to get the 8bit status register
235 ********************************************************************************/
236 static MV_STATUS
mvStatusRegGet(MV_SFLASH_INFO
* pFlinfo
, MV_U8
* pStatReg
)
239 MV_U8 cmd
[MV_SFLASH_RDSR_CMND_LENGTH
];
240 MV_U8 sr
[MV_SFLASH_RDSR_REPLY_LENGTH
];
245 cmd
[0] = sflash
[pFlinfo
->index
].opcdRDSR
;
247 if ((ret
= mvSpiWriteThenRead(cmd
, MV_SFLASH_RDSR_CMND_LENGTH
, sr
,
248 MV_SFLASH_RDSR_REPLY_LENGTH
,0)) != MV_OK
)
256 /*******************************************************************************
257 * mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared
260 * Block waiting for the WIP (write in progress) to be cleared
262 ********************************************************************************/
263 static MV_STATUS
mvWaitOnWipClear(MV_SFLASH_INFO
* pFlinfo
)
269 for (i
=0; i
<MV_SFLASH_MAX_WAIT_LOOP
; i
++)
271 if ((ret
= mvStatusRegGet(pFlinfo
, &stat
)) != MV_OK
)
274 if ((stat
& MV_SFLASH_STATUS_REG_WIP_MASK
) == 0)
278 DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__
);)
282 /*******************************************************************************
283 * mvWaitOnChipEraseDone - Block waiting for the WIP (write in progress) to be
284 * cleared after a chip erase command which is supposed
285 * to take about 2:30 minutes
288 * Block waiting for the WIP (write in progress) to be cleared
290 ********************************************************************************/
291 static MV_STATUS
mvWaitOnChipEraseDone(MV_SFLASH_INFO
* pFlinfo
)
297 for (i
=0; i
<MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP
; i
++)
299 if ((ret
= mvStatusRegGet(pFlinfo
, &stat
)) != MV_OK
)
302 if ((stat
& MV_SFLASH_STATUS_REG_WIP_MASK
) == 0)
306 DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__
);)
310 /*******************************************************************************
311 * mvStatusRegSet - Set the value of the 8bit status register
314 * Set the value of the 8bit status register
316 ********************************************************************************/
317 static MV_STATUS
mvStatusRegSet(MV_SFLASH_INFO
* pFlinfo
, MV_U8 sr
)
320 MV_U8 cmd
[MV_SFLASH_WRSR_CMND_LENGTH
];
323 /* Issue the Write enable command prior the WRSR command */
324 if ((ret
= mvWriteEnable(pFlinfo
)) != MV_OK
)
327 /* Write the SR with the new values */
328 cmd
[0] = sflash
[pFlinfo
->index
].opcdWRSR
;
331 if ((ret
= mvSpiWriteThenRead(cmd
, MV_SFLASH_WRSR_CMND_LENGTH
, NULL
, 0, 0)) != MV_OK
)
334 if ((ret
= mvWaitOnWipClear(pFlinfo
)) != MV_OK
)
342 /*******************************************************************************
343 * mvSFlashPageWr - Write up to 256 Bytes in the same page
346 * Write a buffer up to the page size in length provided that the whole address
347 * range is within the same page (alligned to page bounderies)
349 *******************************************************************************/
350 static MV_STATUS
mvSFlashPageWr (MV_SFLASH_INFO
* pFlinfo
, MV_U32 offset
,
351 MV_U8
* pPageBuff
, MV_U32 buffSize
)
354 MV_U8 cmd
[MV_SFLASH_PP_CMND_LENGTH
];
357 /* Protection - check if the model was detected */
358 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
360 DB(mvOsPrintf("%s WARNING: Invalid parameter device index!\n", __FUNCTION__
);)
364 /* check that we do not cross the page bounderies */
365 if (((offset
& (sflash
[pFlinfo
->index
].pageSize
- 1)) + buffSize
) >
366 sflash
[pFlinfo
->index
].pageSize
)
368 DB(mvOsPrintf("%s WARNING: Page allignment problem!\n", __FUNCTION__
);)
369 return MV_OUT_OF_RANGE
;
372 /* Issue the Write enable command prior the page program command */
373 if ((ret
= mvWriteEnable(pFlinfo
)) != MV_OK
)
376 cmd
[0] = sflash
[pFlinfo
->index
].opcdPP
;
377 cmd
[1] = ((offset
>> 16) & 0xFF);
378 cmd
[2] = ((offset
>> 8) & 0xFF);
379 cmd
[3] = (offset
& 0xFF);
381 if ((ret
= mvSpiWriteThenWrite(cmd
, MV_SFLASH_PP_CMND_LENGTH
, pPageBuff
, buffSize
)) != MV_OK
)
384 if ((ret
= mvWaitOnWipClear(pFlinfo
)) != MV_OK
)
390 /*******************************************************************************
391 * mvSFlashWithDefaultsIdGet - Try to read the manufacturer and Device IDs from
392 * the device using the default RDID opcode and the default WREN opcode.
395 * This is used to detect a generic device that uses the default opcodes
396 * for the WREN and RDID.
398 ********************************************************************************/
399 static MV_STATUS
mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO
* pFlinfo
, MV_U8
* manId
, MV_U16
* devId
)
402 MV_U8 cmdRDID
[MV_SFLASH_RDID_CMND_LENGTH
];
403 MV_U8 id
[MV_SFLASH_RDID_REPLY_LENGTH
];
407 /* Use the default RDID opcode to read the IDs */
408 cmdRDID
[0] = MV_SFLASH_DEFAULT_RDID_OPCD
; /* unknown model try default */
409 if ((ret
= mvSpiWriteThenRead(cmdRDID
, MV_SFLASH_RDID_CMND_LENGTH
, id
, MV_SFLASH_RDID_REPLY_LENGTH
, 0)) != MV_OK
)
414 *devId
|= (id
[1] << 8);
421 #####################################################################################
422 #####################################################################################
425 /*******************************************************************************
426 * mvSFlashInit - Initialize the serial flash device
429 * Perform the neccessary initialization and configuration
432 * pFlinfo: pointer to the Flash information structure
433 * pFlinfo->baseAddr: base address in fast mode.
434 * pFlinfo->index: Index of the flash in the sflash tabel. If the SPI
435 * flash device does not support read Id command with
436 * the standard opcode, then the user should supply this
437 * as an input to skip the autodetection process!!!!
440 * pFlinfo: pointer to the Flash information structure after detection
441 * pFlinfo->manufacturerId: Manufacturer ID
442 * pFlinfo->deviceId: Device ID
443 * pFlinfo->sectorSize: size of the sector (all sectors are the same).
444 * pFlinfo->sectorNumber: number of sectors.
445 * pFlinfo->pageSize: size of the page.
446 * pFlinfo->index: Index of the detected flash in the sflash tabel
449 * Success or Error code.
452 *******************************************************************************/
453 MV_STATUS
mvSFlashInit (MV_SFLASH_INFO
* pFlinfo
)
459 MV_BOOL detectFlag
= MV_FALSE
;
461 /* check for NULL pointer */
464 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
468 /* Initialize the SPI interface with low frequency to make sure that the read ID succeeds */
469 if ((ret
= mvSpiInit(MV_SFLASH_BASIC_SPI_FREQ
)) != MV_OK
)
471 mvOsPrintf("%s ERROR: Failed to initialize the SPI interface!\n", __FUNCTION__
);
475 /* First try to read the Manufacturer and Device IDs */
476 if ((ret
= mvSFlashIdGet(pFlinfo
, &manf
, &dev
)) != MV_OK
)
478 mvOsPrintf("%s ERROR: Failed to get the SFlash ID!\n", __FUNCTION__
);
482 /* loop over the whole table and look for the appropriate SFLASH */
483 for (indx
=0; indx
<MV_ARRAY_SIZE(sflash
); indx
++)
485 if ((manf
== sflash
[indx
].manufacturerId
) && (dev
== sflash
[indx
].deviceId
))
487 pFlinfo
->manufacturerId
= manf
;
488 pFlinfo
->deviceId
= dev
;
489 pFlinfo
->index
= indx
;
490 detectFlag
= MV_TRUE
;
496 mvOsPrintf("%s ERROR: Unknown SPI flash device!\n", __FUNCTION__
);
500 /* fill the info based on the model detected */
501 pFlinfo
->sectorSize
= sflash
[pFlinfo
->index
].sectorSize
;
502 pFlinfo
->sectorNumber
= sflash
[pFlinfo
->index
].sectorNumber
;
503 pFlinfo
->pageSize
= sflash
[pFlinfo
->index
].pageSize
;
505 /* Set the SPI frequency to the MAX allowed for the device for best performance */
506 if ((ret
= mvSpiBaudRateSet(sflash
[pFlinfo
->index
].spiMaxFreq
)) != MV_OK
)
508 mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__
);
512 /* As default lock the SR */
513 if ((ret
= mvSFlashStatRegLock(pFlinfo
, MV_TRUE
)) != MV_OK
)
519 /*******************************************************************************
520 * mvSFlashSectorErase - Erasse a single sector of the serial flash
523 * Issue the erase sector command and address
526 * pFlinfo: pointer to the Flash information structure
527 * secNumber: sector Number to erase (0 -> (sectorNumber-1))
533 * Success or Error code.
536 *******************************************************************************/
537 MV_STATUS
mvSFlashSectorErase (MV_SFLASH_INFO
* pFlinfo
, MV_U32 secNumber
)
540 MV_U8 cmd
[MV_SFLASH_SE_CMND_LENGTH
];
542 MV_U32 secAddr
= (secNumber
* pFlinfo
->sectorSize
);
545 MV_U32
* pW
= (MV_U32
*) (secAddr
+ pFlinfo
->baseAddr
);
546 MV_U32 erasedWord
= 0xFFFFFFFF;
547 MV_U32 wordsPerSector
= (pFlinfo
->sectorSize
/ sizeof(MV_U32
));
548 MV_BOOL eraseNeeded
= MV_FALSE
;
550 /* check for NULL pointer */
553 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
557 /* Protection - check if the model was detected */
558 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
560 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
564 /* check that the sector number is valid */
565 if (secNumber
>= pFlinfo
->sectorNumber
)
567 DB(mvOsPrintf("%s WARNING: Invaild parameter sector number!\n", __FUNCTION__
);)
571 /* we don't want to access SPI in direct mode from in-direct API,
572 becasue of timing issue between CS asserts. */
574 /* First compare to FF and check if erase is needed */
575 for (i
=0; i
<wordsPerSector
; i
++)
577 if (memcmp(pW
, &erasedWord
, sizeof(MV_U32
)) != 0)
579 eraseNeeded
= MV_TRUE
;
589 cmd
[0] = sflash
[pFlinfo
->index
].opcdSE
;
590 cmd
[1] = ((secAddr
>> 16) & 0xFF);
591 cmd
[2] = ((secAddr
>> 8) & 0xFF);
592 cmd
[3] = (secAddr
& 0xFF);
594 /* Issue the Write enable command prior the sector erase command */
595 if ((ret
= mvWriteEnable(pFlinfo
)) != MV_OK
)
598 if ((ret
= mvSpiWriteThenWrite(cmd
, MV_SFLASH_SE_CMND_LENGTH
, NULL
, 0)) != MV_OK
)
601 if ((ret
= mvWaitOnWipClear(pFlinfo
)) != MV_OK
)
607 /*******************************************************************************
608 * mvSFlashChipErase - Erasse the whole serial flash
611 * Issue the bulk (chip) erase command
614 * pFlinfo: pointer to the Flash information structure
620 * Success or Error code.
623 *******************************************************************************/
624 MV_STATUS
mvSFlashChipErase (MV_SFLASH_INFO
* pFlinfo
)
627 MV_U8 cmd
[MV_SFLASH_BE_CMND_LENGTH
];
630 /* check for NULL pointer */
633 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
637 /* Protection - check if the model was detected */
638 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
640 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
644 cmd
[0] = sflash
[pFlinfo
->index
].opcdBE
;
646 /* Issue the Write enable command prior the Bulk erase command */
647 if ((ret
= mvWriteEnable(pFlinfo
)) != MV_OK
)
650 if ((ret
= mvSpiWriteThenWrite(cmd
, MV_SFLASH_BE_CMND_LENGTH
, NULL
, 0)) != MV_OK
)
653 if ((ret
= mvWaitOnChipEraseDone(pFlinfo
)) != MV_OK
)
659 /*******************************************************************************
660 * mvSFlashBlockRd - Read from the serial flash
663 * Issue the read command and address then perfom the needed read
666 * pFlinfo: pointer to the Flash information structure
667 * offset: byte offset with the flash to start reading from
668 * pReadBuff: pointer to the buffer to read the data in
669 * buffSize: size of the buffer to read.
672 * pReadBuff: pointer to the buffer containing the read data
675 * Success or Error code.
678 *******************************************************************************/
679 MV_STATUS
mvSFlashBlockRd (MV_SFLASH_INFO
* pFlinfo
, MV_U32 offset
,
680 MV_U8
* pReadBuff
, MV_U32 buffSize
)
682 MV_U8 cmd
[MV_SFLASH_READ_CMND_LENGTH
];
685 /* check for NULL pointer */
686 if ((pFlinfo
== NULL
) || (pReadBuff
== NULL
))
688 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
692 /* Protection - check if the model was detected */
693 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
695 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
699 cmd
[0] = sflash
[pFlinfo
->index
].opcdREAD
;
700 cmd
[1] = ((offset
>> 16) & 0xFF);
701 cmd
[2] = ((offset
>> 8) & 0xFF);
702 cmd
[3] = (offset
& 0xFF);
704 return mvSpiWriteThenRead(cmd
, MV_SFLASH_READ_CMND_LENGTH
, pReadBuff
, buffSize
, 0);
707 /*******************************************************************************
708 * mvSFlashFastBlockRd - Fast read from the serial flash
711 * Issue the fast read command and address then perfom the needed read
714 * pFlinfo: pointer to the Flash information structure
715 * offset: byte offset with the flash to start reading from
716 * pReadBuff: pointer to the buffer to read the data in
717 * buffSize: size of the buffer to read.
720 * pReadBuff: pointer to the buffer containing the read data
723 * Success or Error code.
726 *******************************************************************************/
727 MV_STATUS
mvSFlashFastBlockRd (MV_SFLASH_INFO
* pFlinfo
, MV_U32 offset
,
728 MV_U8
* pReadBuff
, MV_U32 buffSize
)
730 MV_U8 cmd
[MV_SFLASH_READ_CMND_LENGTH
];
733 /* check for NULL pointer */
734 if ((pFlinfo
== NULL
) || (pReadBuff
== NULL
))
736 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
740 /* Protection - check if the model was detected */
741 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
743 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
747 /* Set the SPI frequency to the MAX allowed for fast-read operations */
748 mvOsPrintf("Setting freq to %d.\n",sflash
[pFlinfo
->index
].spiMaxFastFreq
);
749 if ((ret
= mvSpiBaudRateSet(sflash
[pFlinfo
->index
].spiMaxFastFreq
)) != MV_OK
)
751 mvOsPrintf("%s ERROR: Failed to set the SPI fast frequency!\n", __FUNCTION__
);
755 cmd
[0] = sflash
[pFlinfo
->index
].opcdFSTRD
;
756 cmd
[1] = ((offset
>> 16) & 0xFF);
757 cmd
[2] = ((offset
>> 8) & 0xFF);
758 cmd
[3] = (offset
& 0xFF);
761 ret
= mvSpiWriteThenRead(cmd
, MV_SFLASH_READ_CMND_LENGTH
, pReadBuff
, buffSize
,
762 sflash
[pFlinfo
->index
].spiFastRdDummyBytes
);
764 /* Reset the SPI frequency to the MAX allowed for the device for best performance */
765 if ((ret
= mvSpiBaudRateSet(sflash
[pFlinfo
->index
].spiMaxFreq
)) != MV_OK
)
767 mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__
);
775 /*******************************************************************************
776 * mvSFlashBlockWr - Write a buffer with any size
779 * write regardless of the page boundaries and size limit per Page
783 * pFlinfo: pointer to the Flash information structure
784 * offset: byte offset within the flash region
785 * pWriteBuff: pointer to the buffer holding the data to program
786 * buffSize: size of the buffer to write
792 * Success or Error code.
795 *******************************************************************************/
796 MV_STATUS
mvSFlashBlockWr (MV_SFLASH_INFO
* pFlinfo
, MV_U32 offset
,
797 MV_U8
* pWriteBuff
, MV_U32 buffSize
)
800 MV_U32 data2write
= buffSize
;
801 MV_U32 preAllOffset
= (offset
& MV_SFLASH_PAGE_ALLIGN_MASK(MV_M25P_PAGE_SIZE
));
802 MV_U32 preAllSz
= (preAllOffset
? (MV_M25P_PAGE_SIZE
- preAllOffset
) : 0);
803 MV_U32 writeOffset
= offset
;
805 /* check for NULL pointer */
806 #ifndef CONFIG_MARVELL
807 if(NULL
== pWriteBuff
)
809 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
816 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
820 /* Protection - check if the model was detected */
821 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
823 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
827 /* check that the buffer size does not exceed the flash size */
828 if ((offset
+ buffSize
) > mvSFlashSizeGet(pFlinfo
))
830 DB(mvOsPrintf("%s WARNING: Write exceeds flash size!\n", __FUNCTION__
);)
831 return MV_OUT_OF_RANGE
;
834 /* check if the total block size is less than the first chunk remainder */
835 if (data2write
< preAllSz
)
836 preAllSz
= data2write
;
838 /* check if programing does not start at a 64byte alligned offset */
841 if ((ret
= mvSFlashPageWr(pFlinfo
, writeOffset
, pWriteBuff
, preAllSz
)) != MV_OK
)
844 /* increment pointers and counters */
845 writeOffset
+= preAllSz
;
846 data2write
-= preAllSz
;
847 pWriteBuff
+= preAllSz
;
850 /* program the data that fits in complete page chunks */
851 while (data2write
>= sflash
[pFlinfo
->index
].pageSize
)
853 if ((ret
= mvSFlashPageWr(pFlinfo
, writeOffset
, pWriteBuff
, sflash
[pFlinfo
->index
].pageSize
)) != MV_OK
)
856 /* increment pointers and counters */
857 writeOffset
+= sflash
[pFlinfo
->index
].pageSize
;
858 data2write
-= sflash
[pFlinfo
->index
].pageSize
;
859 pWriteBuff
+= sflash
[pFlinfo
->index
].pageSize
;
862 /* program the last partial chunk */
865 if ((ret
= mvSFlashPageWr(pFlinfo
, writeOffset
, pWriteBuff
, data2write
)) != MV_OK
)
872 /*******************************************************************************
873 * mvSFlashIdGet - Get the manufacturer and device IDs.
876 * Get the Manufacturer and device IDs from the serial flash through
877 * writing the RDID command then reading 3 bytes of data. In case that
878 * this command was called for the first time in order to detect the
879 * manufacturer and device IDs, then the default RDID opcode will be used
880 * unless the device index is indicated by the user (in case the SPI flash
881 * does not use the default RDID opcode).
884 * pFlinfo: pointer to the Flash information structure
885 * pManId: pointer to the 8bit variable to hold the manufacturing ID
886 * pDevId: pointer to the 16bit variable to hold the device ID
889 * pManId: pointer to the 8bit variable holding the manufacturing ID
890 * pDevId: pointer to the 16bit variable holding the device ID
893 * Success or Error code.
896 *******************************************************************************/
897 MV_STATUS
mvSFlashIdGet (MV_SFLASH_INFO
* pFlinfo
, MV_U8
* pManId
, MV_U16
* pDevId
)
900 MV_U8 cmd
[MV_SFLASH_RDID_CMND_LENGTH
];
901 MV_U8 id
[MV_SFLASH_RDID_REPLY_LENGTH
];
905 /* check for NULL pointer */
906 if ((pFlinfo
== NULL
) || (pManId
== NULL
) || (pDevId
== NULL
))
908 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
912 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
913 return mvSFlashWithDefaultsIdGet(pFlinfo
, pManId
, pDevId
);
915 cmd
[0] = sflash
[pFlinfo
->index
].opcdRDID
;
917 if ((ret
= mvSpiWriteThenRead(cmd
, MV_SFLASH_RDID_CMND_LENGTH
, id
, MV_SFLASH_RDID_REPLY_LENGTH
, 0)) != MV_OK
)
922 *pDevId
|= (id
[1] << 8);
928 /*******************************************************************************
929 * mvSFlashWpRegionSet - Set the Write-Protected region
932 * Set the Write-Protected region
935 * pFlinfo: pointer to the Flash information structure
936 * wpRegion: which region will be protected
942 * Success or Error code.
945 *******************************************************************************/
946 MV_STATUS
mvSFlashWpRegionSet (MV_SFLASH_INFO
* pFlinfo
, MV_SFLASH_WP_REGION wpRegion
)
950 /* check for NULL pointer */
953 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
957 /* Protection - check if the model was detected */
958 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
960 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
964 /* Check if the chip is an ST flash; then WP supports only 3 bits */
965 if (pFlinfo
->manufacturerId
== MV_M25PXXX_ST_MANF_ID
)
970 wpMask
= MV_M25P_STATUS_BP_NONE
;
973 case MV_WP_UPR_1OF128
:
974 DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__
);)
975 return MV_NOT_SUPPORTED
;
977 case MV_WP_UPR_1OF64
:
978 wpMask
= MV_M25P_STATUS_BP_1_OF_64
;
981 case MV_WP_UPR_1OF32
:
982 wpMask
= MV_M25P_STATUS_BP_1_OF_32
;
985 case MV_WP_UPR_1OF16
:
986 wpMask
= MV_M25P_STATUS_BP_1_OF_16
;
990 wpMask
= MV_M25P_STATUS_BP_1_OF_8
;
994 wpMask
= MV_M25P_STATUS_BP_1_OF_4
;
998 wpMask
= MV_M25P_STATUS_BP_1_OF_2
;
1002 wpMask
= MV_M25P_STATUS_BP_ALL
;
1006 DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__
);)
1007 return MV_BAD_PARAM
;
1010 /* check if the manufacturer is MXIC then the WP is 4bits */
1011 else if (pFlinfo
->manufacturerId
== MV_MXIC_MANF_ID
)
1016 wpMask
= MV_MX25L_STATUS_BP_NONE
;
1019 case MV_WP_UPR_1OF128
:
1020 wpMask
= MV_MX25L_STATUS_BP_1_OF_128
;
1023 case MV_WP_UPR_1OF64
:
1024 wpMask
= MV_MX25L_STATUS_BP_1_OF_64
;
1027 case MV_WP_UPR_1OF32
:
1028 wpMask
= MV_MX25L_STATUS_BP_1_OF_32
;
1031 case MV_WP_UPR_1OF16
:
1032 wpMask
= MV_MX25L_STATUS_BP_1_OF_16
;
1035 case MV_WP_UPR_1OF8
:
1036 wpMask
= MV_MX25L_STATUS_BP_1_OF_8
;
1039 case MV_WP_UPR_1OF4
:
1040 wpMask
= MV_MX25L_STATUS_BP_1_OF_4
;
1043 case MV_WP_UPR_1OF2
:
1044 wpMask
= MV_MX25L_STATUS_BP_1_OF_2
;
1048 wpMask
= MV_MX25L_STATUS_BP_ALL
;
1052 DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__
);)
1053 return MV_BAD_PARAM
;
1056 /* check if the manufacturer is SPANSION then the WP is 4bits */
1057 else if (pFlinfo
->manufacturerId
== MV_SPANSION_MANF_ID
)
1062 wpMask
= MV_S25FL_STATUS_BP_NONE
;
1065 case MV_WP_UPR_1OF128
:
1066 DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__
);)
1067 return MV_NOT_SUPPORTED
;
1069 case MV_WP_UPR_1OF64
:
1070 wpMask
= MV_S25FL_STATUS_BP_1_OF_64
;
1073 case MV_WP_UPR_1OF32
:
1074 wpMask
= MV_S25FL_STATUS_BP_1_OF_32
;
1077 case MV_WP_UPR_1OF16
:
1078 wpMask
= MV_S25FL_STATUS_BP_1_OF_16
;
1081 case MV_WP_UPR_1OF8
:
1082 wpMask
= MV_S25FL_STATUS_BP_1_OF_8
;
1085 case MV_WP_UPR_1OF4
:
1086 wpMask
= MV_S25FL_STATUS_BP_1_OF_4
;
1089 case MV_WP_UPR_1OF2
:
1090 wpMask
= MV_S25FL_STATUS_BP_1_OF_2
;
1094 wpMask
= MV_S25FL_STATUS_BP_ALL
;
1099 DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__
);)
1100 return MV_BAD_PARAM
;
1105 DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__
);)
1106 return MV_BAD_PARAM
;
1109 /* Verify that the SRWD bit is always set - register is s/w locked */
1110 wpMask
|= MV_SFLASH_STATUS_REG_SRWD_MASK
;
1112 return mvStatusRegSet(pFlinfo
, wpMask
);
1115 /*******************************************************************************
1116 * mvSFlashWpRegionGet - Get the Write-Protected region configured
1119 * Get from the chip the Write-Protected region configured
1122 * pFlinfo: pointer to the Flash information structure
1123 * pWpRegion: pointer to the variable to return the WP region in
1126 * wpRegion: pointer to the variable holding the WP region configured
1129 * Success or Error code.
1132 *******************************************************************************/
1133 MV_STATUS
mvSFlashWpRegionGet (MV_SFLASH_INFO
* pFlinfo
, MV_SFLASH_WP_REGION
* pWpRegion
)
1138 /* check for NULL pointer */
1139 if ((pFlinfo
== NULL
) || (pWpRegion
== NULL
))
1141 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
1142 return MV_BAD_PARAM
;
1145 /* Protection - check if the model was detected */
1146 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
1148 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
1149 return MV_BAD_PARAM
;
1152 if ((ret
= mvStatusRegGet(pFlinfo
, ®
)) != MV_OK
)
1155 /* Check if the chip is an ST flash; then WP supports only 3 bits */
1156 if (pFlinfo
->manufacturerId
== MV_M25PXXX_ST_MANF_ID
)
1158 switch ((reg
& MV_M25P_STATUS_REG_WP_MASK
))
1160 case MV_M25P_STATUS_BP_NONE
:
1161 *pWpRegion
= MV_WP_NONE
;
1164 case MV_M25P_STATUS_BP_1_OF_64
:
1165 *pWpRegion
= MV_WP_UPR_1OF64
;
1168 case MV_M25P_STATUS_BP_1_OF_32
:
1169 *pWpRegion
= MV_WP_UPR_1OF32
;
1172 case MV_M25P_STATUS_BP_1_OF_16
:
1173 *pWpRegion
= MV_WP_UPR_1OF16
;
1176 case MV_M25P_STATUS_BP_1_OF_8
:
1177 *pWpRegion
= MV_WP_UPR_1OF8
;
1180 case MV_M25P_STATUS_BP_1_OF_4
:
1181 *pWpRegion
= MV_WP_UPR_1OF4
;
1184 case MV_M25P_STATUS_BP_1_OF_2
:
1185 *pWpRegion
= MV_WP_UPR_1OF2
;
1188 case MV_M25P_STATUS_BP_ALL
:
1189 *pWpRegion
= MV_WP_ALL
;
1193 DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__
);)
1194 return MV_BAD_VALUE
;
1197 /* check if the manufacturer is MXIC then the WP is 4bits */
1198 else if (pFlinfo
->manufacturerId
== MV_MXIC_MANF_ID
)
1200 switch ((reg
& MV_MX25L_STATUS_REG_WP_MASK
))
1202 case MV_MX25L_STATUS_BP_NONE
:
1203 *pWpRegion
= MV_WP_NONE
;
1206 case MV_MX25L_STATUS_BP_1_OF_128
:
1207 *pWpRegion
= MV_WP_UPR_1OF128
;
1210 case MV_MX25L_STATUS_BP_1_OF_64
:
1211 *pWpRegion
= MV_WP_UPR_1OF64
;
1214 case MV_MX25L_STATUS_BP_1_OF_32
:
1215 *pWpRegion
= MV_WP_UPR_1OF32
;
1218 case MV_MX25L_STATUS_BP_1_OF_16
:
1219 *pWpRegion
= MV_WP_UPR_1OF16
;
1222 case MV_MX25L_STATUS_BP_1_OF_8
:
1223 *pWpRegion
= MV_WP_UPR_1OF8
;
1226 case MV_MX25L_STATUS_BP_1_OF_4
:
1227 *pWpRegion
= MV_WP_UPR_1OF4
;
1230 case MV_MX25L_STATUS_BP_1_OF_2
:
1231 *pWpRegion
= MV_WP_UPR_1OF2
;
1234 case MV_MX25L_STATUS_BP_ALL
:
1235 *pWpRegion
= MV_WP_ALL
;
1239 DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__
);)
1240 return MV_BAD_VALUE
;
1243 /* Check if the chip is an SPANSION flash; then WP supports only 3 bits */
1244 else if (pFlinfo
->manufacturerId
== MV_SPANSION_MANF_ID
)
1246 switch ((reg
& MV_S25FL_STATUS_REG_WP_MASK
))
1248 case MV_S25FL_STATUS_BP_NONE
:
1249 *pWpRegion
= MV_WP_NONE
;
1252 case MV_S25FL_STATUS_BP_1_OF_64
:
1253 *pWpRegion
= MV_WP_UPR_1OF64
;
1256 case MV_S25FL_STATUS_BP_1_OF_32
:
1257 *pWpRegion
= MV_WP_UPR_1OF32
;
1260 case MV_S25FL_STATUS_BP_1_OF_16
:
1261 *pWpRegion
= MV_WP_UPR_1OF16
;
1264 case MV_S25FL_STATUS_BP_1_OF_8
:
1265 *pWpRegion
= MV_WP_UPR_1OF8
;
1268 case MV_S25FL_STATUS_BP_1_OF_4
:
1269 *pWpRegion
= MV_WP_UPR_1OF4
;
1272 case MV_S25FL_STATUS_BP_1_OF_2
:
1273 *pWpRegion
= MV_WP_UPR_1OF2
;
1276 case MV_S25FL_STATUS_BP_ALL
:
1277 *pWpRegion
= MV_WP_ALL
;
1281 DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__
);)
1282 return MV_BAD_VALUE
;
1287 DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__
);)
1288 return MV_BAD_PARAM
;
1294 /*******************************************************************************
1295 * mvSFlashStatRegLock - Lock the status register for writing - W/Vpp
1296 * pin should be low to take effect
1299 * Lock the access to the Status Register for writing. This will
1300 * cause the flash to enter the hardware protection mode if the W/Vpp
1301 * is low. If the W/Vpp is hi, the chip will be in soft protection mode, but
1302 * the register will continue to be writable if WREN sequence was used.
1305 * pFlinfo: pointer to the Flash information structure
1306 * srLock: enable/disable (MV_TRUE/MV_FALSE) status registor lock mechanism
1312 * Success or Error code.
1315 *******************************************************************************/
1316 MV_STATUS
mvSFlashStatRegLock (MV_SFLASH_INFO
* pFlinfo
, MV_BOOL srLock
)
1321 /* check for NULL pointer */
1322 if (pFlinfo
== NULL
)
1324 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
1325 return MV_BAD_PARAM
;
1328 /* Protection - check if the model was detected */
1329 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
1331 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
1332 return MV_BAD_PARAM
;
1335 if ((ret
= mvStatusRegGet(pFlinfo
, ®
)) != MV_OK
)
1339 reg
|= MV_SFLASH_STATUS_REG_SRWD_MASK
;
1341 reg
&= ~MV_SFLASH_STATUS_REG_SRWD_MASK
;
1343 return mvStatusRegSet(pFlinfo
, reg
);
1346 /*******************************************************************************
1347 * mvSFlashSizeGet - Get the size of the SPI flash
1350 * based on the sector number and size of each sector calculate the total
1351 * size of the flash memory.
1354 * pFlinfo: pointer to the Flash information structure
1360 * Size of the flash in bytes.
1363 *******************************************************************************/
1364 MV_U32
mvSFlashSizeGet (MV_SFLASH_INFO
* pFlinfo
)
1366 /* check for NULL pointer */
1367 if (pFlinfo
== NULL
)
1369 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
1373 return (pFlinfo
->sectorSize
* pFlinfo
->sectorNumber
);
1376 /*******************************************************************************
1377 * mvSFlashPowerSaveEnter - Cause the falsh device to go into power save mode
1380 * Enter a special power save mode.
1383 * pFlinfo: pointer to the Flash information structure
1389 * Size of the flash in bytes.
1392 *******************************************************************************/
1393 MV_STATUS
mvSFlashPowerSaveEnter(MV_SFLASH_INFO
* pFlinfo
)
1396 MV_U8 cmd
[MV_SFLASH_DP_CMND_LENGTH
];
1399 /* check for NULL pointer */
1400 if (pFlinfo
== NULL
)
1402 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
1406 /* Protection - check if the model was detected */
1407 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
1409 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
1410 return MV_BAD_PARAM
;
1413 /* check that power save mode is supported in the specific device */
1414 if (sflash
[pFlinfo
->index
].opcdPwrSave
== MV_SFLASH_NO_SPECIFIC_OPCD
)
1416 DB(mvOsPrintf("%s WARNING: Power save not supported for this device!\n", __FUNCTION__
);)
1417 return MV_NOT_SUPPORTED
;
1420 cmd
[0] = sflash
[pFlinfo
->index
].opcdPwrSave
;
1422 if ((ret
= mvSpiWriteThenWrite(cmd
, MV_SFLASH_DP_CMND_LENGTH
, NULL
, 0)) != MV_OK
)
1429 /*******************************************************************************
1430 * mvSFlashPowerSaveExit - Cause the falsh device to exit the power save mode
1433 * Exit the deep power save mode.
1436 * pFlinfo: pointer to the Flash information structure
1442 * Size of the flash in bytes.
1445 *******************************************************************************/
1446 MV_STATUS
mvSFlashPowerSaveExit (MV_SFLASH_INFO
* pFlinfo
)
1449 MV_U8 cmd
[MV_SFLASH_RES_CMND_LENGTH
];
1452 /* check for NULL pointer */
1453 if (pFlinfo
== NULL
)
1455 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
1459 /* Protection - check if the model was detected */
1460 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
1462 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
1463 return MV_BAD_PARAM
;
1466 /* check that power save mode is supported in the specific device */
1467 if (sflash
[pFlinfo
->index
].opcdRES
== MV_SFLASH_NO_SPECIFIC_OPCD
)
1469 DB(mvOsPrintf("%s WARNING: Read Electronic Signature not supported for this device!\n", __FUNCTION__
);)
1470 return MV_NOT_SUPPORTED
;
1473 cmd
[0] = sflash
[pFlinfo
->index
].opcdRES
;
1475 if ((ret
= mvSpiWriteThenWrite(cmd
, MV_SFLASH_RES_CMND_LENGTH
, NULL
, 0)) != MV_OK
)
1478 /* add the delay needed for the device to wake up */
1479 mvOsDelay(MV_MXIC_DP_EXIT_DELAY
); /* 30 ms */
1485 /*******************************************************************************
1486 * mvSFlashModelGet - Retreive the string with the device manufacturer and model
1489 * Retreive the string with the device manufacturer and model
1492 * pFlinfo: pointer to the Flash information structure
1498 * pointer to the string indicating the device manufacturer and model
1501 *******************************************************************************/
1502 const MV_8
* mvSFlashModelGet (MV_SFLASH_INFO
* pFlinfo
)
1504 static const MV_8
* unknModel
= (const MV_8
*)"Unknown";
1506 /* check for NULL pointer */
1507 if (pFlinfo
== NULL
)
1509 mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__
);
1513 /* Protection - check if the model was detected */
1514 if (pFlinfo
->index
>= MV_ARRAY_SIZE(sflash
))
1516 DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__
);)
1520 return sflash
[pFlinfo
->index
].deviceModel
;