• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
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 /**
17  * @file    wm_fls.c
18  *
19  * @brief   flash Driver Module
20  *
21  * @author  dave
22  *
23  * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
24  */
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 
29 #include "list.h"
30 #include "wm_hostspi.h"
31 #include "wm_flash.h"
32 #include "wm_dbg.h"
33 #include "wm_mem.h"
34 #include "wm_fls_gd25qxx.h"
35 
36 static struct tls_fls *spi_fls = NULL;
37 
tls_spifls_read_id(u32 * id)38 static int tls_spifls_read_id(u32 * id)
39 {
40     u32 cmd;
41     int err;
42 
43     cmd = FLS_CMD_READ_DEV_ID;
44     *id = 0;
45 
46     err = tls_spi_read_with_cmd((const u8 *) &cmd, 4, (u8 *) id, 3);
47     if (err != TLS_SPI_STATUS_OK) {
48         TLS_DBGPRT_ERR("flash read ID fail(%d)!\n", err);
49         return TLS_FLS_STATUS_EIO;
50     }
51 
52     TLS_DBGPRT_FLASH_INFO("flash ID - 0x%x.\n", *id);
53 
54     return TLS_FLS_STATUS_OK;
55 }
56 
57 /**
58  * @brief          This function is used to read data from the flash.
59  *
60  * @param[in]      addr                 is byte offset addr for read from the flash.
61  * @param[in]      buf                   is user for data buffer of flash read
62  * @param[in]      len                   is byte length for read.
63  *
64  * @retval         TLS_FLS_STATUS_OK        if read sucsess
65  * @retval         TLS_FLS_STATUS_EIO        if read fail
66  *
67  * @note           None
68  */
tls_spifls_read(u32 addr,u8 * buf,u32 len)69 int tls_spifls_read(u32 addr, u8 * buf, u32 len)
70 {
71     int err;
72     u32 read_bytes;
73     struct tls_fls_drv *drv;
74 
75     if (spi_fls == NULL) {
76         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
77         return TLS_FLS_STATUS_EPERM;
78     }
79 
80     if (spi_fls->current_drv == NULL) {
81         TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
82         return TLS_FLS_STATUS_ENODRV;
83     }
84 
85     if ((addr >= spi_fls->current_drv->total_size) || (len == 0)
86         || (buf == NULL)) {
87         return TLS_FLS_STATUS_EINVAL;
88     }
89     tls_os_sem_acquire(spi_fls->fls_lock, 0);
90     drv = spi_fls->current_drv;
91     read_bytes =
92         ((addr + len) > drv->total_size) ? (drv->total_size - addr) : len;
93 
94     err = drv->read(addr, buf, read_bytes);
95     tls_os_sem_release(spi_fls->fls_lock);
96     return err;
97 }
98 
tls_spifls_fast_read(u32 addr,u8 * buf,u32 len)99 int tls_spifls_fast_read(u32 addr, u8 * buf, u32 len)
100 {
101     int err;
102     u32 read_bytes;
103     struct tls_fls_drv *drv;
104 
105     if (spi_fls == NULL) {
106         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
107         return TLS_FLS_STATUS_EPERM;
108     }
109 
110     if (spi_fls->current_drv == NULL) {
111         TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
112         return TLS_FLS_STATUS_ENODRV;
113     }
114 
115     if ((addr >= spi_fls->current_drv->total_size) || (len == 0)
116         || (buf == NULL)) {
117         return TLS_FLS_STATUS_EINVAL;
118     }
119     if ((spi_fls->current_drv->flags & TLS_FLS_FLAG_FAST_READ) !=
120         TLS_FLS_FLAG_FAST_READ) {
121         return TLS_FLS_STATUS_ENOSUPPORT;
122     }
123 
124     drv = spi_fls->current_drv;
125     read_bytes =
126         ((addr + len) > drv->total_size) ? (drv->total_size - addr) : len;
127 
128     err = drv->fast_read(addr, buf, read_bytes);
129 
130     return err;
131 }
132 
tls_spifls_page_write(u32 page,u8 * buf,u32 page_cnt)133 int tls_spifls_page_write(u32 page, u8 * buf, u32 page_cnt)
134 {
135     int err;
136     u32 write_pages;
137     u32 i;
138     struct tls_fls_drv *drv;
139 
140     if (spi_fls == NULL) {
141         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
142         return TLS_FLS_STATUS_EPERM;
143     }
144 
145     if (spi_fls->current_drv == NULL) {
146         TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
147         return TLS_FLS_STATUS_ENODRV;
148     }
149 
150     if ((page >= (spi_fls->current_drv->total_size / spi_fls->current_drv->page_size))
151         || (page_cnt == 0) || (buf == NULL)) {
152         return TLS_FLS_STATUS_EINVAL;
153     }
154 
155     drv = spi_fls->current_drv;
156     write_pages = ((page + page_cnt) > (drv->total_size / drv->page_size)) ?
157                     ((drv->total_size / drv->page_size) -page) : page_cnt;
158 
159     err = TLS_FLS_STATUS_OK;
160 
161     for (i = 0; i < write_pages; i++) {
162         err = drv->page_write(page + i, buf + i * drv->page_size);
163         if (err != TLS_FLS_STATUS_OK) {
164             TLS_DBGPRT_ERR("flash page write fail(page %d)!\n", (page + i));
165             break;
166         }
167     }
168 
169     return err;
170 }
171 
172 /**
173  * @brief          This function is used to write data to the flash.
174  *
175  * @param[in]      addr     is byte offset addr for write to the flash
176  * @param[in]      buf       is the data buffer want to write to flash
177  * @param[in]      len       is the byte length want to write
178  *
179  * @retval         TLS_FLS_STATUS_OK               if write flash success
180  * @retval         TLS_FLS_STATUS_EPERM        if flash struct point is null
181  * @retval         TLS_FLS_STATUS_ENODRV        if flash driver is not installed
182  * @retval         TLS_FLS_STATUS_EINVAL        if argument is invalid
183  * @retval         TLS_FLS_STATUS_EIO           if io error
184  *
185  * @note           None
186  */
tls_spifls_write(u32 addr,u8 * buf,u32 len)187 int tls_spifls_write(u32 addr, u8 * buf, u32 len)
188 {
189     u8 *cache;
190     int err;
191     u32 sector_addr;
192     u32 sector_num;
193     u32 write_bytes;
194     u32 i;
195     struct tls_fls_drv *drv;
196 
197     if (spi_fls == NULL) {
198         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
199         return TLS_FLS_STATUS_EPERM;
200     }
201 
202     if (spi_fls->current_drv == NULL) {
203         TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
204         return TLS_FLS_STATUS_ENODRV;
205     }
206 
207     if ((addr >= spi_fls->current_drv->total_size) || (len == 0)
208         || (buf == NULL)) {
209         return TLS_FLS_STATUS_EINVAL;
210     }
211     tls_os_sem_acquire(spi_fls->fls_lock, 0);
212     drv = spi_fls->current_drv;
213     write_bytes =
214         ((addr + len) > drv->total_size) ? (drv->total_size - addr) : len;
215     sector_addr = addr / drv->sector_size;
216     sector_num = (addr + write_bytes - 1) / drv->sector_size - sector_addr + 1;
217 
218     TLS_DBGPRT_FLASH_INFO("write to flash: sector address - %d, sectors - %d.\n", sector_addr, sector_num);
219 
220     err = TLS_FLS_STATUS_OK;
221 
222     cache = tls_mem_alloc(drv->sector_size);
223     if (cache == NULL) {
224         tls_os_sem_release(spi_fls->fls_lock);
225         TLS_DBGPRT_ERR("allocate sector cache memory(%dB) fail!\n",
226                        drv->sector_size);
227         return TLS_FLS_STATUS_ENOMEM;
228     }
229 
230     for (i = 0; i < sector_num; i++) {
231         TLS_DBGPRT_FLASH_INFO("firstly, read the sector - %d to cache.\n",
232                               sector_addr + i);
233         err = drv->read((sector_addr + i) * drv->sector_size, cache, drv->sector_size);
234         if (err != TLS_FLS_STATUS_OK) {
235             tls_os_sem_release(spi_fls->fls_lock);
236             TLS_DBGPRT_ERR("flash read fail(sector %d)!\n", (sector_addr + i));
237             break;
238         }
239 
240         if (sector_num == 1) { /* flash write only in one sector */
241             MEMCPY(cache + (addr%drv->sector_size), buf, write_bytes);
242             buf += write_bytes;
243             write_bytes = 0;
244         } else { /* flash write through some sectors */
245             if (i == 0) {
246                 MEMCPY(cache+(addr%drv->sector_size), buf, drv->sector_size - (addr%drv->sector_size));
247                 buf += drv->sector_size - (addr%drv->sector_size);
248                 write_bytes -= drv->sector_size - (addr%drv->sector_size);
249             } else if (i == (sector_num - 1)) {
250                 MEMCPY(cache, buf, write_bytes);
251                 buf += write_bytes;
252                 write_bytes = 0;
253             } else {
254                 MEMCPY(cache, buf, drv->sector_size);
255                 buf += drv->sector_size;
256                 write_bytes -= drv->sector_size;
257             }
258         }
259 
260         TLS_DBGPRT_FLASH_INFO("second, erase the sector - %d.\n",
261                               sector_addr + i);
262         err = drv->erase(sector_addr + i);
263         if (err != TLS_FLS_STATUS_OK) {
264             tls_os_sem_release(spi_fls->fls_lock);
265             TLS_DBGPRT_ERR("flash erase fail(sector %d)!\n", (sector_addr + i));
266             break;
267         }
268 
269         TLS_DBGPRT_FLASH_INFO("finnaly, write the data in cache to the sector - %d.\n", sector_addr + i);
270         err = tls_spifls_page_write((sector_addr +i) * (drv->sector_size / drv->page_size),
271                                     cache, drv->sector_size / drv->page_size);
272         if (err != TLS_FLS_STATUS_OK) {
273             tls_os_sem_release(spi_fls->fls_lock);
274             TLS_DBGPRT_ERR("flash write fail(sector %d)!\n", (sector_addr + i));
275             break;
276         }
277     }
278 
279     tls_mem_free(cache);
280     tls_os_sem_release(spi_fls->fls_lock);
281     return err;
282 }
283 
tls_spifls_erase(u32 sector)284 int tls_spifls_erase(u32 sector)
285 {
286     int err;
287     struct tls_fls_drv *drv;
288 
289     if (spi_fls == NULL) {
290         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
291         return TLS_FLS_STATUS_EPERM;
292     }
293 
294     if (spi_fls->current_drv == NULL) {
295         TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
296         return TLS_FLS_STATUS_ENODRV;
297     }
298 
299     if (sector >= (spi_fls->current_drv->total_size / spi_fls->current_drv->sector_size)) {
300         TLS_DBGPRT_ERR("the sector to be erase overflow!\n");
301         return TLS_FLS_STATUS_EINVAL;
302     }
303     tls_os_sem_acquire(spi_fls->fls_lock, 0);
304     drv = spi_fls->current_drv;
305 
306     err = drv->erase(sector);
307     tls_os_sem_release(spi_fls->fls_lock);
308     return err;
309 }
310 
tls_spifls_chip_erase(void)311 int tls_spifls_chip_erase(void)
312 {
313     int err;
314     struct tls_fls_drv *drv;
315 
316     if (spi_fls == NULL) {
317         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
318         return TLS_FLS_STATUS_EPERM;
319     }
320 
321     if (spi_fls->current_drv == NULL) {
322         TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
323         return TLS_FLS_STATUS_ENODRV;
324     }
325 
326     drv = spi_fls->current_drv;
327 
328     err = drv->chip_erase();
329 
330     return err;
331 }
332 
tls_spifls_get_param(u8 type,void * param)333 int tls_spifls_get_param(u8 type, void *param)
334 {
335     int err;
336     struct tls_fls_drv *drv;
337 
338     if (spi_fls == NULL) {
339         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
340         return TLS_FLS_STATUS_EPERM;
341     }
342 
343     if (spi_fls->current_drv == NULL) {
344         TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
345         return TLS_FLS_STATUS_ENODRV;
346     }
347 
348     if (param == NULL) {
349         return TLS_FLS_STATUS_EINVAL;
350     }
351     tls_os_sem_acquire(spi_fls->fls_lock, 0);
352     drv = spi_fls->current_drv;
353     err = TLS_FLS_STATUS_OK;
354     switch (type) {
355         case TLS_FLS_PARAM_TYPE_ID:
356             *((u32 *) param) = drv->id;
357             break;
358 
359         case TLS_FLS_PARAM_TYPE_SIZE:
360             *((u32 *) param) = drv->total_size;
361             break;
362 
363         case TLS_FLS_PARAM_TYPE_PAGE_SIZE:
364             *((u32 *) param) = drv->page_size;
365             break;
366 
367         case TLS_FLS_PARAM_TYPE_PROG_SIZE:
368             *((u32 *) param) = drv->program_size;
369             break;
370 
371         case TLS_FLS_PARAM_TYPE_SECTOR_SIZE:
372             *((u32 *) param) = drv->sector_size;
373             break;
374 
375         default:
376             TLS_DBGPRT_WARNING("invalid parameter ID!\n");
377             err = TLS_FLS_STATUS_EINVAL;
378             break;
379     }
380     tls_os_sem_release(spi_fls->fls_lock);
381     return err;
382 }
383 
tls_spifls_drv_register(struct tls_fls_drv * fls_drv)384 int tls_spifls_drv_register(struct tls_fls_drv *fls_drv)
385 {
386     u32 cpu_sr;
387     struct tls_fls_drv *drv;
388 
389     if (fls_drv == NULL) {
390         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
391         return TLS_FLS_STATUS_EINVAL;
392     }
393 
394     dl_list_for_each(drv, &spi_fls->fls_drvs, struct tls_fls_drv, drv_list)
395     {
396         if (drv->id == fls_drv->id) {
397             TLS_DBGPRT_WARNING
398                 ("corresponding spi flash driver has registered!\n");
399             return TLS_FLS_STATUS_EEXIST;
400         }
401     }
402 
403     cpu_sr = tls_os_set_critical();
404     dl_list_add_tail((struct dl_list *) &spi_fls->fls_drvs,
405                      (struct dl_list *) &fls_drv->drv_list);
406     tls_os_release_critical(cpu_sr);
407 
408     TLS_DBGPRT_FLASH_INFO("the spi flash driver is registered successfully!\n");
409 
410     return TLS_FLS_STATUS_OK;
411 }
412 
tls_spifls_drv_unregister(struct tls_fls_drv * fls_drv)413 int tls_spifls_drv_unregister(struct tls_fls_drv *fls_drv)
414 {
415     TLS_DBGPRT_WARNING("unregister spi flash driver operation is not supported!\n");
416     return TLS_FLS_STATUS_EPERM;
417 }
418 
tls_spifls_probe(void)419 int tls_spifls_probe(void)
420 {
421     int err;
422     u32 id;
423     struct tls_fls_drv *drv;
424 
425     if (spi_fls == NULL) {
426         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
427         return TLS_FLS_STATUS_EPERM;
428     }
429     if (spi_fls->current_drv != NULL) {
430         TLS_DBGPRT_ERR("the current spi flash has fount the matched driver!\n");
431         return TLS_FLS_STATUS_EBUSY;
432     }
433 
434     TLS_DBGPRT_FLASH_INFO("try to read the current spi flash ID.\n");
435     err = tls_spifls_read_id(&id);
436     if (err != TLS_FLS_STATUS_OK) {
437         return err;
438     }
439 
440     TLS_DBGPRT_FLASH_INFO("current spi flash ID - 0x%x.\n", id);
441 
442     dl_list_for_each(drv, &spi_fls->fls_drvs, struct tls_fls_drv, drv_list)
443     {
444         err = drv->probe(id);
445         if (err != TLS_FLS_STATUS_OK) {
446             return err;
447         }
448 
449         tls_spi_setup(drv->mode, drv->cs_active, drv->clock);
450 
451         TLS_DBGPRT_FLASH_INFO("matched the spi flash driver.\n");
452         spi_fls->current_drv = drv;
453         break;
454     }
455 
456     if (spi_fls->current_drv == NULL) {
457         TLS_DBGPRT_WARNING("not found the matched spi flash driver!\n");
458         return TLS_FLS_STATUS_ENODRV;
459     }
460 
461     return TLS_FLS_STATUS_OK;
462 }
463 
tls_spifls_init(void)464 int tls_spifls_init(void)
465 {
466     struct tls_fls *fls;
467     int err;
468 
469     if (spi_fls != NULL) {
470         TLS_DBGPRT_ERR("flash driver module has been installed!\n");
471         return TLS_FLS_STATUS_EBUSY;
472     }
473 
474     fls = (struct tls_fls *) tls_mem_alloc(sizeof(struct tls_fls));
475     if (fls == NULL) {
476         TLS_DBGPRT_ERR("allocate @spi_fls fail!\n");
477         return TLS_FLS_STATUS_ENOMEM;
478     }
479 
480     memset_s(fls, sizeof(fls), 0, sizeof(*fls));
481     dl_list_init((struct dl_list *) &fls->fls_drvs);
482     err = tls_os_sem_create(&fls->fls_lock, 1);
483     if (err != TLS_OS_SUCCESS) {
484         tls_mem_free(fls);
485         TLS_DBGPRT_ERR("create semaphore @fls_lock fail!\n");
486         return TLS_FLS_STATUS_ENOMEM;
487     }
488     spi_fls = fls;
489 
490     tls_spifls_drv_install();
491 
492     return TLS_FLS_STATUS_OK;
493 }
494 
tls_spifls_exit(void)495 int tls_spifls_exit(void)
496 {
497     TLS_DBGPRT_FLASH_INFO("Not support flash driver module uninstalled!\n");
498     return TLS_FLS_STATUS_EPERM;
499 }