1 /*
2  * NAND Flash Controller Device Driver
3  * Copyright (c) 2009, Intel Corporation and its suppliers.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19 
20 #include "spectraswconfig.h"
21 #include "ffsport.h"
22 #include "ffsdefs.h"
23 #include "lld.h"
24 #include "lld_nand.h"
25 
26 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
27 #if FLASH_EMU		/* vector all the LLD calls to the LLD_EMU code */
28 #include "lld_emu.h"
29 #include "lld_cdma.h"
30 
31 /* common functions: */
GLOB_LLD_Flash_Reset(void)32 u16 GLOB_LLD_Flash_Reset(void)
33 {
34 	return emu_Flash_Reset();
35 }
36 
GLOB_LLD_Read_Device_ID(void)37 u16 GLOB_LLD_Read_Device_ID(void)
38 {
39 	return emu_Read_Device_ID();
40 }
41 
GLOB_LLD_Flash_Release(void)42 int GLOB_LLD_Flash_Release(void)
43 {
44 	return emu_Flash_Release();
45 }
46 
GLOB_LLD_Flash_Init(void)47 u16 GLOB_LLD_Flash_Init(void)
48 {
49 	return emu_Flash_Init();
50 }
51 
GLOB_LLD_Erase_Block(u32 block_add)52 u16 GLOB_LLD_Erase_Block(u32 block_add)
53 {
54 	return emu_Erase_Block(block_add);
55 }
56 
GLOB_LLD_Write_Page_Main(u8 * write_data,u32 block,u16 Page,u16 PageCount)57 u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
58 				u16 PageCount)
59 {
60 	return emu_Write_Page_Main(write_data, block, Page, PageCount);
61 }
62 
GLOB_LLD_Read_Page_Main(u8 * read_data,u32 block,u16 Page,u16 PageCount)63 u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 Page,
64 			       u16 PageCount)
65 {
66 	return emu_Read_Page_Main(read_data, block, Page, PageCount);
67 }
68 
GLOB_LLD_Read_Page_Main_Polling(u8 * read_data,u32 block,u16 page,u16 page_count)69 u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
70 			u32 block, u16 page, u16 page_count)
71 {
72 	return emu_Read_Page_Main(read_data, block, page, page_count);
73 }
74 
GLOB_LLD_Write_Page_Main_Spare(u8 * write_data,u32 block,u16 Page,u16 PageCount)75 u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
76 				      u16 Page, u16 PageCount)
77 {
78 	return emu_Write_Page_Main_Spare(write_data, block, Page, PageCount);
79 }
80 
GLOB_LLD_Read_Page_Main_Spare(u8 * read_data,u32 block,u16 Page,u16 PageCount)81 u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
82 				     u16 Page, u16 PageCount)
83 {
84 	return emu_Read_Page_Main_Spare(read_data, block, Page, PageCount);
85 }
86 
GLOB_LLD_Write_Page_Spare(u8 * write_data,u32 block,u16 Page,u16 PageCount)87 u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
88 				 u16 PageCount)
89 {
90 	return emu_Write_Page_Spare(write_data, block, Page, PageCount);
91 }
92 
GLOB_LLD_Read_Page_Spare(u8 * read_data,u32 block,u16 Page,u16 PageCount)93 u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
94 				u16 PageCount)
95 {
96 	return emu_Read_Page_Spare(read_data, block, Page, PageCount);
97 }
98 
GLOB_LLD_Get_Bad_Block(u32 block)99 u16  GLOB_LLD_Get_Bad_Block(u32 block)
100 {
101     return  emu_Get_Bad_Block(block);
102 }
103 
104 #endif /* FLASH_EMU */
105 
106 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
107 #if FLASH_MTD		/* vector all the LLD calls to the LLD_MTD code */
108 #include "lld_mtd.h"
109 #include "lld_cdma.h"
110 
111 /* common functions: */
GLOB_LLD_Flash_Reset(void)112 u16 GLOB_LLD_Flash_Reset(void)
113 {
114 	return mtd_Flash_Reset();
115 }
116 
GLOB_LLD_Read_Device_ID(void)117 u16 GLOB_LLD_Read_Device_ID(void)
118 {
119 	return mtd_Read_Device_ID();
120 }
121 
GLOB_LLD_Flash_Release(void)122 int GLOB_LLD_Flash_Release(void)
123 {
124 	return mtd_Flash_Release();
125 }
126 
GLOB_LLD_Flash_Init(void)127 u16 GLOB_LLD_Flash_Init(void)
128 {
129 	return mtd_Flash_Init();
130 }
131 
GLOB_LLD_Erase_Block(u32 block_add)132 u16 GLOB_LLD_Erase_Block(u32 block_add)
133 {
134 	return mtd_Erase_Block(block_add);
135 }
136 
GLOB_LLD_Write_Page_Main(u8 * write_data,u32 block,u16 Page,u16 PageCount)137 u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
138 				u16 PageCount)
139 {
140 	return mtd_Write_Page_Main(write_data, block, Page, PageCount);
141 }
142 
GLOB_LLD_Read_Page_Main(u8 * read_data,u32 block,u16 Page,u16 PageCount)143 u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 Page,
144 			       u16 PageCount)
145 {
146 	return mtd_Read_Page_Main(read_data, block, Page, PageCount);
147 }
148 
GLOB_LLD_Read_Page_Main_Polling(u8 * read_data,u32 block,u16 page,u16 page_count)149 u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
150 			u32 block, u16 page, u16 page_count)
151 {
152 	return mtd_Read_Page_Main(read_data, block, page, page_count);
153 }
154 
GLOB_LLD_Write_Page_Main_Spare(u8 * write_data,u32 block,u16 Page,u16 PageCount)155 u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
156 				      u16 Page, u16 PageCount)
157 {
158 	return mtd_Write_Page_Main_Spare(write_data, block, Page, PageCount);
159 }
160 
GLOB_LLD_Read_Page_Main_Spare(u8 * read_data,u32 block,u16 Page,u16 PageCount)161 u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
162 				     u16 Page, u16 PageCount)
163 {
164 	return mtd_Read_Page_Main_Spare(read_data, block, Page, PageCount);
165 }
166 
GLOB_LLD_Write_Page_Spare(u8 * write_data,u32 block,u16 Page,u16 PageCount)167 u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
168 				 u16 PageCount)
169 {
170 	return mtd_Write_Page_Spare(write_data, block, Page, PageCount);
171 }
172 
GLOB_LLD_Read_Page_Spare(u8 * read_data,u32 block,u16 Page,u16 PageCount)173 u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
174 				u16 PageCount)
175 {
176 	return mtd_Read_Page_Spare(read_data, block, Page, PageCount);
177 }
178 
GLOB_LLD_Get_Bad_Block(u32 block)179 u16  GLOB_LLD_Get_Bad_Block(u32 block)
180 {
181     return  mtd_Get_Bad_Block(block);
182 }
183 
184 #endif /* FLASH_MTD */
185 
186 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
187 #if FLASH_NAND	/* vector all the LLD calls to the NAND controller code */
188 #include "lld_nand.h"
189 #include "lld_cdma.h"
190 #include "flash.h"
191 
192 /* common functions for LLD_NAND */
GLOB_LLD_ECC_Control(int enable)193 void GLOB_LLD_ECC_Control(int enable)
194 {
195 	NAND_ECC_Ctrl(enable);
196 }
197 
198 /* common functions for LLD_NAND */
GLOB_LLD_Flash_Reset(void)199 u16 GLOB_LLD_Flash_Reset(void)
200 {
201 	return NAND_Flash_Reset();
202 }
203 
GLOB_LLD_Read_Device_ID(void)204 u16 GLOB_LLD_Read_Device_ID(void)
205 {
206 	return NAND_Read_Device_ID();
207 }
208 
GLOB_LLD_UnlockArrayAll(void)209 u16 GLOB_LLD_UnlockArrayAll(void)
210 {
211 	return NAND_UnlockArrayAll();
212 }
213 
GLOB_LLD_Flash_Init(void)214 u16 GLOB_LLD_Flash_Init(void)
215 {
216 	return NAND_Flash_Init();
217 }
218 
GLOB_LLD_Flash_Release(void)219 int GLOB_LLD_Flash_Release(void)
220 {
221 	return nand_release_spectra();
222 }
223 
GLOB_LLD_Erase_Block(u32 block_add)224 u16 GLOB_LLD_Erase_Block(u32 block_add)
225 {
226 	return NAND_Erase_Block(block_add);
227 }
228 
229 
GLOB_LLD_Write_Page_Main(u8 * write_data,u32 block,u16 Page,u16 PageCount)230 u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
231 				u16 PageCount)
232 {
233 	return NAND_Write_Page_Main(write_data, block, Page, PageCount);
234 }
235 
GLOB_LLD_Read_Page_Main(u8 * read_data,u32 block,u16 page,u16 page_count)236 u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 page,
237 			       u16 page_count)
238 {
239 	if (page_count == 1) /* Using polling to improve read speed */
240 		return NAND_Read_Page_Main_Polling(read_data, block, page, 1);
241 	else
242 		return NAND_Read_Page_Main(read_data, block, page, page_count);
243 }
244 
GLOB_LLD_Read_Page_Main_Polling(u8 * read_data,u32 block,u16 page,u16 page_count)245 u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
246 			u32 block, u16 page, u16 page_count)
247 {
248 	return NAND_Read_Page_Main_Polling(read_data,
249 			block, page, page_count);
250 }
251 
GLOB_LLD_Write_Page_Main_Spare(u8 * write_data,u32 block,u16 Page,u16 PageCount)252 u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
253 				      u16 Page, u16 PageCount)
254 {
255 	return NAND_Write_Page_Main_Spare(write_data, block, Page, PageCount);
256 }
257 
GLOB_LLD_Write_Page_Spare(u8 * write_data,u32 block,u16 Page,u16 PageCount)258 u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
259 				 u16 PageCount)
260 {
261 	return NAND_Write_Page_Spare(write_data, block, Page, PageCount);
262 }
263 
GLOB_LLD_Read_Page_Main_Spare(u8 * read_data,u32 block,u16 page,u16 page_count)264 u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
265 				     u16 page, u16 page_count)
266 {
267 	return NAND_Read_Page_Main_Spare(read_data, block, page, page_count);
268 }
269 
GLOB_LLD_Read_Page_Spare(u8 * read_data,u32 block,u16 Page,u16 PageCount)270 u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
271 				u16 PageCount)
272 {
273 	return NAND_Read_Page_Spare(read_data, block, Page, PageCount);
274 }
275 
GLOB_LLD_Get_Bad_Block(u32 block)276 u16  GLOB_LLD_Get_Bad_Block(u32 block)
277 {
278 	return  NAND_Get_Bad_Block(block);
279 }
280 
281 #if CMD_DMA
GLOB_LLD_Event_Status(void)282 u16 GLOB_LLD_Event_Status(void)
283 {
284 	return CDMA_Event_Status();
285 }
286 
glob_lld_execute_cmds(void)287 u16 glob_lld_execute_cmds(void)
288 {
289 	return CDMA_Execute_CMDs();
290 }
291 
GLOB_LLD_MemCopy_CMD(u8 * dest,u8 * src,u32 ByteCount,u16 flag)292 u16 GLOB_LLD_MemCopy_CMD(u8 *dest, u8 *src,
293 			u32 ByteCount, u16 flag)
294 {
295 	/* Replace the hardware memcopy with software memcpy function */
296 	if (CDMA_Execute_CMDs())
297 		return FAIL;
298 	memcpy(dest, src, ByteCount);
299 	return PASS;
300 
301 	/* return CDMA_MemCopy_CMD(dest, src, ByteCount, flag); */
302 }
303 
GLOB_LLD_Erase_Block_cdma(u32 block,u16 flags)304 u16 GLOB_LLD_Erase_Block_cdma(u32 block, u16 flags)
305 {
306 	return CDMA_Data_CMD(ERASE_CMD, 0, block, 0, 0, flags);
307 }
308 
GLOB_LLD_Write_Page_Main_cdma(u8 * data,u32 block,u16 page,u16 count)309 u16 GLOB_LLD_Write_Page_Main_cdma(u8 *data, u32 block, u16 page, u16 count)
310 {
311 	return CDMA_Data_CMD(WRITE_MAIN_CMD, data, block, page, count, 0);
312 }
313 
GLOB_LLD_Read_Page_Main_cdma(u8 * data,u32 block,u16 page,u16 count,u16 flags)314 u16 GLOB_LLD_Read_Page_Main_cdma(u8 *data, u32 block, u16 page,
315 				u16 count, u16 flags)
316 {
317 	return CDMA_Data_CMD(READ_MAIN_CMD, data, block, page, count, flags);
318 }
319 
GLOB_LLD_Write_Page_Main_Spare_cdma(u8 * data,u32 block,u16 page,u16 count,u16 flags)320 u16 GLOB_LLD_Write_Page_Main_Spare_cdma(u8 *data, u32 block, u16 page,
321 					u16 count, u16 flags)
322 {
323 	return CDMA_Data_CMD(WRITE_MAIN_SPARE_CMD,
324 			data, block, page, count, flags);
325 }
326 
GLOB_LLD_Read_Page_Main_Spare_cdma(u8 * data,u32 block,u16 page,u16 count)327 u16 GLOB_LLD_Read_Page_Main_Spare_cdma(u8 *data,
328 				u32 block, u16 page, u16 count)
329 {
330 	return CDMA_Data_CMD(READ_MAIN_SPARE_CMD, data, block, page, count,
331 			LLD_CMD_FLAG_MODE_CDMA);
332 }
333 
334 #endif /* CMD_DMA */
335 #endif /* FLASH_NAND */
336 
337 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
338 
339 /* end of LLD.c */
340