xilisf: Added QSPIPSU flash interface support.

This patch add QSPIPSU flash interface support
in ZynqMP.

Signed-off-by: P L Sai Krishna <lakshmis@xilinx.com>
Reviewed-by: Harini Katakam <harinik@xilinx.com>
This commit is contained in:
P L Sai Krishna 2015-08-07 21:41:40 +05:30 committed by Nava kishore Manne
parent e177ff8390
commit 37e2397703
5 changed files with 909 additions and 61 deletions

View file

@ -496,6 +496,7 @@
* These were done to fix CR#858950.
* 5.3 sk 06/01/15 Used Half of Actual byte count for calculating
* Real Byte count in parallel mode. CR# 859979.
* 5.4 sk 08/07/17 Added QSPIPSU flash interface support for ZynqMP.
*
* </pre>
*
@ -517,6 +518,8 @@ extern "C" {
#include "xspips.h"
#elif XPAR_XISF_INTERFACE_PSQSPI
#include "xqspips.h"
#elif XPAR_XISF_INTERFACE_QSPIPSU
#include "xqspipsu.h"
#endif
/**
@ -637,6 +640,8 @@ extern "C" {
#elif XPAR_XISF_INTERFACE_PSQSPI
#define XISF_SPI_OPTIONS (XQSPIPS_MANUAL_START_OPTION | \
XQSPIPS_FORCE_SSELECT_OPTION)
#elif XPAR_XISF_INTERFACE_QSPIPSU
#define XISF_SPI_OPTIONS XQSPIPSU_MANUAL_START_OPTION
#elif XPAR_XISF_INTERFACE_PSSPI
#define XISF_SPI_OPTIONS (XSPIPS_MASTER_OPTION | \
XSPIPS_FORCE_SSELECT_OPTION)
@ -647,6 +652,8 @@ extern "C" {
*/
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#define XISF_SPI_PRESCALER XQSPIPS_CLK_PRESCALE_4
#elif XPAR_XISF_INTERFACE_QSPIPSU
#define XISF_SPI_PRESCALER XQSPIPSU_CLK_PRESCALE_4
#elif XPAR_XISF_INTERFACE_PSSPI
#define XISF_SPI_PRESCALER XSPIPS_CLK_PRESCALE_8
#elif XPAR_XISF_INTERFACE_AXISPI
@ -765,6 +772,8 @@ typedef XSpi XIsf_Iface;
typedef XSpiPs XIsf_Iface;
#elif XPAR_XISF_INTERFACE_PSQSPI
typedef XQspiPs XIsf_Iface;
#elif XPAR_XISF_INTERFACE_QSPIPSU
typedef XQspiPsu XIsf_Iface;
#endif
typedef void (*XIsf_StatusHandler) (void *CallBackRef, u32 StatusEvent,
unsigned int ByteCount);
@ -788,7 +797,8 @@ typedef struct {
* 0 - Default/Normal Addressing Mode
* 1 - Power-Of-2 Addressing Mode */
u16 DeviceCode; /**< The Serial Flash Device Code */
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
u8 DeviceIDMemSize; /**< Byte of device ID indicating the memory
* size */
u8 NumDie; /**< No. of die forming a single flash */
@ -807,21 +817,36 @@ typedef struct {
u8 FourByteAddrMode; /**< In four byte address mode flag */
int (*XIsf_Iface_SetOptions)
(XIsf_Iface *InstancePtr, u32 Options);
#ifndef XPAR_XISF_INTERFACE_PSQSPI
#if (!defined (XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined (XPAR_XISF_INTERFACE_QSPIPSU))
int (*XIsf_Iface_SetSlaveSelect)
(XIsf_Iface *InstancePtr, u8 SlaveMask);
#else
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
void (*XIsf_Iface_SetSlaveSelect)
(XIsf_Iface *InstancePtr, u8 FlashCS, u8 FlashBus);
#else
int (*XIsf_Iface_SetSlaveSelect)
(XIsf_Iface *InstancePtr);
#endif
#endif
int (*XIsf_Iface_Start)
(XIsf_Iface *InstancePtr);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
int (*XIsf_Iface_Transfer)
(XIsf_Iface *InstancePtr, XQspiPsu_Msg *Msg,
u32 NumMsg);
int (*XIsf_Iface_PolledTransfer)
(XIsf_Iface *InstancePtr, XQspiPsu_Msg *Msg,
u32 NumMsg);
#else
int (*XIsf_Iface_Transfer)
(XIsf_Iface *InstancePtr, u8 *SendBufPtr,
u8 *RecvBufPtr, unsigned int ByteCount);
int (*XIsf_Iface_PolledTransfer)
(XIsf_Iface *InstancePtr, u8 *SendBufPtr,
u8 *RecvBufPtr, unsigned ByteCount);
#endif
int (*XIsf_Iface_SetClkPrescaler)
(XIsf_Iface *InstancePtr, u8 PreScaler);
XIsf_StatusHandler StatusHandler;
@ -986,7 +1011,8 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation,
int XIsf_Erase(XIsf *InstancePtr, XIsf_EraseOperation Operation, u32 Address);
#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
defined(XPAR_XISF_INTERFACE_AXISPI))
(defined(XPAR_XISF_INTERFACE_AXISPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)))
/*
* Function for entering into 4 byte mode for Micron flash.
*/

View file

@ -92,6 +92,7 @@
* 5.2 asa 05/12/15 Added APIs to support 4 byte addressing for Micron flash.
* 2 APIs were added, one to enter into 4 byte mode and the other
* to exit from the same.
* 5.4 sk 08/07/17 Added QSPIPSU flash interface support for ZynqMP.
*
* </pre>
*
@ -103,6 +104,8 @@
/************************** Constant Definitions *****************************/
#define SIXTEENMB 0x1000000 /**< Sixteen MB */
/**************************** Type Definitions *******************************/
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
@ -123,7 +126,8 @@ typedef struct {
|| (XPAR_XISF_FLASH_FAMILY == SST) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI))) \
((!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU))))
/**
* The following structure specifies the geometry of the Intel/STM Serial Flash.
*/
@ -139,11 +143,13 @@ typedef struct {
(XPAR_XISF_FLASH_FAMILY == SST) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))*/
((!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU))))*/
#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI))
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined(XPAR_XISF_INTERFACE_QSPIPSU)))
/**
* The following structure specifies the geometry of the Spansion/Micron
* Serial Flash.
@ -171,7 +177,8 @@ typedef struct {
#endif /* (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI)) */
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined(XPAR_XISF_INTERFACE_QSPIPSU)))*/
/***************** Macros (Inline Functions) Definitions *********************/
@ -193,23 +200,27 @@ static int AtmelFlashInitialize(XIsf *InstancePtr, u8 *ReadBuf);
#if (((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
(XPAR_XISF_FLASH_FAMILY == SST) || (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))
((!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU))))
static int IntelStmFlashInitialize(XIsf *InstancePtr, u8 *ReadBuf);
#endif /* (((XPAR_XISF_FLASH_FAMILY == INTEL) || \
(XPAR_XISF_FLASH_FAMILY == STM) || \
(XPAR_XISF_FLASH_FAMILY == SST) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI))) */
((!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU)))) */
#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI))
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined(XPAR_XISF_INTERFACE_QSPIPSU)))
static int SpaMicWinFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr);
#endif /* (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI)) */
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined(XPAR_XISF_INTERFACE_QSPIPSU))) */
/************************** Variable Definitions *****************************/
@ -250,7 +261,8 @@ static const AtmelDeviceGeometry AtmelDevices[] = {
|| (XPAR_XISF_FLASH_FAMILY == SST) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))
((!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU))))
static const IntelStmDeviceGeometry IntelStmDevices[] = {
{XISF_MANUFACTURER_ID_INTEL, XISF_INTEL_DEV_S3316MBIT,
XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
@ -401,11 +413,13 @@ static const IntelStmDeviceGeometry IntelStmDevices[] = {
|| (XPAR_XISF_FLASH_FAMILY == SST) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))*/
((!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU))))*/
#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI))
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)))
static const SpaMicWinDeviceGeometry SpaMicWinDevices[] = {
{0x10000, 0x100, 256, 0x10000, 0x1000000,
XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_128,
@ -485,7 +499,8 @@ static const SpaMicWinDeviceGeometry SpaMicWinDevices[] = {
};
#endif /* (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI)) */
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU))) */
/*
* The following variables are shared between non-interrupt processing and
@ -620,7 +635,8 @@ int XIsf_Initialize(XIsf *InstancePtr, XIsf_Iface *SpiInstPtr, u8 SlaveSelect,
|| (XPAR_XISF_FLASH_FAMILY == SST) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))
((!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU))))
/*
* Check for Intel/STM/Winbond/Spansion Serial Flash.
@ -631,16 +647,19 @@ int XIsf_Initialize(XIsf *InstancePtr, XIsf_Iface *SpiInstPtr, u8 SlaveSelect,
|| (XPAR_XISF_FLASH_FAMILY == SST) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))*/
((!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU))))*/
#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI))
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined(XPAR_XISF_INTERFACE_QSPIPSU)))
Status = SpaMicWinFlashInitialize(InstancePtr, ReadBuf);
#endif /*(((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI)) */
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined(XPAR_XISF_INTERFACE_QSPIPSU))) */
return Status;
}
@ -712,6 +731,10 @@ int XIsf_GetStatus(XIsf *InstancePtr, u8 *ReadPtr)
{
int Status;
u8 Mode;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
u8* NULLPtr = NULL;
#endif
if (InstancePtr == NULL) {
return (int)(XST_FAILURE);
@ -725,6 +748,7 @@ int XIsf_GetStatus(XIsf *InstancePtr, u8 *ReadPtr)
return (int)(XST_FAILURE);
}
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Prepare the Write Buffer.
*/
@ -736,6 +760,30 @@ int XIsf_GetStatus(XIsf *InstancePtr, u8 *ReadPtr)
*/
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, ReadPtr,
XISF_STATUS_RDWR_BYTES);
#else
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_STATUSREG_READ;
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = ReadPtr;
FlashMsg[1].ByteCount = 2;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XQSPIPSU_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
/*
* Initiate the Transfer.
*/
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
#endif
/*
* Get the Transfer Mode
*/
@ -774,6 +822,10 @@ int XIsf_GetStatusReg2(XIsf *InstancePtr, u8 *ReadPtr)
{
int Status;
u8 Mode;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
#endif
u8* NULLPtr = NULL;
if (InstancePtr == NULL) {
return (int)(XST_FAILURE);
@ -787,6 +839,7 @@ int XIsf_GetStatusReg2(XIsf *InstancePtr, u8 *ReadPtr)
return (int)(XST_FAILURE);
}
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Prepare the Write Buffer.
*/
@ -798,6 +851,29 @@ int XIsf_GetStatusReg2(XIsf *InstancePtr, u8 *ReadPtr)
*/
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, ReadPtr,
XISF_STATUS_RDWR_BYTES);
#else
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_STATUSREG_READ;
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = ReadPtr;
FlashMsg[1].ByteCount = 2;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XQSPIPSU_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
/*
* Initiate the Transfer.
*/
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
#endif
/*
* Get the Transfer Mode
*/
@ -836,6 +912,10 @@ int XIsf_GetDeviceInfo(XIsf *InstancePtr, u8 *ReadPtr)
{
int Status;
u8 Mode;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
u8* NULLPtr = NULL;
#endif
if (InstancePtr == NULL) {
return (int)(XST_FAILURE);
@ -849,6 +929,7 @@ int XIsf_GetDeviceInfo(XIsf *InstancePtr, u8 *ReadPtr)
return (int)(XST_FAILURE);
}
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Prepare the Write Buffer.
*/
@ -863,6 +944,26 @@ int XIsf_GetDeviceInfo(XIsf *InstancePtr, u8 *ReadPtr)
*/
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
ReadPtr, XISF_INFO_READ_BYTES);
#else
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_ISFINFO_READ;
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = ReadPtr;
FlashMsg[1].ByteCount = 5;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
/*
* Initiate the Transfer.
*/
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
#endif
/*
* Get the Transfer Mode
*/
@ -904,6 +1005,10 @@ int XIsf_WriteEnable(XIsf *InstancePtr, u8 WriteEnable)
u8 Mode;
u8 WriteEnableBuf[1] = {0};
u8 * NULLPtr = NULL;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
#endif
#if ((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION) || (XPAR_XISF_FLASH_FAMILY == SST))
@ -930,11 +1035,25 @@ int XIsf_WriteEnable(XIsf *InstancePtr, u8 WriteEnable)
Xil_AssertNonvoid(NULLPtr == NULL);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = WriteEnableBuf;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
/*
* Initiate the Transfer.
*/
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 1);
#else
/*
* Initiate the Transfer.
*/
Status = XIsf_Transfer(InstancePtr, WriteEnableBuf, NULLPtr,
XISF_CMD_WRITE_ENABLE_DISABLE_BYTES);
#endif
/*
* Get the Transfer Mode
@ -986,6 +1105,9 @@ int XIsf_Ioctl(XIsf *InstancePtr, XIsf_IoctlOperation Operation)
int Status;
u8 Mode;
u8* NULLPtr = NULL;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
#endif
#if ((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
@ -1035,11 +1157,26 @@ int XIsf_Ioctl(XIsf *InstancePtr, XIsf_IoctlOperation Operation)
Xil_AssertNonvoid(NULLPtr == NULL);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = NumBytes;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
/*
* Initiate the Transfer.
*/
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 1);
#else
/*
* Initiate the Transfer.
*/
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULLPtr,
NumBytes);
#endif
/*
* Get the Transfer Mode
*/
@ -1084,17 +1221,17 @@ int XIsf_Ioctl(XIsf *InstancePtr, XIsf_IoctlOperation Operation)
******************************************************************************/
int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr, u32 ByteCount)
{
int Status;
int Status = XST_SUCCESS;
/*
* Select the Serial Flash as a slave.
*/
#ifndef XPAR_XISF_INTERFACE_PSQSPI
#ifdef XPAR_XISF_INTERFACE_PSQSPI
Status = InstancePtr->XIsf_Iface_SetSlaveSelect(
InstancePtr->SpiInstPtr,InstancePtr->SpiSlaveSelect);
#else
InstancePtr->SpiInstPtr);
#elif (!defined(XPAR_XISF_INTERFACE_QSPIPSU))
Status = InstancePtr->XIsf_Iface_SetSlaveSelect(
InstancePtr->SpiInstPtr);
InstancePtr->SpiInstPtr,InstancePtr->SpiSlaveSelect);
#endif
if (Status != (int)(XST_SUCCESS)) {
return (int)(XST_FAILURE);
@ -1123,22 +1260,36 @@ int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr, u32 ByteCount)
#endif
if (InstancePtr->IntrMode == XISF_INTERRUPT_MODE) {
#if defined(XPAR_XISF_INTERFACE_PSQSPI) || defined(XPAR_XISF_INTERFACE_PSSPI)
#if defined(XPAR_XISF_INTERFACE_PSQSPI) || defined(XPAR_XISF_INTERFACE_PSSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
XIsf_TransferInProgress = TRUE;
#endif
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
Status = InstancePtr->XIsf_Iface_Transfer(
InstancePtr->SpiInstPtr,
InstancePtr->SpiInstPtr->Msg, ByteCount);
#else
Status = InstancePtr->XIsf_Iface_Transfer(
InstancePtr->SpiInstPtr,
WritePtr, ReadPtr, ByteCount);
#if defined(XPAR_XISF_INTERFACE_PSQSPI) || defined(XPAR_XISF_INTERFACE_PSSPI)
#endif
#if defined(XPAR_XISF_INTERFACE_PSQSPI) || defined(XPAR_XISF_INTERFACE_PSSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
while (XIsf_TransferInProgress != 0){
/*NOP*/
}
#endif
} else {
#if XPAR_XISF_INTERFACE_QSPIPSU
Status = InstancePtr->XIsf_Iface_PolledTransfer(
InstancePtr->SpiInstPtr,
InstancePtr->SpiInstPtr->Msg, ByteCount);
#else
Status = InstancePtr->XIsf_Iface_PolledTransfer(
InstancePtr->SpiInstPtr,
WritePtr, ReadPtr, ByteCount);
#endif
}
if (Status != (int)(XST_SUCCESS)) {
@ -1173,6 +1324,12 @@ void XIsf_RegisterInterface(XIsf *InstancePtr)
InstancePtr->XIsf_Iface_Transfer = XSpiPs_Transfer;
InstancePtr->XIsf_Iface_PolledTransfer = XSpiPs_PolledTransfer;
InstancePtr->XIsf_Iface_SetClkPrescaler = XSpiPs_SetClkPrescaler;
#elif XPAR_XISF_INTERFACE_QSPIPSU
InstancePtr->XIsf_Iface_SetOptions = XQspiPsu_SetOptions;
InstancePtr->XIsf_Iface_SetSlaveSelect = XQspiPsu_SelectFlash;
InstancePtr->XIsf_Iface_Transfer = XQspiPsu_InterruptTransfer;
InstancePtr->XIsf_Iface_PolledTransfer = XQspiPsu_PolledTransfer;
InstancePtr->XIsf_Iface_SetClkPrescaler = XQspiPsu_SetClkPrescaler;
#elif XPAR_XISF_INTERFACE_PSQSPI
InstancePtr->XIsf_Iface_SetOptions = XQspiPs_SetOptions;
InstancePtr->XIsf_Iface_SetSlaveSelect = XQspiPs_SetSlaveSelect;
@ -1331,7 +1488,8 @@ static int AtmelFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr)
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
defined(XPAR_XISF_INTERFACE_AXISPI))
(defined(XPAR_XISF_INTERFACE_AXISPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)))
/*****************************************************************************/
/**
*
@ -1352,6 +1510,11 @@ int XIsf_MicronFlashEnter4BAddMode(XIsf *InstancePtr)
int Status;
u8* NULLPtr = NULL;
u8 Mode;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
u8 FlashMake, ReadStatusCmd, FSRFlag;
u8 FlashStatus[2] = {0};
#endif
if (InstancePtr == NULL) {
return (int)(XST_FAILURE);
@ -1367,8 +1530,83 @@ int XIsf_MicronFlashEnter4BAddMode(XIsf *InstancePtr)
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_ENTER_4BYTE_ADDR_MODE;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Enable write before transfer
*/
Status = XIsf_WriteEnable(InstancePtr, XISF_WRITE_ENABLE);
if (Status != (int)XST_SUCCESS) {
return (int)XST_FAILURE;
}
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 1);
if (Status != (int)(XST_SUCCESS)) {
return (int)(XST_FAILURE);
}
if((InstancePtr->NumDie > (u8)1) &&
(FlashMake == (u32)XISF_MANUFACTURER_ID_MICRON)) {
ReadStatusCmd = READ_FLAG_STATUS_CMD;
FSRFlag = 1;
} else {
ReadStatusCmd = READ_STATUS_CMD;
FSRFlag = 0;
}
while (1) {
FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = FlashStatus;
FlashMsg[1].ByteCount = 2;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
if(FSRFlag) {
FlashStatus[1] &= FlashStatus[0];
} else {
FlashStatus[1] |= FlashStatus[0];
}
}
if(FSRFlag) {
if ((FlashStatus[1] & 0x80) != 0) {
break;
}
} else {
if ((FlashStatus[1] & 0x01) == 0) {
break;
}
}
}
#else
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
NULLPtr, XISF_CMD_4BYTE_ADDR_ENTER_EXIT_BYTES);
#endif
Mode = XIsf_GetTransferMode(InstancePtr);
@ -1405,6 +1643,11 @@ int XIsf_MicronFlashExit4BAddMode(XIsf *InstancePtr)
int Status;
u8* NULLPtr = NULL;
u8 Mode;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
u8 FlashMake, ReadStatusCmd, FSRFlag;
u8 FlashStatus[2] = {0};
#endif
if (InstancePtr == NULL) {
return (int)(XST_FAILURE);
@ -1420,8 +1663,82 @@ int XIsf_MicronFlashExit4BAddMode(XIsf *InstancePtr)
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_EXIT_4BYTE_ADDR_MODE;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Enable write before transfer
*/
Status = XIsf_WriteEnable(InstancePtr, XISF_WRITE_ENABLE);
if (Status != (int)XST_SUCCESS) {
return (int)XST_FAILURE;
}
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 1);
if (Status != (int)(XST_SUCCESS)) {
return (int)(XST_FAILURE);
}
if((InstancePtr->NumDie > (u8)1) &&
(FlashMake == (u32)XISF_MANUFACTURER_ID_MICRON)) {
ReadStatusCmd = READ_FLAG_STATUS_CMD;
FSRFlag = 1;
} else {
ReadStatusCmd = READ_STATUS_CMD;
FSRFlag = 0;
}
while (1) {
FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = FlashStatus;
FlashMsg[1].ByteCount = 2;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
if(FSRFlag) {
FlashStatus[1] &= FlashStatus[0];
} else {
FlashStatus[1] |= FlashStatus[0];
}
}
if(FSRFlag) {
if ((FlashStatus[1] & 0x80) != 0) {
break;
}
} else {
if ((FlashStatus[1] & 0x01) == 0) {
break;
}
}
}
#else
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
NULLPtr, XISF_CMD_4BYTE_ADDR_ENTER_EXIT_BYTES);
#endif
Mode = XIsf_GetTransferMode(InstancePtr);
@ -1437,12 +1754,14 @@ int XIsf_MicronFlashExit4BAddMode(XIsf *InstancePtr)
return Status;
}
#endif /* ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
defined(XPAR_XISF_INTERFACE_AXISPI)) */
(defined(XPAR_XISF_INTERFACE_AXISPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)))*/
#if (((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
(XPAR_XISF_FLASH_FAMILY == SST) || (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))
(!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU)))
/*****************************************************************************/
/**
*
@ -1526,11 +1845,13 @@ static int IntelStmFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr)
|| (XPAR_XISF_FLASH_FAMILY == SST) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))*/
(!defined(XPAR_XISF_INTERFACE_PSQSPI)) && \
(!defined(XPAR_XISF_INTERFACE_QSPIPSU)))*/
#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI))
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)))
/*****************************************************************************/
/**
*
@ -1560,6 +1881,31 @@ static int SpaMicWinFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr)
u8 * WriteBfrPtr = InstancePtr->WriteBufPtr;
int Status;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
u8* NULLPtr = NULL;
XQspiPsu_Msg FlashMsg[2];
/*
* Read ID
*/
*WriteBfrPtr = READ_ID;
FlashMsg[0].TxBfrPtr = WriteBfrPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = BufferPtr;
FlashMsg[1].ByteCount = 3;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
BufferPtr[1] = BufferPtr[0];
BufferPtr[3] = BufferPtr[2];
#else
/*
* Read ID in Auto mode.
*/
@ -1570,6 +1916,7 @@ static int SpaMicWinFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr)
Status = XIsf_Transfer(InstancePtr, WriteBfrPtr, BufferPtr,
RD_ID_SIZE);
#endif
if (Status != (int)(XST_SUCCESS)) {
return (int)(XST_FAILURE);
}
@ -1717,11 +2064,38 @@ static int SpaMicWinFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr)
InstancePtr->NumSectors = SpaMicWinDevices[XIsf_FCTIndex].NumSect;
InstancePtr->IsReady = TRUE;
#if (XPAR_XISF_FLASH_FAMILY == SPANSION) && \
defined(XPAR_XISF_INTERFACE_QSPIPSU)
/*
* This will put the flash in 4Byte Addressing mode. Exit from
* 4Byte has to take care by the user if required.
*/
if (SpaMicWinDevices[XIsf_FCTIndex].FlashDeviceSize > SIXTEENMB) {
if (InstancePtr->SpiInstPtr->Config.ConnectionMode == XISF_QSPIPS_CONNECTION_MODE_PARALLEL) {
InstancePtr->XIsf_Iface_SetSlaveSelect(InstancePtr->SpiInstPtr,
XQSPIPSU_SELECT_FLASH_CS_UPPER, XQSPIPSU_SELECT_FLASH_BUS_UPPER);
Status = XIsf_MicronFlashEnter4BAddMode(InstancePtr);
}
InstancePtr->XIsf_Iface_SetSlaveSelect(InstancePtr->SpiInstPtr,
XQSPIPSU_SELECT_FLASH_CS_LOWER, XQSPIPSU_SELECT_FLASH_BUS_LOWER);
Status = XIsf_MicronFlashEnter4BAddMode(InstancePtr);
if (InstancePtr->SpiInstPtr->Config.ConnectionMode == XISF_QSPIPS_CONNECTION_MODE_STACKED) {
InstancePtr->XIsf_Iface_SetSlaveSelect(InstancePtr->SpiInstPtr,
XQSPIPSU_SELECT_FLASH_CS_UPPER, XQSPIPSU_SELECT_FLASH_BUS_LOWER);
Status = XIsf_MicronFlashEnter4BAddMode(InstancePtr);
}
if (Status != (int)(XST_SUCCESS)) {
return (int)(XST_FAILURE);
}
}
#endif
return (int)(XST_SUCCESS);
}
#endif /* (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
defined(XPAR_XISF_INTERFACE_PSQSPI))*/
(defined(XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)))*/
/*****************************************************************************/
/**
@ -1742,26 +2116,36 @@ u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address)
{
u32 LqspiCr;
u32 RealAddr = {0};
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
switch(QspiPtr->Config.ConnectionMode) {
case XISF_QSPIPS_CONNECTION_MODE_SINGLE:
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_SelectFlash(QspiPtr, XQSPIPSU_SELECT_FLASH_CS_LOWER,
XQSPIPSU_SELECT_FLASH_BUS_LOWER);
#endif
RealAddr = Address;
break;
case XISF_QSPIPS_CONNECTION_MODE_STACKED:
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Get the current LQSPI Config reg value
*/
LqspiCr = XQspiPs_GetLqspiConfigReg(QspiPtr);
#endif
/* Select lower or upper Flash based on sector address */
if(Address &
SpaMicWinDevices[XIsf_FCTIndex].FlashDeviceSize) {
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_SelectFlash(QspiPtr,
XQSPIPSU_SELECT_FLASH_CS_UPPER, XQSPIPSU_SELECT_FLASH_BUS_LOWER);
#else
/*
* Set selection to U_PAGE
*/
XQspiPs_SetLqspiConfigReg(QspiPtr,
LqspiCr | XQSPIPS_LQSPI_CR_U_PAGE_MASK);
#endif
/*
* Subtract first flash size when accessing second
* flash.
@ -1771,25 +2155,36 @@ u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address)
}
else{
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_SelectFlash(QspiPtr,
XQSPIPSU_SELECT_FLASH_CS_LOWER, XQSPIPSU_SELECT_FLASH_BUS_LOWER);
#else
/*
* Set selection to L_PAGE
*/
XQspiPs_SetLqspiConfigReg(QspiPtr,
LqspiCr & (~XQSPIPS_LQSPI_CR_U_PAGE_MASK));
#endif
RealAddr = Address;
}
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Assert the Flash chip select.
*/
(void)XQspiPs_SetSlaveSelect(QspiPtr);
#endif
break;
case XISF_QSPIPS_CONNECTION_MODE_PARALLEL:
/*
* The effective address in each flash is the actual
* address / 2
*/
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_SelectFlash(QspiPtr,
XQSPIPSU_SELECT_FLASH_CS_BOTH, XQSPIPSU_SELECT_FLASH_BUS_BOTH);
#endif
RealAddr = Address / 2;
break;
default:
@ -1914,7 +2309,10 @@ void XIsf_SetStatusHandler(XIsf *InstancePtr, XIsf_Iface *XIfaceInstancePtr,
* the QSPI driver instance as the callback reference so the handler
* is able to access the instance data
*/
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_SetStatusHandler(XIfaceInstancePtr, XIfaceInstancePtr,
(XQspiPsu_StatusHandler) XIsf_IfaceHandler);
#elif XPAR_XISF_INTERFACE_PSQSPI
XQspiPs_SetStatusHandler(XIfaceInstancePtr, XIfaceInstancePtr,
(XQspiPs_StatusHandler) XIsf_IfaceHandler);
#elif XPAR_XISF_INTERFACE_PSSPI

View file

@ -58,6 +58,7 @@
* BulkErase()
* 5.2 asa 05/12/15 Added support for Micron (N25Q256A) flash part
* which supports 4 byte addressing.
* 5.4 sk 08/07/17 Added QSPIPSU flash interface support for ZynqMP.
* </pre>
*
******************************************************************************/
@ -84,7 +85,8 @@ static int PageErase(XIsf *InstancePtr, u32 Address);
static int BlockErase(XIsf *InstancePtr, u32 Address);
static int SectorErase(XIsf *InstancePtr, u32 Address);
static int BulkErase(XIsf *InstancePtr);
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
static int DieErase(XIsf *InstancePtr);
#endif
/************************** Variable Definitions *****************************/
@ -301,7 +303,14 @@ static int SectorErase(XIsf *InstancePtr, u32 Address)
u8 FlashStatus[2] = {0};
u8 ReadStatusCmdBuf[] = { READ_STATUS_CMD, 0 };
u8 ReadFlagSRCmd[] = {READ_FLAG_STATUS_CMD, 0};
#ifdef XPAR_XISF_INTERFACE_PSQSPI
u8 *WriteBfrPtr = InstancePtr->WriteBufPtr;
u8 FSRFlag, ReadStatusCmd;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
#endif
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
u32 FlashMake = InstancePtr->ManufacturerID;
#endif
@ -357,18 +366,26 @@ static int SectorErase(XIsf *InstancePtr, u32 Address)
InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
InstancePtr->WriteBufPtr[BYTE5] = (u8) (RealAddr);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].ByteCount = 5;
#endif
} else {
#endif
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SECTOR_ERASE;
InstancePtr->WriteBufPtr[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].ByteCount = 4;
#endif
#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))
}
#endif
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
/*
* Enable write before transfer
*/
@ -377,6 +394,16 @@ static int SectorErase(XIsf *InstancePtr, u32 Address)
return (int)XST_FAILURE;
}
#endif
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 1);
#else
if (InstancePtr->FourByteAddrMode == TRUE) {
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
NULLPtr, XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE);
@ -384,22 +411,73 @@ static int SectorErase(XIsf *InstancePtr, u32 Address)
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
NULLPtr, XISF_CMD_SEND_EXTRA_BYTES);
}
#endif
if (Status != (int)XST_SUCCESS) {
return (int)XST_FAILURE;
}
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
if((InstancePtr->NumDie > (u8)1) &&
(FlashMake == (u32)XISF_MANUFACTURER_ID_MICRON)) {
ReadStatusCmd = READ_FLAG_STATUS_CMD;
FSRFlag = 1;
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
Status = XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
(u32)sizeof(ReadFlagSRCmd));
#endif
} else {
ReadStatusCmd = READ_STATUS_CMD;
FSRFlag = 0;
}
/*
* Wait for the sector erase command to the Flash to be completed
*/
while (1) {
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = FlashStatus;
FlashMsg[1].ByteCount = 2;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
if(FSRFlag) {
FlashStatus[1] &= FlashStatus[0];
} else {
FlashStatus[1] |= FlashStatus[0];
}
}
if(FSRFlag) {
if ((FlashStatus[1] & 0x80) != 0) {
break;
}
} else {
if ((FlashStatus[1] & 0x01) == 0) {
break;
}
}
#else
/*
* Poll the status register of the device to determine
* when it completes, by sending a read status command
@ -419,8 +497,10 @@ static int SectorErase(XIsf *InstancePtr, u32 Address)
if ((FlashStatus[1] & 0x01) == 0) {
break;
}
#endif
}
#ifdef XPAR_XISF_INTERFACE_PSQSPI
if((InstancePtr->NumDie > (u8)1) &&
(FlashMake == (u32)XISF_MANUFACTURER_ID_MICRON)) {
@ -428,6 +508,7 @@ static int SectorErase(XIsf *InstancePtr, u32 Address)
XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
(u32)sizeof(ReadFlagSRCmd));
}
#endif
#endif
return Status;
@ -452,12 +533,16 @@ static int BulkErase(XIsf *InstancePtr)
{
int Status = (int)(XST_FAILURE);
u8* NULLPtr = NULL;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
#endif
#if ((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
(XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == SST) \
|| (XPAR_XISF_FLASH_FAMILY == SPANSION))
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
/*
* If the number of die is greater than 1 call die erase
*/
@ -478,13 +563,25 @@ static int BulkErase(XIsf *InstancePtr)
}
Xil_AssertNonvoid(NULLPtr == NULL);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 1);
#else
/*
* Initiate the Transfer.
*/
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
NULLPtr, XISF_BULK_ERASE_BYTES);
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#endif
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
}
#endif
#endif /* ((XPAR_XISF_FLASH_FAMILY==INTEL)||(XPAR_XISF_FLASH_FAMILY==STM)) \
@ -495,7 +592,8 @@ static int BulkErase(XIsf *InstancePtr)
return Status;
}
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
/*****************************************************************************/
/**
*
@ -514,6 +612,13 @@ static int DieErase(XIsf *InstancePtr)
{
int Status = (int)(XST_FAILURE);
u8* NULLPtr = NULL;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
u8 ReadStatusCmd, FSRFlag;
u32 FlashMake = InstancePtr->ManufacturerID;
u8 FlashStatus[2] = {0};
#endif
#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
(XPAR_XISF_FLASH_FAMILY == SPANSION))
@ -522,11 +627,13 @@ static int DieErase(XIsf *InstancePtr)
u8 FlagStatus[2] = {0};
for(DieCnt = 0; DieCnt < InstancePtr->NumDie; DieCnt++) {
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Select bank - the lower of the 2 banks in each die
* This is specific to Micron flash
*/
Status = SendBankSelect(InstancePtr, DieCnt*2);
#endif
/*
* Setup the write command with the specified address and data
@ -552,7 +659,24 @@ static int DieErase(XIsf *InstancePtr)
}
Xil_AssertNonvoid(NULLPtr == NULL);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = BYTE5;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 1);
if((InstancePtr->NumDie > (u8)1) &&
(FlashMake == (u32)XISF_MANUFACTURER_ID_MICRON)) {
ReadStatusCmd = READ_FLAG_STATUS_CMD;
FSRFlag = 1;
} else {
ReadStatusCmd = READ_STATUS_CMD;
FSRFlag = 0;
}
#else
/*
* Send the sector erase command and address; no receive buffer
* is specified since there is nothing to receive
@ -560,11 +684,54 @@ static int DieErase(XIsf *InstancePtr)
Status =
XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULLPtr,
DIE_ERASE_SIZE);
#endif
/*
* Wait for the sector erase command to Flash to be completed
*/
while (1) {
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = FlashStatus;
FlashMsg[1].ByteCount = 2;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
InstancePtr->SpiInstPtr->Msg = FlashMsg;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
if(FSRFlag) {
FlashStatus[1] &= FlashStatus[0];
} else {
FlashStatus[1] |= FlashStatus[0];
}
}
if(FSRFlag) {
if ((FlashStatus[1] & 0x80) != 0) {
break;
}
} else {
if ((FlashStatus[1] & 0x01) == 0) {
break;
}
}
#else
/*
* Poll the status register of the device to determine
@ -585,6 +752,7 @@ static int DieErase(XIsf *InstancePtr)
if ((FlagStatus[1] & (u8)0x80) == (u8)0x80) {
break;
}
#endif
}
}

View file

@ -57,6 +57,7 @@
* which supports 4 byte addressing.
* 5.3 sk 06/01/15 Used Half of Actual byte count for calculating
* Real Byte count in parallel mode. CR# 859979.
* 5.4 sk 08/07/17 Added QSPIPSU flash interface support for ZynqMP.
* </pre>
*
******************************************************************************/
@ -371,6 +372,14 @@ static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
u32 LocalAddress = Address;
u32 TempByteCnt = LocalByteCnt;
u8 WriteBuffer[10] = {0};
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
u32 DieSize, BusWidth, DieTempData;
u8 DiscardByteCnt;
int DieNo;
u8 * NULLPtr = NULL;
XQspiPsu_Msg FlashMsg[3];
#endif
if (LocalByteCnt <= 0 ) {
return (int)XST_FAILURE;
}
@ -387,6 +396,23 @@ static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
*/
RealAddr = GetRealAddr(InstancePtr->SpiInstPtr, LocalAddress);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
DieNo = RealAddr/DieSize;
DieTempData = (DieSize * (DieNo+1)) - (RealAddr);
if (InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL) {
DieTempData = DieTempData*2;
}
/* For Dual Stacked, split and read for boundary crossing */
if(LocalByteCnt > DieTempData) {
RealByteCnt = DieTempData;
} else {
#endif
#ifdef XPAR_XISF_INTERFACE_PSQSPI
if(InstancePtr->DeviceIDMemSize > 0x18U) {
@ -412,7 +438,7 @@ static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
}
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XQSPIPS_CONNECTION_MODE_PARALLEL) {
XISF_QSPIPS_CONNECTION_MODE_PARALLEL) {
TempByteCnt = LocalByteCnt/2;
}
@ -428,7 +454,8 @@ static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
#endif
RealByteCnt = LocalByteCnt;
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
}
#endif
#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
@ -439,16 +466,43 @@ static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
WriteBuffer[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
WriteBuffer[BYTE4] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
WriteBuffer[BYTE5] = (u8) (RealAddr);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
DiscardByteCnt = 5;
#endif
} else {
#endif
WriteBuffer[BYTE1] = XISF_CMD_RANDOM_READ;
WriteBuffer[BYTE2] = (u8)((RealAddr & 0xFF0000) >> XISF_ADDR_SHIFT16);
WriteBuffer[BYTE3] = (u8)((RealAddr & 0xFF00) >> XISF_ADDR_SHIFT8);
WriteBuffer[BYTE4] = (u8)(RealAddr & 0xFF);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
DiscardByteCnt = 4;
#endif
#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))
}
#endif
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = WriteBuffer;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = DiscardByteCnt;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = ReadPtr;
FlashMsg[1].ByteCount = RealByteCnt;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
#else
if (InstancePtr->FourByteAddrMode == TRUE) {
Status = XIsf_Transfer(InstancePtr, WriteBuffer,
&(ReadPtr[TotalByteCnt - LocalByteCnt]),
@ -458,10 +512,16 @@ static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
&(ReadPtr[TotalByteCnt - LocalByteCnt]),
RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES);
}
#endif
if (Status != (int)(XST_SUCCESS)) {
return (int)XST_FAILURE;
}
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
LocalAddress += RealByteCnt;
ReadPtr += RealByteCnt;
#endif
#ifdef XPAR_XISF_INTERFACE_PSQSPI
/*
* To discard the first 4 dummy bytes, shift the data in read buffer
@ -538,6 +598,14 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
u32 LocalAddress = Address;
u32 TempByteCnt = LocalByteCnt;
u8 WriteBuffer[5]= {0};
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
u32 DieSize, BusWidth, DieTempData;
u32 FlashMsgCnt;
u8 DiscardByteCnt;
int DieNo;
u8 * NULLPtr = NULL;
XQspiPsu_Msg FlashMsg[3];
#endif
if (LocalByteCnt <= 0 ) {
return (int)XST_FAILURE;
@ -559,6 +627,23 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
*/
RealAddr = GetRealAddr(InstancePtr->SpiInstPtr, LocalAddress);
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
DieNo = RealAddr/DieSize;
DieTempData = (DieSize * (DieNo+1)) - (RealAddr);
if (InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL) {
DieTempData = DieTempData*2;
}
/* For Dual Stacked, split and read for boundary crossing */
if(LocalByteCnt > DieTempData) {
RealByteCnt = DieTempData;
} else {
#endif
#ifdef XPAR_XISF_INTERFACE_PSQSPI
if(InstancePtr->DeviceIDMemSize > 0x18U) {
/*
@ -583,7 +668,7 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
}
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XQSPIPS_CONNECTION_MODE_PARALLEL) {
XISF_QSPIPS_CONNECTION_MODE_PARALLEL) {
TempByteCnt = LocalByteCnt/2;
}
/*
@ -598,7 +683,8 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
#endif
RealByteCnt = LocalByteCnt;
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
}
#endif
#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
@ -609,24 +695,89 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
WriteBuffer[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
WriteBuffer[BYTE4] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
WriteBuffer[BYTE5] = (u8) RealAddr;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
DiscardByteCnt = 5;
#else
for (Index = 0; Index < NumDummyBytes; Index++) {
WriteBuffer[Index + BYTE5 + 1] = (u8) (XISF_DUMMYBYTE);
}
#endif
} else {
#endif
WriteBuffer[BYTE1] = Command;
WriteBuffer[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
WriteBuffer[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
WriteBuffer[BYTE4] = (u8) RealAddr;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
DiscardByteCnt = 4;
#else
for (Index = 0; Index < NumDummyBytes; Index++) {
WriteBuffer[Index + BYTE5] = (u8) (XISF_DUMMYBYTE);
}
#endif
#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))
}
#endif
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = WriteBuffer;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = DiscardByteCnt;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsgCnt = 1;
BusWidth = XQSPIPSU_SELECT_MODE_SPI;
/* It is recommended to have a separate entry for dummy */
if ((Command == XISF_CMD_FAST_READ) ||
(Command == XISF_CMD_DUAL_OP_FAST_READ) ||
(Command == XISF_CMD_QUAD_OP_FAST_READ) ||
(Command == XISF_CMD_FAST_READ_4BYTE) ||
(Command == XISF_CMD_DUAL_OP_FAST_READ_4B) ||
(Command == XISF_CMD_QUAD_OP_FAST_READ_4B)) {
/* Update Dummy cycles as per flash specs for QUAD IO */
/*
* It is recommended that Bus width value during dummy
* phase should be same as data phase
*/
if ((Command == XISF_CMD_FAST_READ) ||
(Command == XISF_CMD_FAST_READ_4BYTE)) {
BusWidth = XQSPIPSU_SELECT_MODE_SPI;
}
if ((Command == XISF_CMD_DUAL_OP_FAST_READ) ||
(Command == XISF_CMD_DUAL_OP_FAST_READ_4B)) {
BusWidth = XQSPIPSU_SELECT_MODE_DUALSPI;
}
if ((Command == XISF_CMD_QUAD_OP_FAST_READ) ||
(Command == XISF_CMD_QUAD_OP_FAST_READ_4B)) {
BusWidth = XQSPIPSU_SELECT_MODE_QUADSPI;
}
FlashMsg[1].BusWidth = BusWidth;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = NULL;
FlashMsg[1].ByteCount = 8;
FlashMsg[1].Flags = 0;
FlashMsgCnt++;
}
FlashMsg[FlashMsgCnt].BusWidth = BusWidth;
FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
FlashMsg[FlashMsgCnt].RxBfrPtr = ReadPtr;
FlashMsg[FlashMsgCnt].ByteCount = RealByteCnt;
FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
FlashMsg[FlashMsgCnt].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, FlashMsgCnt+1);
#else
RealByteCnt += NumDummyBytes;
if (InstancePtr->FourByteAddrMode == TRUE) {
Status = (int)XIsf_Transfer(InstancePtr, WriteBuffer,
@ -637,10 +788,17 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
&(ReadPtr[TotalByteCnt - LocalByteCnt]),
RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES);
}
#endif
if (Status != (int)(XST_SUCCESS)) {
return (int)(XST_FAILURE);
}
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
LocalAddress += RealByteCnt;
LocalByteCnt -= RealByteCnt;
ReadPtr += RealByteCnt;
#endif
#ifdef XPAR_XISF_INTERFACE_PSQSPI
/*
* To discard the first 5 dummy bytes, shift the data in read buffer
@ -658,10 +816,13 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
*/
LocalAddress = (LocalAddress & BANKMASK) + SIXTEENMB;
#endif
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
/*
* Decrease byte count by bytes already read.
*/
LocalByteCnt = LocalByteCnt - (RealByteCnt - NumDummyBytes);
#endif
}
return (int)XST_SUCCESS;

