• 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_gd25qxx.c
18  *
19  * @brief   gd25qxx flash Driver Module
20  *
21  * @author  dave
22  *
23  * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
24  */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include "wm_type_def.h"
29 #include "wm_flash.h"
30 #include "wm_hostspi.h"
31 #include "wm_debug.h"
32 #include "wm_gpio.h"
33 #include "wm_fls_gd25qxx.h"
34 
35 static int tls_spifls_drv_read(u32 addr, u8 *buf, u32 len);
36 static int tls_spifls_drv_fast_read(u32 addr, u8 *buf, u32 len);
37 static int tls_spifls_drv_page_write(u32 page, u8 *buf);
38 static int tls_spifls_drv_erase(u32 sector);
39 static int tls_spifls_drv_chip_erase(void);
40 static int tls_spifls_drv_probe(u32 id);
41 static void tls_spifls_drv_remove(void);
42 
43 static struct tls_fls_drv exspi_fls = {
44     .drv_list = {NULL, NULL},
45     .clock = SPI_SCLK,
46     .mode = TLS_SPI_MODE_0,
47     .cs_active = TLS_SPI_CS_LOW,
48     .flags = 0,
49     .read = tls_spifls_drv_read,
50     .fast_read = tls_spifls_drv_fast_read,
51     .page_write = tls_spifls_drv_page_write,
52     .erase = tls_spifls_drv_erase,
53     .chip_erase = tls_spifls_drv_chip_erase,
54     .probe = tls_spifls_drv_probe,
55     .remove = tls_spifls_drv_remove
56 };
57 
58 static struct tls_fls_drv *exspifls_drv = NULL;
59 
swap32(unsigned int v)60 static unsigned int swap32(unsigned int v)
61 {
62     return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
63         ((v & 0xff0000) >> 8) | (v >> 24);
64 }
65 
tls_spifls_drv_write_enable(void)66 static int tls_spifls_drv_write_enable(void)
67 {
68     u8 cmd;
69     int err;
70 
71     cmd = EXSPIFLASH_WRITE_ENABLE;
72 
73     err = tls_spi_write((const u8 *) &cmd, 1);
74     if (err != TLS_SPI_STATUS_OK) {
75         return TLS_FLS_STATUS_EIO;
76     }
77 
78     return TLS_FLS_STATUS_OK;
79 }
80 
tls_spifls_drv_wait_write_enable(void)81 static int tls_spifls_drv_wait_write_enable(void)
82 {
83     u8 cmd;
84     u8 sr;
85 
86     cmd = EXSPIFLASH_READ_SR1;
87     sr = 0;
88     do {
89         int err = tls_spi_read_with_cmd((const u8 *) &cmd, 1, &sr, 1);
90         if (err != TLS_SPI_STATUS_OK) {
91             return TLS_FLS_STATUS_EIO;
92         }
93 
94         if (sr & FLASH_STATUS_WEL) {
95             break;
96         }
97     }while (1);
98 
99     return TLS_FLS_STATUS_OK;
100 }
101 
tls_spifls_drv_wait_flash_ready(void)102 static int tls_spifls_drv_wait_flash_ready(void)
103 {
104     u8 cmd;
105     u8 sr;
106 
107     cmd = EXSPIFLASH_READ_SR1;
108     sr = 0;
109     do {
110         int err = tls_spi_read_with_cmd((const u8 *) &cmd, 1, &sr, 1);
111         if (err != TLS_SPI_STATUS_OK) {
112             return TLS_FLS_STATUS_EIO;
113         }
114 
115         if ((sr & FLASH_STATUS_BUSY) == 0x00) {
116             break;
117         }
118     }while (1);
119 
120     return TLS_FLS_STATUS_OK;
121 }
122 
tls_spifls_drv_read(u32 addr,u8 * buf,u32 len)123 static int tls_spifls_drv_read(u32 addr, u8 * buf, u32 len)
124 {
125     u32 cmd;
126     int err;
127 
128     cmd = 0;
129     cmd |= EXSPIFLASH_DATA_READ;
130     cmd |= swap32(addr) & 0xffffff00;
131     err = tls_spi_read_with_cmd((const u8 *) &cmd, 4, buf, len);
132     if (err != TLS_SPI_STATUS_OK) {
133         return TLS_FLS_STATUS_EIO;
134     }
135 
136     return TLS_FLS_STATUS_OK;
137 }
138 
tls_spifls_drv_fast_read(u32 addr,u8 * buf,u32 len)139 static int tls_spifls_drv_fast_read(u32 addr, u8 * buf, u32 len)
140 {
141     return TLS_FLS_STATUS_ENOSUPPORT;
142 }
143 
tls_spifls_drv_page_write(u32 page,u8 * buf)144 static int tls_spifls_drv_page_write(u32 page, u8 * buf)
145 {
146     u32 cmd;
147     int err;
148 
149     err = tls_spifls_drv_write_enable();
150     if (err != TLS_SPI_STATUS_OK) {
151         return TLS_FLS_STATUS_EIO;
152     }
153 
154     err = tls_spifls_drv_wait_write_enable();
155     if (err != TLS_SPI_STATUS_OK) {
156         return TLS_FLS_STATUS_EIO;
157     }
158 
159     cmd = 0;
160     cmd |= EXSPIFLASH_PAGE_PROGRAM;
161     cmd |= swap32(page * exspifls_drv->page_size) & 0xffffff00;
162     err = tls_spi_write_with_cmd((const u8 *) &cmd, 4, (const u8 *) buf,
163                                  exspifls_drv->page_size);
164     if (err != TLS_SPI_STATUS_OK) {
165         return TLS_FLS_STATUS_EIO;
166     }
167 
168     err = tls_spifls_drv_wait_flash_ready();
169     if (err != TLS_SPI_STATUS_OK) {
170         return TLS_FLS_STATUS_EIO;
171     }
172 
173     return TLS_FLS_STATUS_OK;
174 }
175 
tls_spifls_drv_erase(u32 sector)176 static int tls_spifls_drv_erase(u32 sector)
177 {
178     u32 cmd;
179     int err;
180 
181     err = tls_spifls_drv_write_enable();
182     if (err != TLS_SPI_STATUS_OK) {
183         return TLS_FLS_STATUS_EIO;
184     }
185     err = tls_spifls_drv_wait_write_enable();
186     if (err != TLS_SPI_STATUS_OK) {
187         return TLS_FLS_STATUS_EIO;
188     }
189     cmd = 0;
190     cmd |= EXSPIFLASH_SECTOR_ERASE;
191     cmd |= swap32(sector * exspifls_drv->sector_size) & 0xffffff00;
192     err = tls_spi_write((const u8 *) &cmd, 4);
193     if (err != TLS_SPI_STATUS_OK) {
194         return TLS_FLS_STATUS_EIO;
195     }
196     tls_os_time_delay(6);
197     err = tls_spifls_drv_wait_flash_ready();
198     if (err != TLS_SPI_STATUS_OK) {
199         return TLS_FLS_STATUS_EIO;
200     }
201     return TLS_FLS_STATUS_OK;
202 }
203 
tls_spifls_drv_chip_erase(void)204 static int tls_spifls_drv_chip_erase(void)
205 {
206     u8 cmd;
207     int err;
208 
209     err = tls_spifls_drv_write_enable();
210     if (err != TLS_SPI_STATUS_OK) {
211         return TLS_FLS_STATUS_EIO;
212     }
213 
214     err = tls_spifls_drv_wait_write_enable();
215     if (err != TLS_SPI_STATUS_OK) {
216         return TLS_FLS_STATUS_EIO;
217     }
218 
219     cmd = EXSPIFLASH_CHIP_ERASE;
220     err = tls_spi_write((const u8 *) &cmd, 1);
221     if (err != TLS_SPI_STATUS_OK) {
222         return TLS_FLS_STATUS_EIO;
223     }
224 
225     err = tls_spifls_drv_wait_flash_ready();
226     if (err != TLS_SPI_STATUS_OK) {
227         return TLS_FLS_STATUS_EIO;
228     }
229 
230     return TLS_FLS_STATUS_OK;
231 }
232 
tls_spifls_drv_probe(u32 id)233 static int tls_spifls_drv_probe(u32 id)
234 {
235     if (!id) {
236         return TLS_FLS_STATUS_EINVAL;
237     }
238 
239     exspi_fls.id = id;
240     if ((id>>16)&0xFF) {
241         exspi_fls.total_size = 1 << (id>>16);
242     } else {
243         exspi_fls.total_size = FLASH_TOTAL_SIZE; /* 1MByte */
244     }
245 
246     exspi_fls.page_size = PAGE_SIZE;
247     exspi_fls.program_size = PROGRAM_SIZE;
248     exspi_fls.sector_size = SECTOR_SIZE;
249     exspifls_drv = &exspi_fls;
250     return TLS_FLS_STATUS_OK;
251 }
252 
tls_spifls_drv_remove(void)253 static void tls_spifls_drv_remove(void)
254 {
255     exspifls_drv = NULL;
256 }
257 
258 /**
259  * @brief          This function is used to install gd25qxx driver.
260  *
261  * @param[in]      None
262  *
263  * @retval         TLS_FLS_STATUS_OK             if write flash success
264  * @retval         TLS_FLS_STATUS_EPERM     if flash struct point is null
265  * @retval         TLS_FLS_STATUS_ENODRV      if flash driver is not installed
266  * @retval         TLS_FLS_STATUS_EINVAL      if argument is invalid
267  * @retval         TLS_FLS_STATUS_EIO             if io error
268  * @retval         TLS_FLS_STATUS_EEXIST      if driver is already existed
269  *
270  * @note           None
271  */
tls_spifls_drv_install(void)272 int tls_spifls_drv_install(void)
273 {
274     int err;
275     extern int tls_spifls_probe(void);
276     extern int tls_spifls_drv_register(struct tls_fls_drv *fls_drv);
277 
278     err = tls_spifls_drv_register((struct tls_fls_drv *) &exspi_fls);
279     if (err == TLS_FLS_STATUS_EEXIST) {
280         return err;
281     }
282     TLS_DBGPRT_INFO("register the spi flash driver - %d.\n", err);
283 
284     err = tls_spifls_probe();
285     TLS_DBGPRT_INFO("probe spi flash - %d.\n", err);
286 
287     return err;
288 }