File indexing completed on 2025-05-11 08:24:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "xqspipsu_flash_config.h"
0016 #include "xqspipsu-flash-helper.h"
0017
0018 #include <rtems.h>
0019 #include <string.h>
0020
0021
0022
0023
0024 #define PAGE_COUNT 32
0025
0026
0027
0028
0029 #define MAX_PAGE_SIZE 1024
0030
0031 #define TEST_ADDRESS 0x000000
0032
0033 #define XQSPI_FLASH_MAX_READ_SIZE ((size_t)0x8000)
0034
0035 #define ENTER_4B 1
0036 #define EXIT_4B 0
0037
0038 #define NOR_TIMEOUT_US 5000000U
0039 #define NOR_TIMEOUT_TICKS (NOR_TIMEOUT_US / rtems_configuration_get_microseconds_per_tick())
0040
0041 u8 ReadCmd;
0042 u8 WriteCmd;
0043 u8 StatusCmd;
0044 u8 SectorEraseCmd;
0045 u8 FSRFlag;
0046
0047 static int FlashReadID(XQspiPsu *QspiPsuPtr);
0048
0049 static int MultiDieRead(
0050 XQspiPsu *QspiPsuPtr,
0051 u32 Address,
0052 u32 ByteCount,
0053 u8 Command,
0054 u8 *WriteBfrPtr,
0055 u8 *ReadBfrPtr
0056 );
0057
0058 static u32 GetRealAddr(
0059 XQspiPsu *QspiPsuPtr,
0060 u32 Address
0061 );
0062
0063 static int BulkErase(
0064 XQspiPsu *QspiPsuPtr,
0065 u8 *WriteBfrPtr
0066 );
0067
0068 static int DieErase(
0069 XQspiPsu *QspiPsuPtr,
0070 u8 *WriteBfrPtr
0071 );
0072
0073 static int QspiPsuSetupIntrSystem(
0074 XQspiPsu *QspiPsuInstancePtr,
0075 u16 QspiPsuIntrId
0076 );
0077
0078 static void QspiPsuHandler(
0079 void *CallBackRef,
0080 u32 StatusEvent,
0081 unsigned int ByteCount
0082 );
0083
0084 static int FlashEnterExit4BAddMode(
0085 XQspiPsu *QspiPsuPtr,
0086 unsigned int Enable
0087 );
0088
0089 static int FlashEnableQuadMode(XQspiPsu *QspiPsuPtr);
0090
0091 u8 TxBfrPtr;
0092 u8 ReadBfrPtr[3];
0093 u32 FlashMake;
0094 u32 FCTIndex;
0095
0096 static XQspiPsu_Msg FlashMsg[5];
0097
0098
0099
0100
0101
0102 rtems_id TransferTask;
0103
0104 static s32 transfer_and_wait(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, u32 NumMsg)
0105 {
0106 rtems_status_code sc;
0107 TransferTask = rtems_task_self();
0108 s32 Status = XQspiPsu_InterruptTransfer(InstancePtr, Msg, NumMsg);
0109 if (Status != XST_SUCCESS) {
0110 return Status;
0111 }
0112
0113 sc = rtems_event_transient_receive(RTEMS_WAIT, NOR_TIMEOUT_TICKS);
0114 if (sc != RTEMS_SUCCESSFUL) {
0115 rtems_event_transient_clear();
0116 XQspiPsu_Abort(InstancePtr);
0117 return XST_FAILURE;
0118 }
0119
0120 return XST_SUCCESS;
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130 #ifdef __ICCARM__
0131 #pragma data_alignment = 32
0132 u8 ReadBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + (DATA_OFFSET + DUMMY_SIZE)*8];
0133 #else
0134 u8 ReadBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + (DATA_OFFSET + DUMMY_SIZE)*8] __attribute__ ((aligned(64)));
0135 #endif
0136 u8 WriteBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + DATA_OFFSET];
0137 u8 CmdBfr[8];
0138
0139
0140
0141
0142
0143
0144 u32 MaxData = PAGE_COUNT*256;
0145
0146 int QspiPsu_NOR_Initialize(
0147 XQspiPsu *QspiPsuInstancePtr,
0148 u16 QspiPsuIntrId
0149 )
0150 {
0151 int Status;
0152
0153 if (QspiPsuInstancePtr == NULL) {
0154 return XST_FAILURE;
0155 }
0156
0157
0158
0159
0160
0161 Status = QspiPsuSetupIntrSystem(QspiPsuInstancePtr, QspiPsuIntrId);
0162 if (Status != XST_SUCCESS) {
0163 return XST_FAILURE;
0164 }
0165
0166
0167
0168
0169
0170
0171
0172 XQspiPsu_SetStatusHandler(QspiPsuInstancePtr, QspiPsuInstancePtr,
0173 (XQspiPsu_StatusHandler) QspiPsuHandler);
0174
0175
0176
0177
0178 XQspiPsu_SetOptions(QspiPsuInstancePtr, XQSPIPSU_MANUAL_START_OPTION);
0179
0180
0181
0182
0183 XQspiPsu_SetClkPrescaler(QspiPsuInstancePtr, XQSPIPSU_CLK_PRESCALE_8);
0184
0185 XQspiPsu_SelectFlash(QspiPsuInstancePtr,
0186 XQSPIPSU_SELECT_FLASH_CS_LOWER,
0187 XQSPIPSU_SELECT_FLASH_BUS_LOWER);
0188
0189
0190
0191
0192
0193
0194
0195
0196 Status = FlashReadID(QspiPsuInstancePtr);
0197 if (Status != XST_SUCCESS) {
0198 return XST_FAILURE;
0199 }
0200
0201
0202
0203
0204
0205 Status = FlashEnableQuadMode(QspiPsuInstancePtr);
0206 if (Status != XST_SUCCESS)
0207 return XST_FAILURE;
0208
0209
0210
0211
0212
0213 if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_SINGLE)
0214 ReadCmd = FAST_READ_CMD;
0215 else if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_DOUBLE)
0216 ReadCmd = DUAL_READ_CMD;
0217 else
0218 ReadCmd = QUAD_READ_CMD;
0219
0220 WriteCmd = WRITE_CMD;
0221 SectorEraseCmd = SEC_ERASE_CMD;
0222
0223 if ((Flash_Config_Table[FCTIndex].NumDie > 1) &&
0224 (FlashMake == MICRON_ID_BYTE0)) {
0225 StatusCmd = READ_FLAG_STATUS_CMD;
0226 FSRFlag = 1;
0227 } else {
0228 StatusCmd = READ_STATUS_CMD;
0229 FSRFlag = 0;
0230 }
0231
0232 if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
0233 Status = FlashEnterExit4BAddMode(QspiPsuInstancePtr, ENTER_4B);
0234 if (Status != XST_SUCCESS) {
0235 return XST_FAILURE;
0236 }
0237 if (FlashMake == SPANSION_ID_BYTE0) {
0238 if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_SINGLE)
0239 ReadCmd = FAST_READ_CMD_4B;
0240 else if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_DOUBLE)
0241 ReadCmd = DUAL_READ_CMD_4B;
0242 else
0243 ReadCmd = QUAD_READ_CMD_4B;
0244
0245 WriteCmd = WRITE_CMD_4B;
0246 SectorEraseCmd = SEC_ERASE_CMD_4B;
0247 }
0248 }
0249
0250 return XST_SUCCESS;
0251 }
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 static void QspiPsuHandler(
0270 void *CallBackRef,
0271 u32 StatusEvent,
0272 unsigned int ByteCount
0273 )
0274 {
0275
0276 if (StatusEvent == XST_SPI_TRANSFER_DONE) {
0277 (void) rtems_event_transient_send(TransferTask);
0278 }
0279 }
0280
0281 int QspiPsu_NOR_RDSFDP(
0282 XQspiPsu *QspiPsuPtr,
0283 u32 Address,
0284 u32 ByteCount,
0285 u8 **ReadBfrPtr
0286 )
0287 {
0288 int Status;
0289
0290 *ReadBfrPtr = ReadBuffer;
0291
0292 CmdBfr[COMMAND_OFFSET] = READ_SFDP;
0293 CmdBfr[ADDRESS_1_OFFSET] =
0294 (u8)((Address & 0xFF0000) >> 16);
0295 CmdBfr[ADDRESS_2_OFFSET] =
0296 (u8)((Address & 0xFF00) >> 8);
0297 CmdBfr[ADDRESS_3_OFFSET] =
0298 (u8)(Address & 0xFF);
0299
0300 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0301 FlashMsg[0].TxBfrPtr = CmdBfr;
0302 FlashMsg[0].RxBfrPtr = NULL;
0303 FlashMsg[0].ByteCount = 4;
0304 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0305
0306 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0307 FlashMsg[1].TxBfrPtr = NULL;
0308 FlashMsg[1].RxBfrPtr = NULL;
0309 FlashMsg[1].ByteCount = DUMMY_CLOCKS;
0310 FlashMsg[1].Flags = 0;
0311
0312 FlashMsg[2].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0313 FlashMsg[2].TxBfrPtr = NULL;
0314 FlashMsg[2].RxBfrPtr = *ReadBfrPtr;
0315 FlashMsg[2].ByteCount = ByteCount;
0316 FlashMsg[2].Flags = XQSPIPSU_MSG_FLAG_RX;
0317
0318 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 3);
0319 if (Status != XST_SUCCESS)
0320 return XST_FAILURE;
0321
0322 rtems_cache_invalidate_multiple_data_lines(ReadBuffer, ByteCount);
0323 return 0;
0324 }
0325
0326 int QspiPsu_NOR_RDID(XQspiPsu *QspiPsuPtr, u8 *ReadBfrPtr, u32 ReadLen)
0327 {
0328 int Status;
0329
0330
0331
0332
0333 TxBfrPtr = READ_ID;
0334 FlashMsg[0].TxBfrPtr = &TxBfrPtr;
0335 FlashMsg[0].RxBfrPtr = NULL;
0336 FlashMsg[0].ByteCount = 1;
0337 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0338 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0339
0340 FlashMsg[1].TxBfrPtr = NULL;
0341 FlashMsg[1].RxBfrPtr = ReadBfrPtr;
0342 FlashMsg[1].ByteCount = ReadLen;
0343 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0344 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
0345
0346 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
0347 if (Status != XST_SUCCESS) {
0348 return XST_FAILURE;
0349 }
0350
0351 rtems_cache_invalidate_multiple_data_lines(ReadBfrPtr, ReadLen);
0352 return XST_SUCCESS;
0353 }
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 static int FlashReadID(XQspiPsu *QspiPsuPtr)
0368 {
0369 u32 ReadId = 0;
0370 u32 ReadLen = 3;
0371 int Status;
0372
0373 Status = QspiPsu_NOR_RDID(QspiPsuPtr, ReadBfrPtr, ReadLen);
0374 if (Status != XST_SUCCESS) {
0375 return XST_FAILURE;
0376 }
0377
0378
0379
0380
0381
0382
0383 FlashMake = ReadBfrPtr[0];
0384
0385 ReadId = ((ReadBfrPtr[0] << 16) | (ReadBfrPtr[1] << 8) | ReadBfrPtr[2]);
0386
0387
0388
0389 Status = CalculateFCTIndex(ReadId, &FCTIndex);
0390 if (Status != XST_SUCCESS) {
0391 return XST_FAILURE;
0392 }
0393
0394 return XST_SUCCESS;
0395 }
0396
0397 int QspiPsu_NOR_Write_Page(
0398 XQspiPsu *QspiPsuPtr,
0399 u32 Address,
0400 u32 ByteCount,
0401 u8 *WriteBfrPtr
0402 )
0403 {
0404 u8 WriteEnableCmd;
0405 u8 ReadStatusCmd;
0406 u8 FlashStatus[2];
0407 u8 WriteCmdBfr[5];
0408 u32 RealAddr;
0409 u32 CmdByteCount;
0410 int Status;
0411
0412 WriteEnableCmd = WRITE_ENABLE_CMD;
0413
0414
0415
0416
0417 RealAddr = GetRealAddr(QspiPsuPtr, Address);
0418
0419
0420
0421
0422
0423
0424 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
0425 FlashMsg[0].RxBfrPtr = NULL;
0426 FlashMsg[0].ByteCount = 1;
0427 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0428 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0429
0430 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
0431 if (Status != XST_SUCCESS) {
0432 return XST_FAILURE;
0433 }
0434
0435 WriteCmdBfr[COMMAND_OFFSET] = WriteCmd;
0436
0437
0438 if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
0439 WriteCmdBfr[ADDRESS_1_OFFSET] =
0440 (u8)((RealAddr & 0xFF000000) >> 24);
0441 WriteCmdBfr[ADDRESS_2_OFFSET] =
0442 (u8)((RealAddr & 0xFF0000) >> 16);
0443 WriteCmdBfr[ADDRESS_3_OFFSET] =
0444 (u8)((RealAddr & 0xFF00) >> 8);
0445 WriteCmdBfr[ADDRESS_4_OFFSET] =
0446 (u8)(RealAddr & 0xFF);
0447 CmdByteCount = 5;
0448 } else {
0449 WriteCmdBfr[ADDRESS_1_OFFSET] =
0450 (u8)((RealAddr & 0xFF0000) >> 16);
0451 WriteCmdBfr[ADDRESS_2_OFFSET] =
0452 (u8)((RealAddr & 0xFF00) >> 8);
0453 WriteCmdBfr[ADDRESS_3_OFFSET] =
0454 (u8)(RealAddr & 0xFF);
0455 CmdByteCount = 4;
0456 }
0457
0458 FlashMsg[0].TxBfrPtr = WriteCmdBfr;
0459 FlashMsg[0].RxBfrPtr = NULL;
0460 FlashMsg[0].ByteCount = CmdByteCount;
0461 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0462 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0463
0464 FlashMsg[1].TxBfrPtr = WriteBfrPtr;
0465 FlashMsg[1].RxBfrPtr = NULL;
0466 FlashMsg[1].ByteCount = ByteCount;
0467 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0468 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
0469 if (QspiPsuPtr->Config.ConnectionMode ==
0470 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
0471 FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
0472 }
0473
0474 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
0475 if (Status != XST_SUCCESS) {
0476 return XST_FAILURE;
0477 }
0478
0479
0480
0481
0482
0483 while (1) {
0484 ReadStatusCmd = StatusCmd;
0485 FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
0486 FlashMsg[0].RxBfrPtr = NULL;
0487 FlashMsg[0].ByteCount = 1;
0488 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0489 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0490
0491 FlashMsg[1].TxBfrPtr = NULL;
0492 FlashMsg[1].RxBfrPtr = FlashStatus;
0493 FlashMsg[1].ByteCount = 2;
0494 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0495 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
0496 if (QspiPsuPtr->Config.ConnectionMode ==
0497 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
0498 FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
0499 }
0500
0501 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
0502 if (Status != XST_SUCCESS) {
0503 return XST_FAILURE;
0504 }
0505
0506 if (QspiPsuPtr->Config.ConnectionMode ==
0507 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
0508 if (FSRFlag) {
0509 FlashStatus[1] &= FlashStatus[0];
0510 } else {
0511 FlashStatus[1] |= FlashStatus[0];
0512 }
0513 }
0514
0515 if (FSRFlag) {
0516 if ((FlashStatus[1] & 0x80) != 0) {
0517 break;
0518 }
0519 } else {
0520 if ((FlashStatus[1] & 0x01) == 0) {
0521 break;
0522 }
0523 }
0524 }
0525
0526 return 0;
0527 }
0528
0529 int QspiPsu_NOR_Write(
0530 XQspiPsu *QspiPsuPtr,
0531 u32 Address,
0532 u32 ByteCount,
0533 u8 *WriteBfrPtr
0534 )
0535 {
0536 int Status;
0537 size_t ByteCountRemaining = ByteCount;
0538 unsigned char *WriteBfrPartial = WriteBfrPtr;
0539 uint32_t AddressPartial = Address;
0540 uint32_t PageSize = Flash_Config_Table[FCTIndex].PageSize;
0541 if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
0542 PageSize *= 2;
0543 }
0544
0545 while (ByteCountRemaining > 0) {
0546
0547 size_t WriteChunkLen = RTEMS_ALIGN_UP(AddressPartial + 1, PageSize);
0548
0549
0550 WriteChunkLen -= (size_t)AddressPartial;
0551
0552
0553 if (WriteChunkLen > ByteCountRemaining) {
0554 WriteChunkLen = ByteCountRemaining;
0555 }
0556
0557 Status = QspiPsu_NOR_Write_Page(
0558 QspiPsuPtr,
0559 AddressPartial,
0560 WriteChunkLen,
0561 WriteBfrPartial
0562 );
0563 if ( Status != XST_SUCCESS ) {
0564 return Status;
0565 }
0566
0567 ByteCountRemaining -= WriteChunkLen;
0568 AddressPartial += WriteChunkLen;
0569 WriteBfrPartial += WriteChunkLen;
0570 }
0571 return Status;
0572 }
0573
0574 int QspiPsu_NOR_Erase(
0575 XQspiPsu *QspiPsuPtr,
0576 u32 Address,
0577 u32 ByteCount
0578 )
0579 {
0580 u8 WriteEnableCmd;
0581 u8 ReadStatusCmd;
0582 u8 FlashStatus[2];
0583 int Sector;
0584 u32 RealAddr;
0585 u32 NumSect;
0586 int Status;
0587 u32 SectSize;
0588
0589 WriteEnableCmd = WRITE_ENABLE_CMD;
0590
0591 if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
0592 SectSize = (Flash_Config_Table[FCTIndex]).SectSize * 2;
0593 NumSect = (Flash_Config_Table[FCTIndex]).NumSect;
0594 } else if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) {
0595 NumSect = (Flash_Config_Table[FCTIndex]).NumSect * 2;
0596 SectSize = (Flash_Config_Table[FCTIndex]).SectSize;
0597 } else {
0598 SectSize = (Flash_Config_Table[FCTIndex]).SectSize;
0599 NumSect = (Flash_Config_Table[FCTIndex]).NumSect;
0600 }
0601
0602
0603
0604
0605
0606 if (ByteCount == NumSect * SectSize) {
0607
0608 if (QspiPsuPtr->Config.ConnectionMode ==
0609 XQSPIPSU_CONNECTION_MODE_STACKED) {
0610 XQspiPsu_SelectFlash(QspiPsuPtr,
0611 XQSPIPSU_SELECT_FLASH_CS_LOWER,
0612 XQSPIPSU_SELECT_FLASH_BUS_LOWER);
0613 }
0614
0615 if (Flash_Config_Table[FCTIndex].NumDie == 1) {
0616
0617
0618
0619 BulkErase(QspiPsuPtr, CmdBfr);
0620 }
0621
0622 if (Flash_Config_Table[FCTIndex].NumDie > 1) {
0623
0624
0625
0626 DieErase(QspiPsuPtr, CmdBfr);
0627 }
0628
0629
0630
0631 if (QspiPsuPtr->Config.ConnectionMode ==
0632 XQSPIPSU_CONNECTION_MODE_STACKED) {
0633
0634 XQspiPsu_SelectFlash(QspiPsuPtr,
0635 XQSPIPSU_SELECT_FLASH_CS_UPPER,
0636 XQSPIPSU_SELECT_FLASH_BUS_LOWER);
0637
0638 if (Flash_Config_Table[FCTIndex].NumDie == 1) {
0639
0640
0641
0642 BulkErase(QspiPsuPtr, CmdBfr);
0643 }
0644
0645 if (Flash_Config_Table[FCTIndex].NumDie > 1) {
0646
0647
0648
0649 DieErase(QspiPsuPtr, CmdBfr);
0650 }
0651 }
0652
0653 return 0;
0654 }
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 u32 SectorStartBase = RTEMS_ALIGN_DOWN(Address, SectSize);
0665 u32 SectorEndTop = RTEMS_ALIGN_UP(Address + ByteCount, SectSize);
0666 NumSect = (SectorEndTop - SectorStartBase)/SectSize;
0667
0668 for (Sector = 0; Sector < NumSect; Sector++) {
0669
0670
0671
0672
0673
0674 RealAddr = GetRealAddr(QspiPsuPtr, Address);
0675
0676
0677
0678
0679
0680
0681 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
0682 FlashMsg[0].RxBfrPtr = NULL;
0683 FlashMsg[0].ByteCount = 1;
0684 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0685 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0686
0687 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
0688 if (Status != XST_SUCCESS) {
0689 return XST_FAILURE;
0690 }
0691
0692 CmdBfr[COMMAND_OFFSET] = SectorEraseCmd;
0693
0694
0695
0696
0697
0698 if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
0699 CmdBfr[ADDRESS_1_OFFSET] =
0700 (u8)((RealAddr & 0xFF000000) >> 24);
0701 CmdBfr[ADDRESS_2_OFFSET] =
0702 (u8)((RealAddr & 0xFF0000) >> 16);
0703 CmdBfr[ADDRESS_3_OFFSET] =
0704 (u8)((RealAddr & 0xFF00) >> 8);
0705 CmdBfr[ADDRESS_4_OFFSET] =
0706 (u8)(RealAddr & 0xFF);
0707 FlashMsg[0].ByteCount = 5;
0708 } else {
0709 CmdBfr[ADDRESS_1_OFFSET] =
0710 (u8)((RealAddr & 0xFF0000) >> 16);
0711 CmdBfr[ADDRESS_2_OFFSET] =
0712 (u8)((RealAddr & 0xFF00) >> 8);
0713 CmdBfr[ADDRESS_3_OFFSET] =
0714 (u8)(RealAddr & 0xFF);
0715 FlashMsg[0].ByteCount = 4;
0716 }
0717
0718 FlashMsg[0].TxBfrPtr = CmdBfr;
0719 FlashMsg[0].RxBfrPtr = NULL;
0720 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0721 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0722
0723 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
0724 if (Status != XST_SUCCESS) {
0725 return XST_FAILURE;
0726 }
0727
0728
0729
0730
0731 while (1) {
0732 ReadStatusCmd = StatusCmd;
0733 FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
0734 FlashMsg[0].RxBfrPtr = NULL;
0735 FlashMsg[0].ByteCount = 1;
0736 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0737 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0738
0739 FlashMsg[1].TxBfrPtr = NULL;
0740 FlashMsg[1].RxBfrPtr = FlashStatus;
0741 FlashMsg[1].ByteCount = 2;
0742 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0743 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
0744 if (QspiPsuPtr->Config.ConnectionMode ==
0745 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
0746 FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
0747 }
0748
0749 Status = transfer_and_wait(QspiPsuPtr,
0750 FlashMsg, 2);
0751 if (Status != XST_SUCCESS) {
0752 return XST_FAILURE;
0753 }
0754
0755 if (QspiPsuPtr->Config.ConnectionMode ==
0756 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
0757 if (FSRFlag) {
0758 FlashStatus[1] &= FlashStatus[0];
0759 } else {
0760 FlashStatus[1] |= FlashStatus[0];
0761 }
0762 }
0763
0764 if (FSRFlag) {
0765 if ((FlashStatus[1] & 0x80) != 0) {
0766 break;
0767 }
0768 } else {
0769 if ((FlashStatus[1] & 0x01) == 0) {
0770 break;
0771 }
0772 }
0773 }
0774 Address += SectSize;
0775 }
0776
0777 return 0;
0778 }
0779
0780 int QspiPsu_NOR_Read_Page(
0781 XQspiPsu *QspiPsuPtr,
0782 u32 Address,
0783 u32 ByteCount,
0784 u8 **ReadBfrPtr
0785 )
0786 {
0787 u32 RealAddr;
0788 u32 DiscardByteCnt;
0789 u32 FlashMsgCnt;
0790 int Status;
0791
0792 *ReadBfrPtr = ReadBuffer;
0793
0794
0795 if (Flash_Config_Table[FCTIndex].NumDie > 1) {
0796
0797 Status = MultiDieRead(QspiPsuPtr, Address, ByteCount, ReadCmd,
0798 CmdBfr, *ReadBfrPtr);
0799 if (Status != XST_SUCCESS)
0800 return XST_FAILURE;
0801 } else {
0802
0803
0804
0805
0806
0807 RealAddr = GetRealAddr(QspiPsuPtr, Address);
0808
0809 CmdBfr[COMMAND_OFFSET] = ReadCmd;
0810 if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
0811 CmdBfr[ADDRESS_1_OFFSET] =
0812 (u8)((RealAddr & 0xFF000000) >> 24);
0813 CmdBfr[ADDRESS_2_OFFSET] =
0814 (u8)((RealAddr & 0xFF0000) >> 16);
0815 CmdBfr[ADDRESS_3_OFFSET] =
0816 (u8)((RealAddr & 0xFF00) >> 8);
0817 CmdBfr[ADDRESS_4_OFFSET] =
0818 (u8)(RealAddr & 0xFF);
0819 DiscardByteCnt = 5;
0820 } else {
0821 CmdBfr[ADDRESS_1_OFFSET] =
0822 (u8)((RealAddr & 0xFF0000) >> 16);
0823 CmdBfr[ADDRESS_2_OFFSET] =
0824 (u8)((RealAddr & 0xFF00) >> 8);
0825 CmdBfr[ADDRESS_3_OFFSET] =
0826 (u8)(RealAddr & 0xFF);
0827 DiscardByteCnt = 4;
0828 }
0829
0830 FlashMsg[0].TxBfrPtr = CmdBfr;
0831 FlashMsg[0].RxBfrPtr = NULL;
0832 FlashMsg[0].ByteCount = DiscardByteCnt;
0833 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0834 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
0835
0836 FlashMsgCnt = 1;
0837
0838
0839 if (ReadCmd == FAST_READ_CMD || ReadCmd == DUAL_READ_CMD ||
0840 ReadCmd == QUAD_READ_CMD || ReadCmd == FAST_READ_CMD_4B ||
0841 ReadCmd == DUAL_READ_CMD_4B ||
0842 ReadCmd == QUAD_READ_CMD_4B) {
0843
0844
0845
0846
0847
0848
0849 if (ReadCmd == FAST_READ_CMD ||
0850 ReadCmd == FAST_READ_CMD_4B) {
0851 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
0852 }
0853
0854 if (ReadCmd == DUAL_READ_CMD ||
0855 ReadCmd == DUAL_READ_CMD_4B) {
0856 FlashMsg[1].BusWidth =
0857 XQSPIPSU_SELECT_MODE_DUALSPI;
0858 }
0859
0860 if (ReadCmd == QUAD_READ_CMD ||
0861 ReadCmd == QUAD_READ_CMD_4B) {
0862 FlashMsg[1].BusWidth =
0863 XQSPIPSU_SELECT_MODE_QUADSPI;
0864 }
0865
0866 FlashMsg[1].TxBfrPtr = NULL;
0867 FlashMsg[1].RxBfrPtr = NULL;
0868 FlashMsg[1].ByteCount = DUMMY_CLOCKS;
0869 FlashMsg[1].Flags = 0;
0870
0871 FlashMsgCnt++;
0872 }
0873
0874
0875
0876
0877 if (ReadCmd == FAST_READ_CMD || ReadCmd == FAST_READ_CMD_4B)
0878 FlashMsg[FlashMsgCnt].BusWidth =
0879 XQSPIPSU_SELECT_MODE_SPI;
0880
0881 if (ReadCmd == DUAL_READ_CMD || ReadCmd == DUAL_READ_CMD_4B)
0882 FlashMsg[FlashMsgCnt].BusWidth =
0883 XQSPIPSU_SELECT_MODE_DUALSPI;
0884
0885 if (ReadCmd == QUAD_READ_CMD || ReadCmd == QUAD_READ_CMD_4B)
0886 FlashMsg[FlashMsgCnt].BusWidth =
0887 XQSPIPSU_SELECT_MODE_QUADSPI;
0888
0889 FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
0890 FlashMsg[FlashMsgCnt].RxBfrPtr = *ReadBfrPtr;
0891 FlashMsg[FlashMsgCnt].ByteCount = ByteCount;
0892 FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
0893
0894 if (QspiPsuPtr->Config.ConnectionMode ==
0895 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
0896 FlashMsg[FlashMsgCnt].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
0897 }
0898
0899 Status = transfer_and_wait(QspiPsuPtr, FlashMsg,
0900 FlashMsgCnt + 1);
0901 if (Status != XST_SUCCESS)
0902 return XST_FAILURE;
0903 }
0904 rtems_cache_invalidate_multiple_data_lines(ReadBuffer, ByteCount);
0905 return 0;
0906 }
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925 int QspiPsu_NOR_Read(
0926 XQspiPsu *QspiPsuPtr,
0927 u32 Address,
0928 u32 ByteCount,
0929 u8 *ReadBfr
0930 ) {
0931 u8 *tmp_buffer = NULL;
0932 int status;
0933 int startAlign = 0;
0934
0935
0936 if (Address%2) {
0937 startAlign = 1;
0938 Address = Address - 1;
0939 ByteCount = ByteCount + 1;
0940 }
0941
0942 while (ByteCount > XQSPI_FLASH_MAX_READ_SIZE) {
0943
0944 status = QspiPsu_NOR_Read_Page(QspiPsuPtr, Address,
0945 XQSPI_FLASH_MAX_READ_SIZE, &tmp_buffer);
0946
0947 if (status == 0) {
0948 memcpy(ReadBfr, tmp_buffer + startAlign,
0949 XQSPI_FLASH_MAX_READ_SIZE - startAlign);
0950
0951 ByteCount -= XQSPI_FLASH_MAX_READ_SIZE;
0952 ReadBfr += XQSPI_FLASH_MAX_READ_SIZE - startAlign;
0953 Address += XQSPI_FLASH_MAX_READ_SIZE;
0954
0955 if (startAlign) {
0956 startAlign = 0;
0957 }
0958 } else {
0959 return status;
0960 }
0961 }
0962
0963 status = QspiPsu_NOR_Read_Page(QspiPsuPtr, Address, ByteCount,
0964 &tmp_buffer);
0965
0966 if (status == 0) {
0967 memcpy(ReadBfr, tmp_buffer + startAlign, ByteCount);
0968 }
0969 return status;
0970 }
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994 static int MultiDieRead(
0995 XQspiPsu *QspiPsuPtr,
0996 u32 Address,
0997 u32 ByteCount,
0998 u8 Command,
0999 u8 *WriteBfrPtr,
1000 u8 *ReadBfrPtr
1001 )
1002 {
1003 u32 RealAddr;
1004 u32 DiscardByteCnt;
1005 u32 FlashMsgCnt;
1006 int Status;
1007 u32 cur_bank = 0;
1008 u32 nxt_bank = 0;
1009 u32 bank_size;
1010 u32 remain_len = ByteCount;
1011 u32 data_len;
1012 u32 transfer_len;
1013 u8 *ReadBuffer = ReadBfrPtr;
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 if (QspiPsuPtr->Config.ConnectionMode ==
1029 XQSPIPSU_CONNECTION_MODE_PARALLEL)
1030 bank_size = SIXTEENMB << 1;
1031 else
1032 bank_size = SIXTEENMB;
1033
1034 while (remain_len) {
1035 cur_bank = Address / bank_size;
1036 nxt_bank = (Address + remain_len) / bank_size;
1037
1038 if (cur_bank != nxt_bank) {
1039 transfer_len = (bank_size * (cur_bank + 1)) - Address;
1040 if (remain_len < transfer_len)
1041 data_len = remain_len;
1042 else
1043 data_len = transfer_len;
1044 } else {
1045 data_len = remain_len;
1046 }
1047
1048
1049
1050
1051 RealAddr = GetRealAddr(QspiPsuPtr, Address);
1052
1053 WriteBfrPtr[COMMAND_OFFSET] = Command;
1054 if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
1055 WriteBfrPtr[ADDRESS_1_OFFSET] =
1056 (u8)((RealAddr & 0xFF000000) >> 24);
1057 WriteBfrPtr[ADDRESS_2_OFFSET] =
1058 (u8)((RealAddr & 0xFF0000) >> 16);
1059 WriteBfrPtr[ADDRESS_3_OFFSET] =
1060 (u8)((RealAddr & 0xFF00) >> 8);
1061 WriteBfrPtr[ADDRESS_4_OFFSET] =
1062 (u8)(RealAddr & 0xFF);
1063 DiscardByteCnt = 5;
1064 } else {
1065 WriteBfrPtr[ADDRESS_1_OFFSET] =
1066 (u8)((RealAddr & 0xFF0000) >> 16);
1067 WriteBfrPtr[ADDRESS_2_OFFSET] =
1068 (u8)((RealAddr & 0xFF00) >> 8);
1069 WriteBfrPtr[ADDRESS_3_OFFSET] =
1070 (u8)(RealAddr & 0xFF);
1071 DiscardByteCnt = 4;
1072 }
1073
1074 FlashMsg[0].TxBfrPtr = WriteBfrPtr;
1075 FlashMsg[0].RxBfrPtr = NULL;
1076 FlashMsg[0].ByteCount = DiscardByteCnt;
1077 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1078 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1079
1080 FlashMsgCnt = 1;
1081
1082
1083 if (Command == FAST_READ_CMD || Command == DUAL_READ_CMD ||
1084 Command == QUAD_READ_CMD || Command == FAST_READ_CMD_4B ||
1085 Command == DUAL_READ_CMD_4B ||
1086 Command == QUAD_READ_CMD_4B) {
1087
1088
1089
1090
1091
1092
1093 if (Command == FAST_READ_CMD ||
1094 Command == FAST_READ_CMD_4B) {
1095 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1096 }
1097
1098 if (Command == DUAL_READ_CMD ||
1099 Command == DUAL_READ_CMD_4B) {
1100 FlashMsg[1].BusWidth =
1101 XQSPIPSU_SELECT_MODE_DUALSPI;
1102 }
1103
1104 if (Command == QUAD_READ_CMD ||
1105 Command == QUAD_READ_CMD_4B) {
1106 FlashMsg[1].BusWidth =
1107 XQSPIPSU_SELECT_MODE_QUADSPI;
1108 }
1109
1110 FlashMsg[1].TxBfrPtr = NULL;
1111 FlashMsg[1].RxBfrPtr = NULL;
1112 FlashMsg[1].ByteCount = DUMMY_CLOCKS;
1113 FlashMsg[1].Flags = 0;
1114
1115 FlashMsgCnt++;
1116 }
1117
1118
1119
1120
1121 if (Command == FAST_READ_CMD || Command == FAST_READ_CMD_4B)
1122 FlashMsg[FlashMsgCnt].BusWidth =
1123 XQSPIPSU_SELECT_MODE_SPI;
1124
1125 if (Command == DUAL_READ_CMD || Command == DUAL_READ_CMD_4B)
1126 FlashMsg[FlashMsgCnt].BusWidth =
1127 XQSPIPSU_SELECT_MODE_DUALSPI;
1128
1129 if (Command == QUAD_READ_CMD || Command == QUAD_READ_CMD_4B)
1130 FlashMsg[FlashMsgCnt].BusWidth =
1131 XQSPIPSU_SELECT_MODE_QUADSPI;
1132
1133 FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
1134 FlashMsg[FlashMsgCnt].RxBfrPtr = ReadBuffer;
1135 FlashMsg[FlashMsgCnt].ByteCount = data_len;
1136 FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
1137
1138 if (QspiPsuPtr->Config.ConnectionMode ==
1139 XQSPIPSU_CONNECTION_MODE_PARALLEL)
1140 FlashMsg[FlashMsgCnt].Flags |=
1141 XQSPIPSU_MSG_FLAG_STRIPE;
1142
1143 Status = transfer_and_wait(QspiPsuPtr, FlashMsg,
1144 FlashMsgCnt + 1);
1145 if (Status != XST_SUCCESS)
1146 return XST_FAILURE;
1147
1148 ReadBuffer += data_len;
1149 Address += data_len;
1150 remain_len -= data_len;
1151 }
1152 rtems_cache_invalidate_multiple_data_lines(ReadBfrPtr, ByteCount);
1153 return 0;
1154 }
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170 static int BulkErase(
1171 XQspiPsu *QspiPsuPtr,
1172 u8 *WriteBfrPtr
1173 )
1174 {
1175 u8 WriteEnableCmd;
1176 u8 ReadStatusCmd;
1177 u8 FlashStatus[2];
1178 int Status;
1179
1180 WriteEnableCmd = WRITE_ENABLE_CMD;
1181
1182
1183
1184
1185
1186 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
1187 FlashMsg[0].RxBfrPtr = NULL;
1188 FlashMsg[0].ByteCount = 1;
1189 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1190 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1191
1192 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1193 if (Status != XST_SUCCESS) {
1194 return XST_FAILURE;
1195 }
1196
1197 WriteBfrPtr[COMMAND_OFFSET] = BULK_ERASE_CMD;
1198 FlashMsg[0].TxBfrPtr = WriteBfrPtr;
1199 FlashMsg[0].RxBfrPtr = NULL;
1200 FlashMsg[0].ByteCount = 1;
1201 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1202 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1203
1204 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1205 if (Status != XST_SUCCESS) {
1206 return XST_FAILURE;
1207 }
1208
1209
1210
1211
1212
1213 while (1) {
1214 ReadStatusCmd = StatusCmd;
1215 FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
1216 FlashMsg[0].RxBfrPtr = NULL;
1217 FlashMsg[0].ByteCount = 1;
1218 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1219 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1220
1221 FlashMsg[1].TxBfrPtr = NULL;
1222 FlashMsg[1].RxBfrPtr = FlashStatus;
1223 FlashMsg[1].ByteCount = 2;
1224 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1225 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1226 if (QspiPsuPtr->Config.ConnectionMode ==
1227 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1228 FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
1229 }
1230
1231 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1232 if (Status != XST_SUCCESS) {
1233 return XST_FAILURE;
1234 }
1235
1236 if (QspiPsuPtr->Config.ConnectionMode ==
1237 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1238 if (FSRFlag) {
1239 FlashStatus[1] &= FlashStatus[0];
1240 } else {
1241 FlashStatus[1] |= FlashStatus[0];
1242 }
1243 }
1244
1245 if (FSRFlag) {
1246 if ((FlashStatus[1] & 0x80) != 0) {
1247 break;
1248 }
1249 } else {
1250 if ((FlashStatus[1] & 0x01) == 0) {
1251 break;
1252 }
1253 }
1254 }
1255
1256 return 0;
1257 }
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274 static int DieErase(
1275 XQspiPsu *QspiPsuPtr,
1276 u8 *WriteBfrPtr
1277 )
1278 {
1279 u8 WriteEnableCmd;
1280 u8 DieCnt;
1281 u8 ReadStatusCmd;
1282 u8 FlashStatus[2];
1283 int Status;
1284 u32 DieSize = 0;
1285 u32 Address;
1286 u32 RealAddr;
1287 u32 SectSize = 0;
1288 u32 NumSect = 0;
1289
1290 WriteEnableCmd = WRITE_ENABLE_CMD;
1291
1292 if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1293 SectSize = (Flash_Config_Table[FCTIndex]).SectSize * 2;
1294 } else if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) {
1295 NumSect = (Flash_Config_Table[FCTIndex]).NumSect * 2;
1296 } else {
1297 SectSize = (Flash_Config_Table[FCTIndex]).SectSize;
1298 NumSect = (Flash_Config_Table[FCTIndex]).NumSect;
1299 }
1300 DieSize = (NumSect * SectSize) / Flash_Config_Table[FCTIndex].NumDie;
1301
1302 for (DieCnt = 0;
1303 DieCnt < Flash_Config_Table[FCTIndex].NumDie;
1304 DieCnt++) {
1305
1306
1307
1308
1309
1310 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
1311 FlashMsg[0].RxBfrPtr = NULL;
1312 FlashMsg[0].ByteCount = 1;
1313 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1314 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1315
1316 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1317 if (Status != XST_SUCCESS) {
1318 return XST_FAILURE;
1319 }
1320
1321 WriteBfrPtr[COMMAND_OFFSET] = DIE_ERASE_CMD;
1322
1323 Address = DieSize * DieCnt;
1324 RealAddr = GetRealAddr(QspiPsuPtr, Address);
1325
1326
1327
1328
1329 if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
1330 WriteBfrPtr[ADDRESS_1_OFFSET] =
1331 (u8)((RealAddr & 0xFF000000) >> 24);
1332 WriteBfrPtr[ADDRESS_2_OFFSET] =
1333 (u8)((RealAddr & 0xFF0000) >> 16);
1334 WriteBfrPtr[ADDRESS_3_OFFSET] =
1335 (u8)((RealAddr & 0xFF00) >> 8);
1336 WriteBfrPtr[ADDRESS_4_OFFSET] =
1337 (u8)(RealAddr & 0xFF);
1338 FlashMsg[0].ByteCount = 5;
1339 } else {
1340 WriteBfrPtr[ADDRESS_1_OFFSET] =
1341 (u8)((RealAddr & 0xFF0000) >> 16);
1342 WriteBfrPtr[ADDRESS_2_OFFSET] =
1343 (u8)((RealAddr & 0xFF00) >> 8);
1344 WriteBfrPtr[ADDRESS_3_OFFSET] =
1345 (u8)(RealAddr & 0xFF);
1346 FlashMsg[0].ByteCount = 4;
1347 }
1348 FlashMsg[0].TxBfrPtr = WriteBfrPtr;
1349 FlashMsg[0].RxBfrPtr = NULL;
1350 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1351 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1352
1353 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1354 if (Status != XST_SUCCESS) {
1355 return XST_FAILURE;
1356 }
1357
1358
1359
1360
1361
1362 while (1) {
1363 ReadStatusCmd = StatusCmd;
1364 FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
1365 FlashMsg[0].RxBfrPtr = NULL;
1366 FlashMsg[0].ByteCount = 1;
1367 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1368 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1369
1370 FlashMsg[1].TxBfrPtr = NULL;
1371 FlashMsg[1].RxBfrPtr = FlashStatus;
1372 FlashMsg[1].ByteCount = 2;
1373 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1374 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1375 if (QspiPsuPtr->Config.ConnectionMode ==
1376 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1377 FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
1378 }
1379
1380 Status = transfer_and_wait(QspiPsuPtr,
1381 FlashMsg, 2);
1382 if (Status != XST_SUCCESS) {
1383 return XST_FAILURE;
1384 }
1385
1386 if (QspiPsuPtr->Config.ConnectionMode ==
1387 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1388 if (FSRFlag) {
1389 FlashStatus[1] &= FlashStatus[0];
1390 } else {
1391 FlashStatus[1] |= FlashStatus[0];
1392 }
1393 }
1394
1395 if (FSRFlag) {
1396 if ((FlashStatus[1] & 0x80) != 0) {
1397 break;
1398 }
1399 } else {
1400 if ((FlashStatus[1] & 0x01) == 0) {
1401 break;
1402 }
1403 }
1404 }
1405 }
1406
1407 return 0;
1408 }
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428 static u32 GetRealAddr(
1429 XQspiPsu *QspiPsuPtr,
1430 u32 Address
1431 )
1432 {
1433 u32 RealAddr = 0;
1434
1435 switch (QspiPsuPtr->Config.ConnectionMode) {
1436 case XQSPIPSU_CONNECTION_MODE_SINGLE:
1437 XQspiPsu_SelectFlash(QspiPsuPtr,
1438 XQSPIPSU_SELECT_FLASH_CS_LOWER,
1439 XQSPIPSU_SELECT_FLASH_BUS_LOWER);
1440 RealAddr = Address;
1441 break;
1442 case XQSPIPSU_CONNECTION_MODE_STACKED:
1443
1444 if (Address & Flash_Config_Table[FCTIndex].FlashDeviceSize) {
1445
1446 XQspiPsu_SelectFlash(QspiPsuPtr,
1447 XQSPIPSU_SELECT_FLASH_CS_UPPER,
1448 XQSPIPSU_SELECT_FLASH_BUS_LOWER);
1449
1450
1451
1452 RealAddr = Address &
1453 (~Flash_Config_Table[FCTIndex].FlashDeviceSize);
1454 }else{
1455
1456
1457
1458 XQspiPsu_SelectFlash(QspiPsuPtr,
1459 XQSPIPSU_SELECT_FLASH_CS_LOWER,
1460 XQSPIPSU_SELECT_FLASH_BUS_LOWER);
1461
1462 RealAddr = Address;
1463
1464 }
1465 break;
1466 case XQSPIPSU_CONNECTION_MODE_PARALLEL:
1467
1468
1469
1470
1471 XQspiPsu_SelectFlash(QspiPsuPtr,
1472 XQSPIPSU_SELECT_FLASH_CS_BOTH,
1473 XQSPIPSU_SELECT_FLASH_BUS_BOTH);
1474 RealAddr = Address / 2;
1475 break;
1476 default:
1477
1478 break;
1479
1480 }
1481
1482 return(RealAddr);
1483 }
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499 static int QspiPsuSetupIntrSystem(
1500 XQspiPsu *QspiPsuInstancePtr,
1501 u16 QspiPsuIntrId
1502 )
1503 {
1504 return rtems_interrupt_handler_install(
1505 QspiPsuIntrId,
1506 NULL,
1507 RTEMS_INTERRUPT_UNIQUE,
1508 (rtems_interrupt_handler) XQspiPsu_InterruptHandler,
1509 QspiPsuInstancePtr
1510 );
1511 }
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531 static int FlashEnterExit4BAddMode(
1532 XQspiPsu *QspiPsuPtr,
1533 unsigned int Enable
1534 )
1535 {
1536 int Status;
1537 u8 WriteEnableCmd;
1538 u8 Cmd;
1539 u8 WriteDisableCmd;
1540 u8 ReadStatusCmd;
1541 u8 WriteBuffer[2] = {0};
1542 u8 FlashStatus[2] = {0};
1543
1544 if (Enable) {
1545 Cmd = ENTER_4B_ADDR_MODE;
1546 } else {
1547 if (FlashMake == ISSI_ID_BYTE0)
1548 Cmd = EXIT_4B_ADDR_MODE_ISSI;
1549 else
1550 Cmd = EXIT_4B_ADDR_MODE;
1551 }
1552
1553 switch (FlashMake) {
1554 case ISSI_ID_BYTE0:
1555 case MICRON_ID_BYTE0:
1556 WriteEnableCmd = WRITE_ENABLE_CMD;
1557 GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
1558
1559
1560
1561
1562
1563 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
1564 FlashMsg[0].RxBfrPtr = NULL;
1565 FlashMsg[0].ByteCount = 1;
1566 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1567 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1568
1569 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1570 if (Status != XST_SUCCESS) {
1571 return XST_FAILURE;
1572 }
1573
1574 break;
1575
1576 case SPANSION_ID_BYTE0:
1577
1578
1579 WriteBuffer[0] = BANK_REG_RD;
1580 FlashMsg[0].TxBfrPtr = &WriteBuffer[0];
1581 FlashMsg[0].RxBfrPtr = NULL;
1582 FlashMsg[0].ByteCount = 1;
1583 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1584 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1585
1586 FlashMsg[1].TxBfrPtr = NULL;
1587 FlashMsg[1].RxBfrPtr = &WriteBuffer[1];
1588 FlashMsg[1].ByteCount = 1;
1589 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1590 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1591 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1592 if (Status != XST_SUCCESS) {
1593 return XST_FAILURE;
1594 }
1595 if (Enable) {
1596 WriteBuffer[0] = BANK_REG_WR;
1597 WriteBuffer[1] |= 1 << 7;
1598 } else {
1599 WriteBuffer[0] = BANK_REG_WR;
1600 WriteBuffer[1] &= ~(0x01 << 7);
1601 }
1602
1603 FlashMsg[0].TxBfrPtr = &WriteBuffer[0];
1604 FlashMsg[0].RxBfrPtr = NULL;
1605 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1606 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1607 FlashMsg[0].ByteCount = 1;
1608 FlashMsg[1].TxBfrPtr = &WriteBuffer[1];
1609 FlashMsg[2].RxBfrPtr = NULL;
1610 FlashMsg[2].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1611 FlashMsg[2].Flags = XQSPIPSU_MSG_FLAG_TX;
1612 FlashMsg[2].ByteCount = 1;
1613
1614 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1615 if (Status != XST_SUCCESS) {
1616 return XST_FAILURE;
1617 }
1618 WriteBuffer[0] = BANK_REG_RD;
1619 FlashMsg[0].TxBfrPtr = &WriteBuffer[0];
1620 FlashMsg[0].RxBfrPtr = NULL;
1621 FlashMsg[0].ByteCount = 1;
1622 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1623 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1624
1625 FlashMsg[1].TxBfrPtr = NULL;
1626 FlashMsg[1].RxBfrPtr = &FlashStatus[0];
1627 FlashMsg[1].ByteCount = 1;
1628 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1629 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1630
1631 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1632 if (Status != XST_SUCCESS) {
1633 return XST_FAILURE;
1634 }
1635
1636 return Status;
1637
1638 default:
1639
1640
1641
1642
1643 break;
1644 }
1645
1646 GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
1647
1648 FlashMsg[0].TxBfrPtr = &Cmd;
1649 FlashMsg[0].RxBfrPtr = NULL;
1650 FlashMsg[0].ByteCount = 1;
1651 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1652 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1653
1654 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1655 if (Status != XST_SUCCESS) {
1656 return XST_FAILURE;
1657 }
1658
1659 while (1) {
1660 ReadStatusCmd = StatusCmd;
1661
1662 FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
1663 FlashMsg[0].RxBfrPtr = NULL;
1664 FlashMsg[0].ByteCount = 1;
1665 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1666 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1667
1668 FlashMsg[1].TxBfrPtr = NULL;
1669 FlashMsg[1].RxBfrPtr = FlashStatus;
1670 FlashMsg[1].ByteCount = 2;
1671 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1672 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1673
1674 if (QspiPsuPtr->Config.ConnectionMode ==
1675 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1676 FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
1677 }
1678
1679 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1680 if (Status != XST_SUCCESS) {
1681 return XST_FAILURE;
1682 }
1683
1684 if (QspiPsuPtr->Config.ConnectionMode ==
1685 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1686 if (FSRFlag) {
1687 FlashStatus[1] &= FlashStatus[0];
1688 } else {
1689 FlashStatus[1] |= FlashStatus[0];
1690 }
1691 }
1692
1693 if (FSRFlag) {
1694 if ((FlashStatus[1] & 0x80) != 0) {
1695 break;
1696 }
1697 } else {
1698 if ((FlashStatus[1] & 0x01) == 0) {
1699 break;
1700 }
1701 }
1702 }
1703
1704 switch (FlashMake) {
1705 case ISSI_ID_BYTE0:
1706 case MICRON_ID_BYTE0:
1707 WriteDisableCmd = WRITE_DISABLE_CMD;
1708 GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
1709
1710
1711
1712
1713
1714 FlashMsg[0].TxBfrPtr = &WriteDisableCmd;
1715 FlashMsg[0].RxBfrPtr = NULL;
1716 FlashMsg[0].ByteCount = 1;
1717 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1718 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1719
1720 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1721 if (Status != XST_SUCCESS) {
1722 return XST_FAILURE;
1723 }
1724
1725 break;
1726
1727 default:
1728
1729
1730
1731
1732 break;
1733 }
1734 return Status;
1735 }
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753 static int FlashEnableQuadMode(XQspiPsu *QspiPsuPtr)
1754 {
1755 int Status;
1756 u8 WriteEnableCmd;
1757 u8 ReadStatusCmd;
1758 u8 FlashStatus[2];
1759 u8 StatusRegVal;
1760 u8 WriteBuffer[3] = {0};
1761
1762 switch (FlashMake) {
1763 case SPANSION_ID_BYTE0:
1764 TxBfrPtr = READ_CONFIG_CMD;
1765 FlashMsg[0].TxBfrPtr = &TxBfrPtr;
1766 FlashMsg[0].RxBfrPtr = NULL;
1767 FlashMsg[0].ByteCount = 1;
1768 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1769 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1770
1771 FlashMsg[1].TxBfrPtr = NULL;
1772 FlashMsg[1].RxBfrPtr = &WriteBuffer[2];
1773 FlashMsg[1].ByteCount = 1;
1774 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1775 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1776
1777 Status = transfer_and_wait(QspiPsuPtr,
1778 FlashMsg, 2);
1779 if (Status != XST_SUCCESS) {
1780 return XST_FAILURE;
1781 }
1782
1783 WriteEnableCmd = WRITE_ENABLE_CMD;
1784
1785
1786
1787
1788
1789
1790 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
1791 FlashMsg[0].RxBfrPtr = NULL;
1792 FlashMsg[0].ByteCount = 1;
1793 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1794 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1795
1796 Status = transfer_and_wait(QspiPsuPtr,
1797 FlashMsg, 1);
1798 if (Status != XST_SUCCESS) {
1799 return XST_FAILURE;
1800 }
1801
1802 GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
1803
1804 WriteBuffer[0] = WRITE_CONFIG_CMD;
1805 WriteBuffer[1] |= 0x02;
1806 WriteBuffer[2] |= 0x01 << 1;
1807
1808 FlashMsg[0].TxBfrPtr = &WriteBuffer[0];
1809 FlashMsg[0].RxBfrPtr = NULL;
1810 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1811 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1812 FlashMsg[0].ByteCount = 1;
1813 FlashMsg[1].TxBfrPtr = &WriteBuffer[1];
1814 FlashMsg[1].RxBfrPtr = NULL;
1815 FlashMsg[1].ByteCount = 2;
1816 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1817 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
1818
1819 Status = transfer_and_wait(QspiPsuPtr,
1820 FlashMsg, 2);
1821 if (Status != XST_SUCCESS) {
1822 return XST_FAILURE;
1823 }
1824
1825 while (1) {
1826 TxBfrPtr = READ_STATUS_CMD;
1827 FlashMsg[0].TxBfrPtr = &TxBfrPtr;
1828 FlashMsg[0].RxBfrPtr = NULL;
1829 FlashMsg[0].ByteCount = 1;
1830 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1831 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1832
1833 FlashMsg[1].TxBfrPtr = NULL;
1834 FlashMsg[1].RxBfrPtr = FlashStatus;
1835 FlashMsg[1].ByteCount = 2;
1836 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1837 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1838
1839 Status = transfer_and_wait(QspiPsuPtr,
1840 FlashMsg, 2);
1841 if (Status != XST_SUCCESS) {
1842 return XST_FAILURE;
1843 }
1844 if (QspiPsuPtr->Config.ConnectionMode ==
1845 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1846 if (FSRFlag) {
1847 FlashStatus[1] &= FlashStatus[0];
1848 }else {
1849 FlashStatus[1] |= FlashStatus[0];
1850 }
1851 }
1852
1853 if ((FlashStatus[1] & 0x01) == 0x00)
1854 break;
1855 }
1856 TxBfrPtr = READ_CONFIG_CMD;
1857 FlashMsg[0].TxBfrPtr = &TxBfrPtr;
1858 FlashMsg[0].RxBfrPtr = NULL;
1859 FlashMsg[0].ByteCount = 1;
1860 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1861 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1862
1863 FlashMsg[1].TxBfrPtr = NULL;
1864 FlashMsg[1].RxBfrPtr = ReadBfrPtr;
1865 FlashMsg[1].ByteCount = 1;
1866 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1867 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1868
1869 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1870 if (Status != XST_SUCCESS) {
1871 return XST_FAILURE;
1872 }
1873 break;
1874 case ISSI_ID_BYTE0:
1875
1876
1877
1878 ReadStatusCmd = READ_STATUS_CMD;
1879 FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
1880 FlashMsg[0].RxBfrPtr = NULL;
1881 FlashMsg[0].ByteCount = 1;
1882 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1883 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1884 FlashMsg[1].TxBfrPtr = NULL;
1885 FlashMsg[1].RxBfrPtr = FlashStatus;
1886 FlashMsg[1].ByteCount = 2;
1887 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1888 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1889 if (QspiPsuPtr->Config.ConnectionMode ==
1890 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1891 FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
1892 }
1893 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1894 if (Status != XST_SUCCESS) {
1895 return XST_FAILURE;
1896 }
1897 if (QspiPsuPtr->Config.ConnectionMode ==
1898 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1899 if (FSRFlag) {
1900 FlashStatus[1] &= FlashStatus[0];
1901 } else {
1902 FlashStatus[1] |= FlashStatus[0];
1903 }
1904 }
1905
1906
1907
1908 StatusRegVal = FlashStatus[1];
1909 StatusRegVal |= 0x1 << QUAD_MODE_ENABLE_BIT;
1910
1911
1912
1913
1914 WriteEnableCmd = WRITE_ENABLE_CMD;
1915
1916
1917
1918
1919
1920 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
1921 FlashMsg[0].RxBfrPtr = NULL;
1922 FlashMsg[0].ByteCount = 1;
1923 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1924 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1925 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1926 if (Status != XST_SUCCESS) {
1927 return XST_FAILURE;
1928 }
1929
1930
1931
1932
1933 WriteBuffer[COMMAND_OFFSET] = WRITE_STATUS_CMD;
1934 FlashMsg[0].TxBfrPtr = WriteBuffer;
1935 FlashMsg[0].RxBfrPtr = NULL;
1936 FlashMsg[0].ByteCount = 1;
1937 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1938 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1939
1940 FlashMsg[1].TxBfrPtr = &StatusRegVal;
1941 FlashMsg[1].RxBfrPtr = NULL;
1942 FlashMsg[1].ByteCount = 1;
1943 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1944 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
1945 if (QspiPsuPtr->Config.ConnectionMode ==
1946 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1947 FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
1948 }
1949 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1950 if (Status != XST_SUCCESS) {
1951 return XST_FAILURE;
1952 }
1953
1954
1955
1956
1957 WriteEnableCmd = WRITE_DISABLE_CMD;
1958 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
1959 FlashMsg[0].RxBfrPtr = NULL;
1960 FlashMsg[0].ByteCount = 1;
1961 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1962 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1963 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
1964 if (Status != XST_SUCCESS) {
1965 return XST_FAILURE;
1966 }
1967 break;
1968
1969 case WINBOND_ID_BYTE0:
1970 ReadStatusCmd = READ_STATUS_REG_2_CMD;
1971 FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
1972 FlashMsg[0].RxBfrPtr = NULL;
1973 FlashMsg[0].ByteCount = 1;
1974 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1975 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
1976 FlashMsg[1].TxBfrPtr = NULL;
1977 FlashMsg[1].RxBfrPtr = FlashStatus;
1978 FlashMsg[1].ByteCount = 2;
1979 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
1980 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
1981 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
1982 if (Status != XST_SUCCESS) {
1983 return XST_FAILURE;
1984 }
1985
1986 if (QspiPsuPtr->Config.ConnectionMode ==
1987 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
1988 if (FSRFlag) {
1989 FlashStatus[1] &= FlashStatus[0];
1990 } else {
1991 FlashStatus[1] |= FlashStatus[0];
1992 }
1993 }
1994
1995
1996
1997 StatusRegVal = FlashStatus[1];
1998 StatusRegVal |= 0x1 << WB_QUAD_MODE_ENABLE_BIT;
1999
2000
2001
2002 WriteEnableCmd = WRITE_ENABLE_CMD;
2003 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
2004 FlashMsg[0].RxBfrPtr = NULL;
2005 FlashMsg[0].ByteCount = 1;
2006 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2007 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
2008 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 1);
2009 if (Status != XST_SUCCESS) {
2010 return XST_FAILURE;
2011 }
2012
2013
2014
2015 WriteBuffer[COMMAND_OFFSET] = WRITE_STATUS_REG_2_CMD;
2016 FlashMsg[0].TxBfrPtr = WriteBuffer;
2017 FlashMsg[0].RxBfrPtr = NULL;
2018 FlashMsg[0].ByteCount = 1;
2019 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2020 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
2021
2022 FlashMsg[1].TxBfrPtr = &StatusRegVal;
2023 FlashMsg[1].RxBfrPtr = NULL;
2024 FlashMsg[1].ByteCount = 1;
2025 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2026 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
2027 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
2028 if (Status != XST_SUCCESS) {
2029 return XST_FAILURE;
2030 }
2031
2032 while (1) {
2033 ReadStatusCmd = READ_STATUS_CMD;
2034 FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
2035 FlashMsg[0].RxBfrPtr = NULL;
2036 FlashMsg[0].ByteCount = 1;
2037 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2038 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
2039 FlashMsg[1].TxBfrPtr = NULL;
2040 FlashMsg[1].RxBfrPtr = FlashStatus;
2041 FlashMsg[1].ByteCount = 2;
2042 FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2043 FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
2044 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
2045 if (Status != XST_SUCCESS) {
2046 return XST_FAILURE;
2047 }
2048
2049 if (QspiPsuPtr->Config.ConnectionMode ==
2050 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
2051 if (FSRFlag) {
2052 FlashStatus[1] &= FlashStatus[0];
2053 } else {
2054 FlashStatus[1] |= FlashStatus[0];
2055 }
2056 }
2057 if ((FlashStatus[1] & 0x01) == 0x00) {
2058 break;
2059 }
2060 }
2061
2062
2063
2064 WriteEnableCmd = WRITE_DISABLE_CMD;
2065 FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
2066 FlashMsg[0].RxBfrPtr = NULL;
2067 FlashMsg[0].ByteCount = 1;
2068 FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2069 FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
2070 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, 2);
2071 if (Status != XST_SUCCESS) {
2072 return XST_FAILURE;
2073 }
2074 break;
2075
2076 default:
2077
2078
2079
2080
2081 Status = XST_SUCCESS;
2082 break;
2083 }
2084
2085 return Status;
2086 }
2087
2088 static int MultiDieReadEcc(
2089 XQspiPsu *QspiPsuPtr,
2090 u32 Address,
2091 u32 ByteCount,
2092 u8 *WriteBfrPtr,
2093 u8 *ReadBfrPtr
2094 );
2095
2096 int QspiPsu_NOR_Read_Ecc(
2097 XQspiPsu *QspiPsuPtr,
2098 u32 Address,
2099 u8 *ReadBfrPtr
2100 )
2101 {
2102 u32 RealAddr;
2103 u32 DiscardByteCnt;
2104 u32 FlashMsgCnt;
2105 u8 EccBuffer[16];
2106 int ByteCount = sizeof(EccBuffer);
2107 int Status;
2108
2109
2110 if (Flash_Config_Table[FCTIndex].NumDie > 1) {
2111
2112 Status = MultiDieReadEcc(QspiPsuPtr, Address, ByteCount,
2113 CmdBfr, EccBuffer);
2114 if (Status == XST_SUCCESS) {
2115
2116 *ReadBfrPtr = EccBuffer[0];
2117 }
2118 return Status;
2119 }
2120
2121
2122
2123
2124
2125
2126 RealAddr = GetRealAddr(QspiPsuPtr, Address);
2127
2128 CmdBfr[COMMAND_OFFSET] = READ_ECCSR;
2129 CmdBfr[ADDRESS_1_OFFSET] =
2130 (u8)((RealAddr & 0xFF000000) >> 24);
2131 CmdBfr[ADDRESS_2_OFFSET] =
2132 (u8)((RealAddr & 0xFF0000) >> 16);
2133 CmdBfr[ADDRESS_3_OFFSET] =
2134 (u8)((RealAddr & 0xFF00) >> 8);
2135 CmdBfr[ADDRESS_4_OFFSET] =
2136 (u8)(RealAddr & 0xF0);
2137 DiscardByteCnt = 5;
2138
2139 FlashMsgCnt = 0;
2140
2141 FlashMsg[FlashMsgCnt].TxBfrPtr = CmdBfr;
2142 FlashMsg[FlashMsgCnt].RxBfrPtr = NULL;
2143 FlashMsg[FlashMsgCnt].ByteCount = DiscardByteCnt;
2144 FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2145 FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_TX;
2146
2147 FlashMsgCnt++;
2148
2149 FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
2150 FlashMsg[FlashMsgCnt].RxBfrPtr = NULL;
2151 FlashMsg[FlashMsgCnt].ByteCount = DUMMY_CLOCKS;
2152 FlashMsg[FlashMsgCnt].Flags = 0;
2153
2154 FlashMsgCnt++;
2155
2156 FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
2157 FlashMsg[FlashMsgCnt].RxBfrPtr = EccBuffer;
2158 FlashMsg[FlashMsgCnt].ByteCount = ByteCount;
2159 FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2160 FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
2161
2162 if (QspiPsuPtr->Config.ConnectionMode ==
2163 XQSPIPSU_CONNECTION_MODE_PARALLEL) {
2164 FlashMsg[FlashMsgCnt].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
2165 }
2166
2167 Status = transfer_and_wait(QspiPsuPtr, FlashMsg,
2168 FlashMsgCnt + 1);
2169 if (Status == XST_SUCCESS) {
2170
2171 *ReadBfrPtr = EccBuffer[0];
2172 }
2173
2174 return Status;
2175 }
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197 static int MultiDieReadEcc(
2198 XQspiPsu *QspiPsuPtr,
2199 u32 Address,
2200 u32 ByteCount,
2201 u8 *WriteBfrPtr,
2202 u8 *ReadBuffer
2203 )
2204 {
2205 u32 RealAddr;
2206 u32 DiscardByteCnt;
2207 u32 FlashMsgCnt;
2208 int Status;
2209 u32 cur_bank = 0;
2210 u32 nxt_bank = 0;
2211 u32 bank_size;
2212 u32 remain_len = ByteCount;
2213 u32 data_len;
2214 u32 transfer_len;
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229 if (QspiPsuPtr->Config.ConnectionMode ==
2230 XQSPIPSU_CONNECTION_MODE_PARALLEL)
2231 bank_size = SIXTEENMB << 1;
2232 else
2233 bank_size = SIXTEENMB;
2234
2235 while (remain_len) {
2236 cur_bank = Address / bank_size;
2237 nxt_bank = (Address + remain_len) / bank_size;
2238
2239 if (cur_bank != nxt_bank) {
2240 transfer_len = (bank_size * (cur_bank + 1)) - Address;
2241 if (remain_len < transfer_len)
2242 data_len = remain_len;
2243 else
2244 data_len = transfer_len;
2245 } else {
2246 data_len = remain_len;
2247 }
2248
2249
2250
2251
2252 RealAddr = GetRealAddr(QspiPsuPtr, Address);
2253
2254 WriteBfrPtr[COMMAND_OFFSET] = READ_ECCSR;
2255 WriteBfrPtr[ADDRESS_1_OFFSET] =
2256 (u8)((RealAddr & 0xFF000000) >> 24);
2257 WriteBfrPtr[ADDRESS_2_OFFSET] =
2258 (u8)((RealAddr & 0xFF0000) >> 16);
2259 WriteBfrPtr[ADDRESS_3_OFFSET] =
2260 (u8)((RealAddr & 0xFF00) >> 8);
2261 WriteBfrPtr[ADDRESS_4_OFFSET] =
2262 (u8)(RealAddr & 0xF0);
2263 DiscardByteCnt = 5;
2264
2265 FlashMsgCnt = 0;
2266
2267 FlashMsg[FlashMsgCnt].TxBfrPtr = WriteBfrPtr;
2268 FlashMsg[FlashMsgCnt].RxBfrPtr = NULL;
2269 FlashMsg[FlashMsgCnt].ByteCount = DiscardByteCnt;
2270 FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2271 FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_TX;
2272
2273 FlashMsgCnt++;
2274
2275 FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
2276 FlashMsg[FlashMsgCnt].RxBfrPtr = NULL;
2277 FlashMsg[FlashMsgCnt].ByteCount = DUMMY_CLOCKS;
2278 FlashMsg[FlashMsgCnt].Flags = 0;
2279
2280 FlashMsgCnt++;
2281
2282 FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
2283 FlashMsg[FlashMsgCnt].RxBfrPtr = ReadBuffer;
2284 FlashMsg[FlashMsgCnt].ByteCount = data_len;
2285 FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
2286 FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
2287
2288 if (QspiPsuPtr->Config.ConnectionMode ==
2289 XQSPIPSU_CONNECTION_MODE_PARALLEL)
2290 FlashMsg[FlashMsgCnt].Flags |=
2291 XQSPIPSU_MSG_FLAG_STRIPE;
2292
2293 Status = transfer_and_wait(QspiPsuPtr, FlashMsg, FlashMsgCnt + 1);
2294 if (Status != XST_SUCCESS)
2295 return XST_FAILURE;
2296
2297 ReadBuffer += data_len;
2298 Address += data_len;
2299 remain_len -= data_len;
2300 }
2301 return 0;
2302 }
2303
2304 u32 QspiPsu_NOR_Get_Sector_Size(XQspiPsu *QspiPsuPtr)
2305 {
2306 if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
2307 return Flash_Config_Table[FCTIndex].SectSize * 2;
2308 }
2309 return Flash_Config_Table[FCTIndex].SectSize;
2310 }
2311
2312 u32 QspiPsu_NOR_Get_Device_Size(XQspiPsu *QspiPsuPtr)
2313 {
2314 if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED
2315 || QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
2316 return Flash_Config_Table[FCTIndex].FlashDeviceSize * 2;
2317 }
2318 return Flash_Config_Table[FCTIndex].FlashDeviceSize;
2319 }
2320
2321 u32 QspiPsu_NOR_Get_Page_Size(XQspiPsu *QspiPsuPtr)
2322 {
2323 if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) {
2324 return Flash_Config_Table[FCTIndex].PageSize * 2;
2325 }
2326 return Flash_Config_Table[FCTIndex].PageSize;
2327 }
2328
2329 u32 QspiPsu_NOR_Get_JEDEC_ID(XQspiPsu *QspiPsuPtr)
2330 {
2331 return Flash_Config_Table[FCTIndex].jedec_id;
2332 }