View file

@ -56,6 +56,7 @@
* XIsf_Write()
* 5.2 asa 05/12/15 Added support for Micron (N25Q256A) flash part
* which supports 4 byte addressing.
* 5.4 sk 08/07/17 Added QSPIPSU flash interface support for ZynqMP.
* </pre>
*
******************************************************************************/
@ -81,7 +82,7 @@ extern u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address);
extern int SendBankSelect(XIsf *InstancePtr, u32 BankSel);
#endif
static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
const u8 *BufferPtr, u32 ByteCount);
u8 *BufferPtr, u32 ByteCount);
static int AutoPageWrite(XIsf *InstancePtr, u32 Address);
static int BufferWrite(XIsf *InstancePtr, u8 BufferNum, const u8 *WritePtr,
u32 ByteOffset, u32 NumBytes);
@ -383,7 +384,7 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
*
******************************************************************************/
static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
const u8 *BufferPtr, u32 ByteCount)
u8 *BufferPtr, u32 ByteCount)
{
u8 Mode;
u32 Index;
@ -393,8 +394,14 @@ static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
u8 FlagStatus[2] = {0};
u8 FlashStatus[2] = {0};
u8 * NULLPtr = NULL;
const u8 * LocalBufPtr = BufferPtr;
#ifdef XPAR_XISF_INTERFACE_PSQSPI
u8 * LocalBufPtr = BufferPtr;
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
XQspiPsu_Msg FlashMsg[2];
u8 ReadStatusCmd, FSRFlag;
u32 CmdByteCount;
#endif
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
u32 FlashMake = InstancePtr->ManufacturerID;
#endif
u8 ReadStatusCmdBuf[] = { READ_STATUS_CMD, 0 };
@ -455,33 +462,65 @@ static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
InstancePtr->WriteBufPtr[BYTE5] = (u8) (RealAddr);
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
for(Index = 5U; Index < (ByteCount + XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE);
Index++) {
InstancePtr->WriteBufPtr[Index] = *LocalBufPtr;
LocalBufPtr += 1;
}
#else
CmdByteCount = 5;
#endif
} else {
#endif
InstancePtr->WriteBufPtr[BYTE1] = Command;
InstancePtr->WriteBufPtr[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr);
#ifndef XPAR_XISF_INTERFACE_QSPIPSU
for(Index = 4U; Index < (ByteCount + XISF_CMD_SEND_EXTRA_BYTES);
Index++) {
InstancePtr->WriteBufPtr[Index] = *LocalBufPtr;
LocalBufPtr += 1;
}
#else
CmdByteCount = 4;
#endif
#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
(!defined(XPAR_XISF_INTERFACE_PSQSPI)))
}
#endif
#ifdef XPAR_XISF_INTERFACE_PSQSPI
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
/*
* Enable write before transfer
*/
Status = XIsf_WriteEnable(InstancePtr, XISF_WRITE_ENABLE);
#endif
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = InstancePtr->WriteBufPtr;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = CmdByteCount;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = LocalBufPtr;
FlashMsg[1].RxBfrPtr = NULL;
FlashMsg[1].ByteCount = ByteCount;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
#else
if (InstancePtr->FourByteAddrMode == TRUE) {
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULLPtr,
(ByteCount + XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE));
@ -489,18 +528,29 @@ static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULLPtr,
(ByteCount + XISF_CMD_SEND_EXTRA_BYTES));
}
#endif
if (Status != (int)XST_SUCCESS) {
return (int)XST_FAILURE;
}
#ifdef XPAR_XISF_INTERFACE_PSQSPI
if((InstancePtr->NumDie > 1) &&
(FlashMake == XISF_MANUFACTURER_ID_MICRON)) {
#if defined (XPAR_XISF_INTERFACE_PSQSPI) || \
defined (XPAR_XISF_INTERFACE_QSPIPSU)
if((InstancePtr->NumDie > (u8)1) &&
(FlashMake == (u32)XISF_MANUFACTURER_ID_MICRON)) {
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
ReadStatusCmd = READ_FLAG_STATUS_CMD;
FSRFlag = 1;
#else
Status = XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
(u32)sizeof(ReadFlagSRCmd));
if(Status != (int)XST_SUCCESS){
return (int)XST_FAILURE;
}
#endif
} else {
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
ReadStatusCmd = READ_STATUS_CMD;
FSRFlag = 0;
#endif
}
/*
@ -508,6 +558,48 @@ static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
* some time for the data to be written
*/
while (1) {
#ifdef XPAR_XISF_INTERFACE_QSPIPSU
FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
FlashMsg[0].RxBfrPtr = NULL;
FlashMsg[0].ByteCount = 1;
FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
FlashMsg[1].TxBfrPtr = NULL;
FlashMsg[1].RxBfrPtr = FlashStatus;
FlashMsg[1].ByteCount = 2;
FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
}
InstancePtr->SpiInstPtr->Msg = FlashMsg;
Status = XIsf_Transfer(InstancePtr, NULLPtr, NULLPtr, 2);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
if(InstancePtr->SpiInstPtr->Config.ConnectionMode ==
XISF_QSPIPS_CONNECTION_MODE_PARALLEL){
if(FSRFlag) {
FlashStatus[1] &= FlashStatus[0];
} else {
FlashStatus[1] |= FlashStatus[0];
}
}
if(FSRFlag) {
if ((FlashStatus[1] & 0x80) != 0) {
break;
}
} else {
if ((FlashStatus[1] & 0x01) == 0) {
break;
}
}
#else
/*
* Poll the status register of the Flash to determine when it
* completes, by sending a read status command and receiving
@ -529,8 +621,10 @@ static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
if ((FlashStatus[1] & 0x01) == 0) {
break;
}
#endif
}
#ifdef XPAR_XISF_INTERFACE_PSQSPI
if((InstancePtr->NumDie > 1) &&
(FlashMake == XISF_MANUFACTURER_ID_MICRON)) {
Status = XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
@ -539,6 +633,7 @@ static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
return (int)XST_FAILURE;
}
}
#endif
#endif
return Status;