blob: 8c31a803133d9682abbeffc6f742204e086f19f0 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2 *
3 * (C)Copyright 2013 Marvell. All Rights Reserved.
4 *
5 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
6 * The copyright notice above does not evidence any actual or intended
7 * publication of such source code.
8 * This Module contains Proprietary Information of Marvell and should be
9 * treated as Confidential.
10 * The information in this file is provided for the exclusive use of the
11 * licensees of Marvell.
12 * Such users have the right to use, modify, and incorporate this code into
13 * products for purposes authorized by the license agreement provided they
14 * include this notice and the associated copyright notice with any such
15 * product.
16 * The information in this file is provided "AS IS" without warranty.
17 *
18 ******************************************************************************/
19
20#include "SPINAND.h"
21#include "spi.h"
22#include "Errors.h"
23#include "misc.h"
24#include "timer.h"
25#include "PlatformConfig.h"
26#include "platform_interrupts.h"
27#include "xllp_dmac.h"
28
29extern volatile P_XLLP_DMAC_T pDmacHandle;
30
31extern UINT_T ssp_52mhz;
32extern UINT_T spi_tx_dma, spi_rx_dma;
33
34/***********************************************************
35* InitializeSPINAND()
36* Initializes the SSP port on the platform and issues
37* a Read ID command to see if a device is connected
38* returns:
39* NoError - on a successful read ID
40* NotFoundError - when read ID value is bogus (0xFFFF or 0x0000)
41************************************************************/
42UINT_T InitializeSPINAND(UINT8_T FlashNum, FlashBootType_T FlashBootType, UINT8_T* P_DefaultPartitionNum)
43{
44 unsigned char mid, did, sn_feature;
45 P_FlashProperties_T pFlashP = GetFlashProperties(FlashBootType);
46 int i;
47
48 ssp_52mhz = 1;
49
50 ChipSelectSPINAND();
51
52 SPINAND_Reset(FlashBootType);
53
54 SPINAND_ReadID(&mid, &did);
55
56 obm_printf("Manufactory and Device ID: 0x%08x\n\r", (mid<<8)|(did));
57
58 SPINAND_UnProtectBlocks();
59
60 sn_feature = SPINAND_GetFeatures(SN_FEATURE);
61 obm_printf("SN_FEATURE: 0x%x\n\r", sn_feature);
62
63 if ((sn_feature & GIGA_SPINAND_FEATURE_ECC_EN) == 0)
64 SPINAND_SetFeatures(SN_FEATURE, (sn_feature | GIGA_SPINAND_FEATURE_ECC_EN));
65
66 //define functions
67 pFlashP->ReadFromFlash = &SPINAND_Read;
68 pFlashP->WriteToFlash = &SPINAND_Write;
69 pFlashP->EraseFlash = &SPINAND_Erase;
70 pFlashP->ResetFlash = &SPINAND_Reset;
71 pFlashP->FlashSettings.UseBBM = 1;
72 pFlashP->FlashSettings.UseSpareArea = 0;
73 pFlashP->PageSize = 2048;
74 pFlashP->BlockSize = 128*1024;
75 pFlashP->FlashSettings.SASize = 0;
76 pFlashP->FlashSettings.UseHwEcc = 0;
77 pFlashP->StreamingFlash = FALSE;
78 pFlashP->FlashType = SPI_NAND;
79 pFlashP->FinalizeFlash = NULL;
80 pFlashP->TimFlashAddress = 0;
81 pFlashP->NumBlocks = 1024;
82
83 *P_DefaultPartitionNum = 0;
84
85 SPI_GetSSPDMAReqNum(&spi_tx_dma, &spi_rx_dma);
86
87 return NoError;
88}
89
90/***********************************************************
91* SPINAND_ReadID
92* Reads the 16 bit MID and DID
93* Returns:
94* None
95*************************************************************/
96void SPINAND_ReadID(unsigned char *mid, unsigned char *did)
97{
98 unsigned char cmd[4], data[4];
99
100 cmd[0] = SN_READ_ID;
101 cmd[1] = 0;
102 cmd[2] = 0;
103 cmd[3] = 0;
104
105 SPI_DisableSSP();
106
107 // workaround for 52MHz SPI bit shift
108 if (ssp_52mhz)
109 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
110 //fire it up
111 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
112
113 Assert_CS();
114
115 SPI_Write_Read(cmd, data, sizeof(cmd));
116
117 Deassert_CS();
118
119 SPI_DisableSSP();
120
121 *mid = data[2];
122 *did = data[3];
123
124 return;
125}
126
127
128// SPI NAND READ: using DMA
129unsigned int SPINAND_Read(unsigned int FlashOffset, unsigned int Buffer, unsigned int Size)
130{
131 unsigned int retval = NoError, read_size, start_time;
132 unsigned char status;
133
134 //calculate the initial read size (for the first page)
135 read_size = SN_PAGE_SIZE - (FlashOffset & (SN_PAGE_SIZE - 1)); //whole page - pre_bytes
136
137 //for each loop iteration, one page of flash will be read into internal memory
138 while (Size > 0)
139 { //update read_size if there are post_bytes (i.e. leftover for the last page)
140 read_size = read_size > Size ? Size : read_size;
141
142 /** Step 1: Cache Load: Load the correct page into cache **/
143 SPINAND_CacheLoad(FlashOffset);
144
145 /** Step 2: Get Features: wait for OIP to be cleared **/
146 retval = SPINAND_CheckReady();
147 if(retval != NoError)
148 break;
149
150 /** Step 3: Cache Read: Read the page in cache to memory (DMA) **/
151 retval = SPINAND_CacheRead_4Bytes(FlashOffset, Buffer, read_size);
152 if(retval != NoError)
153 break;
154
155 retval = SPINAND_CheckReady();
156 if(retval != NoError)
157 break;
158
159 /** Step 4: Update counters: make sure to adjust up to a page boundary each iteration **/
160 FlashOffset += read_size;
161 Buffer += read_size;
162 Size -= read_size;
163 read_size = SN_PAGE_SIZE;
164 }
165
166 return retval;
167}
168
169
170/***********************************************************
171* SPINAND_CacheLoad
172* Issues command to read a page of NAND into the cache
173* Inputs:
174* The flash address of the page to be loaded
175* Returns:
176* no returns
177*************************************************************/
178void SPINAND_CacheLoad(unsigned int Address)
179{
180 SN_ADDRESS_FIELD_T addr;
181 unsigned int input;
182
183 //store the command into the highest byte
184 input = SN_CACHE_LOAD << 24;
185 //put the 16 bits of Row Address (RA) into the lowest two bytes
186 addr.value = Address;
187 input |= (addr.fields.RA & 0xFFFF);
188
189 SPI_DisableSSP();
190
191 //setup in 32 bit mode
192 reg_bit_set(SSP_CR0, SSP_CR0_DSS_32);
193 // workaround for 52MHz SPI bit shift
194 if (ssp_52mhz)
195 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
196 //fire it up
197 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
198
199 Assert_CS();
200
201 //load the input data
202 BU_REG_WRITE(SSP_DR, input);
203 SPI_WaitSSPComplete();
204
205 Deassert_CS();
206
207 SPI_DisableSSP();
208
209 return;
210}
211
212/***********************************************************
213* SPINAND_GetFeatures
214* Reads the corresponding feature value of SPI device.
215* Inputs:
216* The feature type to be read out
217* Returns:
218* status value
219*************************************************************/
220unsigned char SPINAND_GetFeatures(SN_Feature_E feature_type)
221{
222 unsigned int input, status;
223
224 //fill out the command (2 bytes) plus dummy bytes for the readback
225 input = SN_GET_FEATURES << 24;
226 input |= (feature_type & 0xFF) << 16;
227
228 SPI_DisableSSP();
229
230 //setup in 32 bit mode
231 reg_bit_set(SSP_CR0, SSP_CR0_DSS_32);
232 // workaround for 52MHz SPI bit shift
233 if (ssp_52mhz)
234 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
235 //fire it up
236 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
237
238 Assert_CS();
239
240 //load the command
241 BU_REG_WRITE(SSP_DR, input);
242 SPI_WaitSSPComplete();
243
244 Deassert_CS();
245
246 status = BU_REG_READ(SSP_DR); //actual status value
247
248 SPI_DisableSSP();
249
250 //return last known status
251 return (unsigned char) ((status >> 8) & 0xff);
252}
253
254/***********************************************************
255* SPINAND_SetFeatures
256* set the corresponding feature value of SPI device.
257* Inputs:
258* The feature type to be set
259* Returns:
260* none
261*************************************************************/
262unsigned char SPINAND_SetFeatures(SN_Feature_E feature_type, unsigned char feature)
263{
264 unsigned int input;
265
266 //fill out the command (2 bytes) plus dummy bytes for the readback
267 input = SN_SET_FEATURES << 24;
268 input |= (feature_type & 0xFF) << 16;
269 input |= (feature & 0xff) << 8;
270
271 SPI_DisableSSP();
272
273 //setup in 32 bit mode
274 reg_bit_set(SSP_CR0, SSP_CR0_DSS_32);
275 // workaround for 52MHz SPI bit shift
276 if (ssp_52mhz)
277 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
278 //fire it up
279 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
280
281 Assert_CS();
282
283 //load the command
284 BU_REG_WRITE(SSP_DR, input);
285 SPI_WaitSSPComplete();
286
287 Deassert_CS();
288
289 SPI_DisableSSP();
290
291 return;
292}
293
294/***********************************************************
295* SPINAND_CacheRead
296* Reads the loaded page from Cache to internal memory using DMA
297* Inputs:
298* Offset into page
299* Buffer location
300* Size to be read
301* Returns:
302* error status
303*************************************************************/
304extern __attribute__ ((aligned(16))) XLLP_DMAC_DESCRIPTOR_T pRX_data, pTX_cmd;
305extern __attribute__ ((aligned(16)))unsigned int tx_command[2112];
306int tt = 0;
307unsigned int SPINAND_CacheRead_4Bytes(unsigned int Offset, unsigned int Buffer, unsigned int Size)
308{
309 unsigned int command, dummy, start_time, i, Retval = NoError;
310 SN_ADDRESS_FIELD_T addr;
311 DMA_CMDx_T RX_data, TX_cmd;
312
313 unsigned int * buff = (unsigned int *) Buffer;
314
315 //fill out the "command" sequence: CMD + Column Address (CA) + dummy byte
316 addr.value = Offset;
317 command = SN_CACHE_READ << 24;
318 command |= (addr.fields.CA << 8); //(upper bits will be 0's for the 'wrap')
319 command |= 0xA5; //0xA5 is a dummy byte that easily seen on a scope
320 tx_command[0] = command;
321
322 //fill out commands
323 RX_data.value = 0;
324 RX_data.bits.IncTrgAddr = 1;
325 RX_data.bits.FlowSrc = 1;
326 RX_data.bits.Width = 3;
327 RX_data.bits.MaxBurstSize = 2;
328
329 TX_cmd.value = 0;
330 TX_cmd.bits.IncSrcAddr = 1;
331 TX_cmd.bits.FlowTrg = 1;
332 TX_cmd.bits.Width = 3;
333 TX_cmd.bits.MaxBurstSize = 2;
334
335 //Map Device to Channels
336 XllpDmacMapDeviceToChannel(spi_rx_dma, SSP_RX_CHANNEL);
337 XllpDmacMapDeviceToChannel(spi_tx_dma, SSP_TX_CHANNEL);
338
339 //turn ON user alignment - in case buffer address is 64bit aligned
340 alignChannel(SSP_RX_CHANNEL, 1);
341
342 // * configure RX & TX descriptors * //
343 configDescriptor(&pRX_data, NULL, (unsigned int)SSP_DR, (unsigned int)Buffer, &RX_data, Size, 1);
344 configDescriptor(&pTX_cmd,
345 NULL,
346 (unsigned int)&tx_command[0],
347 (unsigned int)SSP_DR,
348 &TX_cmd,
349 Size,
350 1);
351
352 //Load descriptors
353 loadDescriptor (&pRX_data, SSP_RX_CHANNEL);
354 loadDescriptor (&pTX_cmd, SSP_TX_CHANNEL);
355
356 SPI_DisableSSP();
357
358 //setup in 32 bit mode
359 reg_bit_set(SSP_CR0, SSP_CR0_DSS_32);
360 // workaround for 52MHz SPI bit shift
361 if (ssp_52mhz)
362 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
363 //setup for DMA: TX and RX DMA request + DMA handles Trailing bytes
364 reg_bit_set(SSP_CR1, SSP_SSCR1_TRAIL |
365 SSP_SSCR1_TSRE |
366 SSP_SSCR1_RSRE |
367 SSP_SSCR1_TINTE|
368 (3 << SSP_SSCR1_TFT_BASE) |
369 (4 << SSP_SSCR1_RFT_BASE));
370
371 reg_write(SSP_TO, 0x400);
372
373#if ENABLE_MMU
374 dcache_clean_range(&pRX_data, sizeof(XLLP_DMAC_DESCRIPTOR_T));
375 dcache_clean_range(&pTX_cmd, sizeof(XLLP_DMAC_DESCRIPTOR_T));
376 dcache_clean_range(&tx_command[0], sizeof(tx_command));
377 dcache_invalidate_range(Buffer, Size);
378#endif
379
380 //fire it up
381 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
382
383 Assert_CS();
384
385 BU_REG_WRITE(SSP_DR, tx_command[0]);
386 SPI_WaitSSPComplete();
387 BU_REG_READ(SSP_DR);
388
389 //Kick off DMA's
390 XllpDmacStartTransfer(SSP_TX_CHANNEL);
391 XllpDmacStartTransfer(SSP_RX_CHANNEL);
392
393 //wait until the RX channel gets the stop interrupt
394 while( (readDmaStatusRegister(SSP_RX_CHANNEL) & XLLP_DMAC_DCSR_STOP_INTR) != XLLP_DMAC_DCSR_STOP_INTR )
395 ROW_DELAY(DEFAULT_TIMEOUT);
396
397 while( (readDmaStatusRegister(SSP_TX_CHANNEL) & XLLP_DMAC_DCSR_STOP_INTR) != XLLP_DMAC_DCSR_STOP_INTR )
398 ROW_DELAY(DEFAULT_TIMEOUT);
399
400 SPI_WaitSSPComplete();
401
402 Deassert_CS();
403
404 SPI_DisableSSP();
405
406 //clear out DMA settings
407 XllpDmacUnMapDeviceToChannel(spi_rx_dma, SSP_RX_CHANNEL);
408 XllpDmacUnMapDeviceToChannel(spi_tx_dma, SSP_TX_CHANNEL);
409
410 //postprocessing... endian convert
411 Size >>= 2; //convert Size from bytes to words
412 for(i = 0; i < Size; i++)
413 buff[i] = Endian_Convert(buff[i]);
414
415 return Retval;
416}
417
418unsigned int SPINAND_CacheRead_1Byte(unsigned int Offset, unsigned int Buffer, unsigned int Size)
419{
420 unsigned int command, dummy, start_time, i, Retval = NoError;
421 SN_ADDRESS_FIELD_T addr;
422 DMA_CMDx_T RX_data, TX_cmd;
423 unsigned char cmd[4], data[4];
424
425 unsigned int * buff = (unsigned int *) Buffer;
426
427 //fill out the "command" sequence: CMD + Column Address (CA) + dummy byte
428 addr.value = Offset;
429
430 cmd[0] = SN_CACHE_READ;
431 cmd[1] = ((addr.fields.CA >> 8) & (~0xC0)) | 0x40;
432 cmd[2] = addr.fields.CA & 0xff;
433 cmd[3] = 0xFF;
434
435
436 //fill out commands
437 RX_data.value = 0;
438 RX_data.bits.IncTrgAddr = 1;
439 RX_data.bits.FlowSrc = 1;
440 RX_data.bits.Width = 1;
441 RX_data.bits.MaxBurstSize = 1;
442
443 TX_cmd.value = 0;
444 TX_cmd.bits.IncSrcAddr = 1;
445 TX_cmd.bits.FlowTrg = 1;
446 TX_cmd.bits.Width = 1;
447 TX_cmd.bits.MaxBurstSize = 1;
448
449 //Map Device to Channels
450 XllpDmacMapDeviceToChannel(spi_rx_dma, SSP_RX_CHANNEL);
451 XllpDmacMapDeviceToChannel(spi_tx_dma, SSP_TX_CHANNEL);
452
453 //turn ON user alignment - in case buffer address is 64bit aligned
454 alignChannel(SSP_RX_CHANNEL, 1);
455
456 // * configure RX & TX descriptors * //
457 configDescriptor(&pRX_data, NULL, (unsigned int)SSP_DR, (unsigned int)Buffer, &RX_data, Size, 1);
458 configDescriptor(&pTX_cmd,
459 NULL,
460 (unsigned int)&tx_command[0],
461 (unsigned int)SSP_DR,
462 &TX_cmd,
463 Size,
464 1);
465
466 //Load descriptors
467 loadDescriptor (&pRX_data, SSP_RX_CHANNEL);
468 loadDescriptor (&pTX_cmd, SSP_TX_CHANNEL);
469
470 SPI_DisableSSP();
471
472 // workaround for 52MHz SPI bit shift
473 if (ssp_52mhz)
474 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
475 //setup for DMA: TX and RX DMA request + DMA handles Trailing bytes
476 reg_bit_set(SSP_CR1, SSP_SSCR1_TRAIL |
477 SSP_SSCR1_TSRE |
478 SSP_SSCR1_RSRE |
479 SSP_SSCR1_TINTE|
480 (8 << SSP_SSCR1_TFT_BASE) |
481 (3 << SSP_SSCR1_RFT_BASE));
482
483 reg_write(SSP_TO, 0xffff);
484
485 //fire it up
486 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
487
488 Assert_CS();
489
490 SPI_Write_Read(cmd, data, sizeof(cmd));
491
492 //Kick off DMA's
493 XllpDmacStartTransfer(SSP_TX_CHANNEL);
494 XllpDmacStartTransfer(SSP_RX_CHANNEL);
495
496 //wait until the RX channel gets the stop interrupt
497 while( (readDmaStatusRegister(SSP_RX_CHANNEL) & XLLP_DMAC_DCSR_STOP_INTR) != XLLP_DMAC_DCSR_STOP_INTR )
498 ROW_DELAY(DEFAULT_TIMEOUT);
499
500 while( (readDmaStatusRegister(SSP_TX_CHANNEL) & XLLP_DMAC_DCSR_STOP_INTR) != XLLP_DMAC_DCSR_STOP_INTR )
501 ROW_DELAY(DEFAULT_TIMEOUT);
502
503 SPI_WaitSSPComplete();
504
505 Deassert_CS();
506
507 SPI_DisableSSP();
508
509 //clear out DMA settings
510 XllpDmacUnMapDeviceToChannel(spi_rx_dma, SSP_RX_CHANNEL);
511 XllpDmacUnMapDeviceToChannel(spi_tx_dma, SSP_TX_CHANNEL);
512
513 //postprocessing... endian convert
514 //Size >>= 2; //convert Size from bytes to words
515 //for(i = 0; i < Size; i++)
516 // buff[i] = Endian_Convert(buff[i]);
517
518 return Retval;
519}
520
521
522// SPI NAND WRITE: using DMA
523unsigned int SPINAND_Write(unsigned int FlashOffset, unsigned int Buffer, unsigned int Size)
524{
525 unsigned int retval = NoError, write_size;
526
527 //calculate the initial write size (for the first page)
528 //write_size = SN_PAGE_SIZE - (FlashOffset & (SN_PAGE_SIZE - 1)); //whole page - pre_bytes
529
530 //for each loop iteration, one page of flash will be written
531 while (Size > 0)
532 { //update write_size if there are post_bytes (i.e. leftover for the last page)
533 write_size = Size > SN_PAGE_SIZE ? SN_PAGE_SIZE : Size;
534
535 /** Step 1: Program Load: Load the data into cache (DMA) **/
536 retval = SPINAND_ProgramLoad_4Bytes(FlashOffset, Buffer, write_size);
537 if(retval != NoError)
538 break;
539
540 retval = SPINAND_CheckReady();
541 if(retval != NoError)
542 break;
543
544 /** Step 2: Write Enable: set the write enable bit **/
545 SPINAND_WriteEnable();
546
547 /** Step 3: Program Execute: Write the page in cache to flash **/
548 SPINAND_ProgramExecute(FlashOffset);
549
550 /** Step 4: Get Features: wait for OIP to be cleared **/
551 retval = SPINAND_CheckReady();
552 if(retval != NoError)
553 break;
554
555 /** Step 5: Update counters: make sure to adjust up to a page boundary each iteration **/
556 FlashOffset += write_size;
557 Buffer += write_size;
558 Size -= write_size;
559 write_size = SN_PAGE_SIZE;
560 }
561
562 return retval;
563}
564
565unsigned int SPINAND_ProgramLoad_4Bytes(unsigned int Address, unsigned int Buffer, unsigned int Size)
566{
567 unsigned int Retval = NoError, i;
568 DMA_CMDx_T TX_data;
569 unsigned char cmd[3], data[3];
570 unsigned int convert_size = Size;
571
572 unsigned int * convert_buff = (unsigned int *) DDR_SPI_CONVERT_ADDR;
573 unsigned int * orginal_buff = (unsigned int *) Buffer;
574
575 //postprocessing... endian convert
576 convert_size >>= 2; //convert Size from bytes to words
577 for(i = 0; i < convert_size; i++)
578 convert_buff[i] = Endian_Convert(orginal_buff[i]);
579
580 //#if ENABLE_MMU
581 //dcache_invalidate_range(convert_buff, Size);
582 //#endif
583
584 cmd[0] = SN_PROGRAM_LOAD;
585 cmd[1] = 0;
586 cmd[2] = 0;
587
588 TX_data.value = 0;
589 TX_data.bits.IncSrcAddr = 1;
590 TX_data.bits.FlowTrg = 1;
591 TX_data.bits.Width = 3;
592 TX_data.bits.MaxBurstSize = 2;
593 TX_data.bits.Length = Size;
594
595 //Map Device to Channels
596 XllpDmacMapDeviceToChannel(spi_tx_dma, SSP_TX_CHANNEL);
597 XllpDmacNoDescriptorFetch( SSP_TX_CHANNEL );
598
599 //turn ON user alignment - in case buffer address is 64bit aligned
600 alignChannel(SSP_TX_CHANNEL, 1);
601
602 loadNonDescriptor((unsigned int)convert_buff, (unsigned int) SSP_DR, &TX_data, SSP_TX_CHANNEL);
603
604 SPI_DisableSSP();
605
606 // workaround for 52MHz SPI bit shift
607 if (ssp_52mhz)
608 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
609 //setup for DMA: TX and RX DMA request
610 reg_bit_set(SSP_CR1, SSP_SSCR1_TRAIL |
611 SSP_SSCR1_TSRE |
612 SSP_SSCR1_RSRE |
613 SSP_SSCR1_TINTE|
614 (3 << SSP_SSCR1_TFT_BASE) |
615 (4 << SSP_SSCR1_RFT_BASE));
616
617 reg_write(SSP_TO, 0x400);
618
619 //fire it up
620 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
621
622 Assert_CS();
623
624 SPI_Write_Read(cmd, data, sizeof(cmd));
625
626 SPI_DisableSSP();
627
628 //setup in 32 bit mode
629 reg_bit_set(SSP_CR0, SSP_CR0_DSS_32);
630
631 // workaround for 52MHz SPI bit shift
632 if (ssp_52mhz)
633 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
634 //setup for DMA: TX and RX DMA request
635 reg_bit_set(SSP_CR1, SSP_SSCR1_TRAIL |
636 SSP_SSCR1_TSRE |
637 SSP_SSCR1_RSRE |
638 SSP_SSCR1_TINTE|
639 (3 << SSP_SSCR1_TFT_BASE) |
640 (4 << SSP_SSCR1_RFT_BASE));
641
642 reg_write(SSP_TO, 0x400);
643
644 //fire it up
645 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
646
647 //Kick off DMA's
648 XllpDmacStartTransfer(SSP_TX_CHANNEL);
649
650 //wait until the RX channel gets the stop interrupt
651 while( (readDmaStatusRegister(SSP_TX_CHANNEL) & XLLP_DMAC_DCSR_STOP_INTR) != XLLP_DMAC_DCSR_STOP_INTR )
652 ROW_DELAY(DEFAULT_TIMEOUT);
653
654 SPI_WaitSSPComplete();
655
656 Deassert_CS();
657
658 SPI_DisableSSP();
659
660 //clear out DMA settings
661 XllpDmacUnMapDeviceToChannel(spi_tx_dma, SSP_TX_CHANNEL);
662
663 return Retval;
664
665}
666
667/***********************************************************
668* SPINAND_ProgramLoad
669* Writes a page of data to Cache from internal memory using DMA
670* Inputs:
671* Offset into page
672* Buffer location
673* Size to be write
674* Returns:
675* error status
676*************************************************************/
677unsigned int SPINAND_ProgramLoad_1Byte(unsigned int Address, unsigned int Buffer, unsigned int Size)
678{
679 unsigned int dummy, start_time, Retval = NoError;
680 DMA_CMDx_T TX_data;
681 unsigned char cmd[3], data[3];
682
683 cmd[0] = SN_PROGRAM_LOAD;
684 cmd[1] = 0;
685 cmd[2] = 0;
686
687 TX_data.value = 0;
688 TX_data.bits.IncSrcAddr = 1;
689 TX_data.bits.FlowTrg = 1;
690 TX_data.bits.Width = 1;
691 TX_data.bits.MaxBurstSize = 1;
692 TX_data.bits.Length = Size;
693
694 //Map Device to Channels
695 XllpDmacMapDeviceToChannel(spi_tx_dma, SSP_TX_CHANNEL);
696 XllpDmacNoDescriptorFetch( SSP_TX_CHANNEL );
697
698 //turn ON user alignment - in case buffer address is 64bit aligned
699 alignChannel(SSP_TX_CHANNEL, 1);
700
701 loadNonDescriptor((unsigned int)Buffer, (unsigned int) SSP_DR, &TX_data, SSP_TX_CHANNEL);
702
703 SPI_DisableSSP();
704
705 // workaround for 52MHz SPI bit shift
706 if (ssp_52mhz)
707 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
708 //setup for DMA: TX and RX DMA request
709 reg_bit_set(SSP_CR1, SSP_SSCR1_TRAIL |
710 SSP_SSCR1_TSRE |
711 SSP_SSCR1_RSRE |
712 (8 << SSP_SSCR1_TFT_BASE) |
713 (3 << SSP_SSCR1_RFT_BASE));
714
715 //reg_write(SSP_TO, 0xfff);
716
717 //fire it up
718 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
719
720 Assert_CS();
721
722 SPI_Write_Read(cmd, data, sizeof(cmd));
723
724 //Kick off DMA's
725 XllpDmacStartTransfer(SSP_TX_CHANNEL);
726
727 //wait until the RX channel gets the stop interrupt
728 while( (readDmaStatusRegister(SSP_TX_CHANNEL) & XLLP_DMAC_DCSR_STOP_INTR) != XLLP_DMAC_DCSR_STOP_INTR )
729 ROW_DELAY(DEFAULT_TIMEOUT);
730
731 SPI_WaitSSPComplete();
732
733 Deassert_CS();
734
735 SPI_DisableSSP();
736
737 //clear out DMA settings
738 XllpDmacUnMapDeviceToChannel(spi_tx_dma, SSP_TX_CHANNEL);
739
740 return Retval;
741
742}
743
744/***********************************************************
745* SPINAND_WriteEnable
746* Sets the WEL bit in the SPI NAND status register,
747* allowing the device to be programmed or erased
748* Returns:
749* none
750*************************************************************/
751void SPINAND_WriteEnable(void)
752{
753 unsigned char cmd[1], data[1];
754
755 cmd[0] = SN_WRITE_ENABLE;
756
757 SPI_DisableSSP();
758
759 // workaround for 52MHz SPI bit shift
760 if (ssp_52mhz)
761 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
762 //fire it up
763 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
764
765 Assert_CS();
766
767 SPI_Write_Read(cmd, data, sizeof(cmd));
768
769 Deassert_CS();
770
771 SPI_DisableSSP();
772}
773
774/***********************************************************
775* SPINAND_ProgramExecute
776* Issues command to program a page of NAND from the cache
777* Inputs:
778* The flash address of the page to be loaded
779* Returns:
780* no returns
781*************************************************************/
782void SPINAND_ProgramExecute(unsigned int Address)
783{
784 unsigned char cmd[4], data[4];
785
786 cmd[0] = SN_PROGRAM_EXECUTE;
787 cmd[1] = ((Address>>11)&0xffff) >> 16;
788 cmd[2] = ((Address>>11)&0xffff) >> 8;
789 cmd[3] = ((Address>>11)&0xffff);
790
791 SPI_DisableSSP();
792
793 // workaround for 52MHz SPI bit shift
794 if (ssp_52mhz)
795 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
796 //fire it up
797 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
798
799 Assert_CS();
800
801 SPI_Write_Read(cmd, data, sizeof(cmd));
802
803 Deassert_CS();
804
805 SPI_DisableSSP();
806
807 return;
808}
809
810// SPI NAND ERASE: Erases 1 whole block at a time
811unsigned int SPINAND_Erase(unsigned int FlashOffset, unsigned int Size)
812{
813 unsigned int retval = NoError;
814
815 //adjust the size/offset fields to start on a block boundary
816 Size += FlashOffset & (SN_BLOCK_SIZE - 1);
817 FlashOffset &= ~(SN_BLOCK_SIZE - 1);
818
819 //for each loop iteration, one block of flash will be erased
820 while (Size > 0)
821 { /** Step 1: Write Enable: set the write enable bit **/
822 SPINAND_WriteEnable();
823
824 /** Step 2: Block Erase: erase 1 block **/
825 SPINAND_BlockErase(FlashOffset);
826
827 /** Step 3: Get Features: wait for OIP to be cleared **/
828 retval = SPINAND_CheckReady();
829 if(retval != NoError)
830 break;
831
832
833 /** Step 4: Update counters **/
834 FlashOffset += SN_BLOCK_SIZE;
835 Size = (Size > SN_BLOCK_SIZE) ? (Size - SN_BLOCK_SIZE) : 0;
836 }
837
838 return retval;
839
840}
841
842/***********************************************************
843* SPINAND_BlockErase
844* Issues command to erase 1 block of flash
845* Inputs:
846* The flash address of the block to be erased
847* Returns:
848* no returns
849*************************************************************/
850void SPINAND_BlockErase(unsigned int Address)
851{
852 unsigned char cmd[4], data[4];
853
854 cmd[0] = SN_BLOCK_ERASE;
855 cmd[1] = ((Address>>11)&0xffff) >> 16;
856 cmd[2] = ((Address>>11)&0xffff) >> 8;
857 cmd[3] = ((Address>>11)&0xffff);
858
859 SPI_DisableSSP();
860
861 // workaround for 52MHz SPI bit shift
862 if (ssp_52mhz)
863 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
864 //fire it up
865 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
866
867 Assert_CS();
868
869 SPI_Write_Read(cmd, data, sizeof(cmd));
870
871 Deassert_CS();
872
873 SPI_DisableSSP();
874
875 return;
876}
877
878/***********************************************************
879* SPINAND_Reset
880* Issues command to reset flash
881* Inputs:
882* The flash boot type
883* Returns:
884* no error
885*************************************************************/
886unsigned int SPINAND_Reset(FlashBootType_T fbt)
887{
888 unsigned char cmd[1], data[1];
889
890 cmd[0] = SN_RESET;
891
892 SPI_DisableSSP();
893
894 // workaround for 52MHz SPI bit shift
895 if (ssp_52mhz)
896 reg_bit_set(SSP_CR0, SSP_SSCR0_52MM);
897 //fire it up
898 reg_bit_set(SSP_CR0, SSP_CR0_SSE);
899
900 Assert_CS();
901
902 SPI_Write_Read(cmd, data, sizeof(cmd));
903
904 Deassert_CS();
905
906 SPI_DisableSSP();
907
908 return NoError;
909}
910
911/***********************************************************
912* SPINAND_UnProtectBlocks
913* unprotect the protected flash blocks
914* Inputs:
915* none
916* Returns:
917* none
918*************************************************************/
919void SPINAND_UnProtectBlocks(void)
920{
921 unsigned char protection;
922
923 protection = SPINAND_GetFeatures(SN_PROTECTION);
924 obm_printf("SN_PROTECTION: 0x%x\n\r", protection);
925
926 if ((protection & (GIGA_SPINAND_PROTECTION_BP2 |
927 GIGA_SPINAND_PROTECTION_BP1 |
928 GIGA_SPINAND_PROTECTION_BP0)) == 0)
929 {
930 obm_printf("Giga SPINAND is already unprotected\n\r");
931 return;
932 }
933 else
934 {
935 obm_printf("Giga SPINAND is not unprotected\n\r");
936 }
937
938 // clear BP0/BP1/BP2
939 protection &= ~(GIGA_SPINAND_PROTECTION_BP2 |
940 GIGA_SPINAND_PROTECTION_BP1 |
941 GIGA_SPINAND_PROTECTION_BP0);
942
943 SPINAND_SetFeatures(SN_PROTECTION, protection);
944
945 obm_printf("Giga SPINAND unprotect done\n\r");
946}
947
948UINT_T SPINAND_CheckReady(void)
949{
950 unsigned int start_time, retval = NoError;
951 unsigned char status;
952
953 start_time = GetOSCR0();
954 do
955 { //Read the Status register on the device
956 status = SPINAND_GetFeatures(SN_STATUS);
957
958 //Check for timeout
959 if( OSCR0IntervalInMilli(start_time, GetOSCR0()) > 5 )
960 retval = SPINANDCheckReadyTimeOutError;
961
962 if (status & GIGA_SPINAND_STATUS_P_FAIL)
963 retval = SPI_PROGRAMFAIL;
964
965 if (status & GIGA_SPINAND_STATUS_E_FAIL)
966 retval = SPI_ERASEFAIL;
967
968 //stay in loop if OIP bit is still high AND no timeout error has occured
969 } while( (status & GIGA_SPINAND_STATUS_OIP) && (retval == NoError) );
970
971 return retval;
972}
973
974