[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_2_eng / packages / ti / board / src / flash / board_flash.c
1 /*
2 * Copyright (c) 2016, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
34 /**
35 *
36 * \file board_flash.c
37 *
38 * \brief This contains board flash common APIs.
39 *
40 ******************************************************************************/
42 #include "board_cfg.h"
43 #include "board_utils.h"
44 #include "board_flash.h"
45 #if defined(SOC_K2G)
46 #include <ti/board/src/flash/qspi_nor/s25fl512s/qspi_nor.h>
47 #endif
49 /* This structure holds information about the flash devices on the board */
51 #if defined(BOARD_QSPI_FLASH_IN)
52 Board_FlashInfo Board_flashInfo =
53 {
54 0, /* Flash handle */
55 0, /* Flash manufacturer ID */
56 0, /* Flash device ID */
57 BOARD_FLASH_QSPI_FLASH, /* Flash type */
58 8, /* Flash data width in bits */
59 QSPI_FLASH_NUM_SECTORS,
60 (QSPI_FLASH_SECTOR_SIZE / QSPI_FLASH_PAGE_SIZE),
61 QSPI_FLASH_PAGE_SIZE,
62 0, /* NAND spare area size in bytes */
63 0, /* NAND spare area offset for bad block */
64 0, /* NAND column */
65 NULL /* NAND Bad block list */
66 };
67 #endif
69 /******************************************************************************
70 * BOARD_flashOpen
71 ******************************************************************************/
72 Board_flashHandle Board_flashOpen(uint32_t deviceId, uint32_t portNum, void *params)
73 {
74 #if defined(BOARD_QSPI_FLASH_IN)
75 FLASH_HANDLE flashHandle;
76 uint8_t idCode[3];
77 int32_t device_id;
79 if (deviceId == BOARD_FLASH_ID_QSPIFLASH_S25FL512S)
80 {
81 /* Initialize the qspi flash */
82 flashHandle = qspiNorInit(portNum, params);
83 if (!flashHandle)
84 {
85 return 0;
86 }
88 if (qspiNorReadId(flashHandle, idCode) != QSPI_NOR_SUCCESS)
89 {
90 qspiNorClose(flashHandle);
91 return 0;
92 }
94 device_id = (idCode[1] << 8) | (idCode[2]);
95 if (device_id != BOARD_FLASH_ID_QSPIFLASH_S25FL512S)
96 {
97 qspiNorClose(flashHandle);
98 return 0;
99 }
101 Board_flashInfo.flashHandle = flashHandle;
102 Board_flashInfo.device_id = device_id;
103 Board_flashInfo.manufacturer_id = idCode[0];
105 return (Board_flashHandle)&(Board_flashInfo);
106 }
107 #endif
109 return 0;
110 }
112 /******************************************************************************
113 * BOARD_flashClose
114 ******************************************************************************/
115 Board_flash_STATUS Board_flashClose(Board_flashHandle handle)
116 {
117 Board_FlashInfo *info;
119 if (!handle)
120 {
121 return BOARD_FLASH_EFAIL;
122 }
124 info = (Board_FlashInfo *)handle;
125 if (!info->flashHandle)
126 {
127 return BOARD_FLASH_EFAIL;
128 }
130 #if defined(BOARD_QSPI_FLASH_IN)
131 if (info->device_id == BOARD_FLASH_ID_QSPIFLASH_S25FL512S)
132 {
133 qspiNorClose(info->flashHandle);
134 }
135 #endif
137 info->flashHandle = 0;
138 return BOARD_FLASH_EOK;
139 }
141 /******************************************************************************
142 * BOARD_flashRead
143 ******************************************************************************/
144 Board_flash_STATUS Board_flashRead(Board_flashHandle handle,
145 uint32_t offset,
146 uint8_t *buf,
147 uint32_t len,
148 void *params)
149 {
150 Board_FlashInfo *info;
151 uint32_t qspiReadMode;
153 if (!handle)
154 {
155 return BOARD_FLASH_EFAIL;
156 }
158 info = (Board_FlashInfo *)handle;
159 if (!info->flashHandle)
160 {
161 return BOARD_FLASH_EFAIL;
162 }
164 if (buf == NULL || len == 0)
165 {
166 return BOARD_FLASH_EINVALID;
167 }
169 #if defined(BOARD_QSPI_FLASH_IN)
170 if (info->device_id == BOARD_FLASH_ID_QSPIFLASH_S25FL512S)
171 {
172 qspiReadMode = *((uint32_t *)params);
173 if (qspiNorRead(info->flashHandle, offset, len, buf, qspiReadMode) \
174 != QSPI_NOR_SUCCESS)
175 {
176 return (BOARD_FLASH_EFAIL);
177 }
178 return BOARD_FLASH_EOK;
179 }
180 #endif
182 return BOARD_FLASH_EUNSUPPORTED;
183 }
185 /******************************************************************************
186 * Computes a block and page based on an offset
187 ******************************************************************************/
188 Board_flash_STATUS Board_flashOffsetToBlkPage(Board_flashHandle handle,
189 uint32_t offset,
190 uint32_t *block,
191 uint32_t *page)
192 {
193 uint32_t leftover, block_size, block_count, page_size, page_count;
194 Board_FlashInfo *info;
196 if (!handle)
197 {
198 return BOARD_FLASH_EFAIL;
199 }
201 info = (Board_FlashInfo *)handle;
202 if (!info->flashHandle)
203 {
204 return BOARD_FLASH_EFAIL;
205 }
207 if (info->device_id == BOARD_FLASH_ID_QSPIFLASH_S25FL512S)
208 {
209 block_count = Board_flashInfo.block_count;
210 page_size = Board_flashInfo.page_size;
211 page_count = Board_flashInfo.page_count;
212 }
213 else
214 {
215 return BOARD_FLASH_EUNSUPPORTED;
216 }
218 block_size = (page_count * page_size);
220 *block = offset / block_size;
221 leftover = offset % block_size;
222 *page = leftover / page_size;
223 if (leftover % page_size)
224 {
225 /* All writes must be page aligned for now */
226 return BOARD_FLASH_EUNSUPPORTED;
227 }
228 if (*block > block_count)
229 {
230 return BOARD_FLASH_EINVALID;
231 }
232 if (*page > page_count)
233 {
234 return BOARD_FLASH_EINVALID;
235 }
237 return BOARD_FLASH_EOK;
239 }
241 /******************************************************************************
242 * Computes a block and page based on an offset
243 ******************************************************************************/
244 Board_flash_STATUS Board_flashBlkPageToOffset(Board_flashHandle handle,
245 uint32_t *offset,
246 uint32_t block,
247 uint32_t page)
248 {
250 uint32_t block_count, page_size, page_count;
251 Board_FlashInfo *info;
253 if (!handle)
254 {
255 return BOARD_FLASH_EFAIL;
256 }
258 info = (Board_FlashInfo *)handle;
259 if (!info->flashHandle)
260 {
261 return BOARD_FLASH_EFAIL;
262 }
264 if (info->device_id == BOARD_FLASH_ID_QSPIFLASH_S25FL512S)
265 {
266 block_count = Board_flashInfo.block_count;
267 page_size = Board_flashInfo.page_size;
268 page_count = Board_flashInfo.page_count;
269 }
270 else
271 {
272 return BOARD_FLASH_EUNSUPPORTED;
273 }
275 if (block >block_count || page > page_count)
276 {
277 return BOARD_FLASH_EINVALID;
278 }
280 *offset = (block * (page_count * page_size)) + (page * page_size);
282 return BOARD_FLASH_EOK;
283 }
285 /******************************************************************************
286 * BOARD_flashWrite
287 ******************************************************************************/
288 Board_flash_STATUS Board_flashWrite(Board_flashHandle handle,
289 uint32_t offset,
290 uint8_t *buf,
291 uint32_t len,
292 void *params)
293 {
294 Board_FlashInfo *info;
296 if (!handle)
297 {
298 return BOARD_FLASH_EFAIL;
299 }
301 info = (Board_FlashInfo *)handle;
302 if (!info->flashHandle)
303 {
304 return BOARD_FLASH_EFAIL;
305 }
307 if (buf == NULL || len == 0)
308 {
309 return BOARD_FLASH_EINVALID;
310 }
312 #if defined(BOARD_QSPI_FLASH_IN)
313 if (info->device_id == BOARD_FLASH_ID_QSPIFLASH_S25FL512S)
314 {
315 if (qspiNorWrite(info->flashHandle, offset, len, buf,
316 *((uint32_t *)params)) != QSPI_NOR_SUCCESS)
317 {
318 return (BOARD_FLASH_EFAIL);
319 }
320 return BOARD_FLASH_EOK;
321 }
322 #endif
324 return BOARD_FLASH_EUNSUPPORTED;
325 }
327 /******************************************************************************
328 * platform_device_erase_block
329 ******************************************************************************/
330 Board_flash_STATUS Board_flashEraseBlk(Board_flashHandle handle,
331 uint32_t blk_num)
332 {
333 Board_FlashInfo *info;
335 if (!handle)
336 {
337 return BOARD_FLASH_EFAIL;
338 }
340 info = (Board_FlashInfo *)handle;
341 if (!info->flashHandle)
342 {
343 return BOARD_FLASH_EFAIL;
344 }
346 if (blk_num > info->block_count)
347 {
348 return BOARD_FLASH_EFAIL;
349 }
351 #if defined(BOARD_QSPI_FLASH_IN)
352 if (info->device_id == BOARD_FLASH_ID_QSPIFLASH_S25FL512S)
353 {
354 if (qspiNorErase (info->flashHandle, blk_num) != QSPI_NOR_SUCCESS)
355 {
356 return (BOARD_FLASH_EFAIL);
357 }
358 return BOARD_FLASH_EOK;
359 }
360 #endif
362 return BOARD_FLASH_EUNSUPPORTED;
363 }