/* $Id: xflash.h,v 1.8 2002/05/13 19:57:06 moleres Exp $ */
/******************************************************************************
*
*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*       FOR A PARTICULAR PURPOSE.
*
*       (c) Copyright 2002 Xilinx Inc.
*       All rights reserved.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xflash.h
*
* This is the base component for XFlash. It provides the public
* interface which upper layers use to communicate with specific flash
* hardware.
*
* This driver supports "Common Flash Interface" (CFI) enabled flash hardware.
* CFI allows entire families of flash parts to be supported with a single
* driver sub-component.
*
* This driver is designed for devices external to the FPGA. As a result
* interfaces such as IPIF and versioning are not incorporated into its
* design. A more detailed description of the driver operation can be found
* in XFlash.c
*
* @note
*
* This driver is intended to be RTOS and processor independent. It
* works with physical addresses only. Any needs for dynamic memory
* management, threads, mutual exclusion, virtual memory, cache
* control, or HW write protection management must be satisfied by the
* layer above this driver.
* <br><br>
* All writes to flash occur in units of bus-width bytes. If more than one
* part exists on the data bus, then the parts are written in parallel.
* Reads from flash are performed in any width up to the width of the data
* bus. It is assumed that the flash bus controller or local bus supports
* these types of accesses.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a rmm  07/16/01 First release
* </pre>
*
***************************************************************************/

#ifndef XFLASH_H /* prevent circular inclusions */
#define XFLASH_H /* by using protection macros */

/***************************** Include Files *********************************/
#include "xbasic_types.h"
#include "xstatus.h"
#include "xflash_geometry.h"
#include "xflash_properties.h"

/************************** Constant Definitions *****************************/

/**
 * Supported manufacturer IDs. Note, that not all parts from these listed
 * vendors are supported.
 */
#define XFL_MANUFACTURER_ID_INTEL 0x89

/** @name Configuration options
 * @{
 */
/**
 * <pre>
 * XFL_NON_BLOCKING_ERASE_OPTION    Controls whether the interface blocks on
 *                                  device erase until the operation is
 *                                  completed 1=noblock, 0=block
  * XFL_NON_BLOCKING_WRITE_OPTION   Controls whether the interface blocks on
 *                                  device program until the operation is
 *                                  completed 1=noblock, 0=block
 * </pre>
 */
#define XFL_NON_BLOCKING_ERASE_OPTION 0x00000001UL
#define XFL_NON_BLOCKING_WRITE_OPTION 0x00000002UL
/*@}*/

#define XFL_MAX_VENDOR_DATA_LENGTH 20       /* Number of 32-bit integers
                                               reserved for vendor data as part
                                               of the XFlash sub-components */

/**************************** Type Definitions *******************************/


/*
 * Define a type to contain part specific data to be maintained by
 * the part component. Within the component, a new type is defined that
 * overlays this type.
 */
typedef Xuint32 XFlashVendorData[XFL_MAX_VENDOR_DATA_LENGTH];

/**
 * This typedef contains configuration information for the device.
 */
typedef struct
{
    Xuint16 DeviceId;     /**< Unique ID of device */
    Xuint32 BaseAddr;     /**< Base address of array */
    Xuint8  NumParts;     /**< Number of parts in the array */
    Xuint8  PartWidth;    /**< Width of each part in bytes */
    Xuint8  PartMode;     /**< Operation mode of each part in bytes */
} XFlash_Config;

/**
 * The XFlash driver instance data. The user is required to allocate a
 * variable of this type for every flash device in the system. A pointer
 * to a variable of this type is then passed to the driver API functions.
 */
typedef struct XFlashTag
{
    Xuint32  Options;                /* Current device options */
    Xboolean IsReady;                /* Device is initialized and ready */
    XFlashGeometry   Geometry;       /* Part geometry */
    XFlashProperties Properties;     /* Part timing, programming, &
                                        identification properties */
    XFlashVendorData VendorData;     /* Part specific data */

    struct
    {
        XStatus (*ReadBlock)(struct XFlashTag *InstancePtr, Xuint16 Region,
                             Xuint16 Block, Xuint32 Offset, Xuint32 Bytes,
                             void* DestPtr);

        XStatus (*WriteBlock)(struct XFlashTag *InstancePtr, Xuint16 Region,
                              Xuint16 Block,Xuint32 Offset, Xuint32 Bytes,
                              void* SrcPtr);

        XStatus (*WriteBlockSuspend)(struct XFlashTag *InstancePtr,
                                     Xuint16 Region, Xuint16 Block,
                                     Xuint32 Offset);

        XStatus (*WriteBlockResume)(struct XFlashTag *InstancePtr,
                                    Xuint16 Region, Xuint16 Block,
                                    Xuint32 Offset);

        XStatus (*EraseBlock)(struct XFlashTag *InstancePtr, Xuint16 Region,
                              Xuint16 Block, Xuint16 NumBlocks);

        XStatus (*EraseBlockSuspend)(struct XFlashTag *InstancePtr,
                                     Xuint16 Region, Xuint16 Block);

        XStatus (*EraseBlockResume)(struct XFlashTag *InstancePtr,
                                    Xuint16 Region, Xuint16 Block);

        XStatus (*LockBlock)(struct XFlashTag *InstancePtr, Xuint16 Region,
                             Xuint16 Block, Xuint16 NumBlocks);

        XStatus (*UnlockBlock)(struct XFlashTag *InstancePtr, Xuint16 Region,
                               Xuint16 Block, Xuint16 NumBlocks);

        XStatus (*GetBlockStatus)(struct XFlashTag *InstancePtr, Xuint16 Region,
                                  Xuint16 Block);

        XStatus (*Read)(struct XFlashTag *InstancePtr, Xuint32 Offset,
                        Xuint32 Bytes, void* DestPtr);

        XStatus (*Write)(struct XFlashTag *InstancePtr, Xuint32 Offset,
                         Xuint32 Bytes, void* SrcPtr);

        XStatus (*WriteSuspend)(struct XFlashTag *InstancePtr, Xuint32 Offset);
        XStatus (*WriteResume)(struct XFlashTag *InstancePtr, Xuint32 Offset);

        XStatus (*Erase)(struct XFlashTag *InstancePtr, Xuint32 Offset,
                         Xuint32 Bytes);

        XStatus (*EraseSuspend)(struct XFlashTag *InstancePtr, Xuint32 Offset);
        XStatus (*EraseResume)(struct XFlashTag *InstancePtr, Xuint32 Offset);

        XStatus (*Lock)(struct XFlashTag *InstancePtr, Xuint32 Offset,
                        Xuint32 Bytes);

        XStatus (*Unlock)(struct XFlashTag *InstancePtr, Xuint32 Offset,
                          Xuint32 Bytes);
        XStatus (*GetStatus)(struct XFlashTag *InstancePtr, Xuint32 Offset);

        XStatus (*EraseChip)(struct XFlashTag *InstancePtr);
        XStatus (*Initialize)(struct XFlashTag *Initialize);
        XStatus (*SelfTest)(struct XFlashTag *InstancePtr);
        XStatus (*Reset)(struct XFlashTag *InstancePtr);
        XStatus (*SetOptions)(struct XFlashTag *InstancePtr,
                               Xuint32 OptionsFlag);

        Xuint32 (*GetOptions)(struct XFlashTag *InstancePtr);
        XFlashProperties* (*GetProperties)(struct XFlashTag *InstancePtr);
        XFlashGeometry* (*GetGeometry)(struct XFlashTag *InstancePtr);
        XStatus (*DeviceControl)(struct XFlashTag *InstancePtr, Xuint32 Command,
                                 Xuint32 Param, Xuint32 *ReturnPtr);
    } VTable;
} XFlash;


/***************** Macros (Inline Functions) Definitions *********************/

/*
 * The following macros implement flash I/O primitives. All flash components
 * use these macros to access the flash devices. The only exceptions are read
 * functions which simply copy data using memcpy or equivalent utility funcs.
 *
 * The 8, 16, 32, 64 signify the access width.
 */
#define READ_FLASH_8(Address) \
    (*(volatile Xuint8*)(Address))

#define READ_FLASH_16(Address) \
    (*(volatile Xuint16*)(Address))

#define READ_FLASH_32(Address) \
    (*(volatile Xuint32*)(Address))

#define READ_FLASH_64(Address, Data) \
    (XUINT64_MSW(Data) = *(volatile Xuint32*)(Address)); \
    (XUINT64_LSW(Data) = *(volatile Xuint32*)(((Xuint32)(Address) + 4)))

#define WRITE_FLASH_8(Address, Data) \
    (*(volatile Xuint8*)(Address) = (Xuint8)(Data))

#define WRITE_FLASH_16(Address, Data) \
    (*(volatile Xuint16*)(Address) = (Xuint16)(Data))

#define WRITE_FLASH_32(Address, Data) \
    (*(volatile Xuint32*)(Address) = (Xuint32)(Data))

#define WRITE_FLASH_64(Address, Data) \
    (*(volatile Xuint32*)(Address) = XUINT64_MSW(Data)); \
    (*(volatile Xuint32*)((Xuint32)(Address) + 4) = XUINT64_LSW(Data))

#define WRITE_FLASH_64x2(Address, Data1, Data2) \
    (*(volatile Xuint32*)(Address) = Data1); \
    (*(volatile Xuint32*)((Xuint32)(Address) + 4) = Data2)

/************************** Function Prototypes ******************************/

/*
 * Initialization, configuration, & control Functions
 */
XStatus XFlash_Initialize(XFlash *InstancePtr, Xuint16 DeviceId);
XStatus XFlash_SelfTest(XFlash *InstancePtr);
XStatus XFlash_Reset(XFlash *InstancePtr);
XFlash_Config *XFlash_LookupConfig(Xuint16 DeviceId);
XStatus XFlash_SetOptions(XFlash *InstancePtr, Xuint32 OptionsFlag);
Xuint32 XFlash_GetOptions(XFlash *InstancePtr);
XFlashProperties* XFlash_GetProperties(XFlash *InstancePtr);
XFlashGeometry*   XFlash_GetGeometry(XFlash *InstancePtr);

XStatus XFlash_DeviceControl(XFlash *InstancePtr, Xuint32 Command,
                             Xuint32 Param, Xuint32 *ReturnPtr);

/*
 * Non-geometry aware API
 */
XStatus XFlash_Read(XFlash *InstancePtr, Xuint32 Offset, Xuint32 Bytes,
                    void* DestPtr);

XStatus XFlash_Write(XFlash *InstancePtr, Xuint32 Offset, Xuint32 Bytes,
                    void* SrcPtr);

XStatus XFlash_WriteSuspend(XFlash *InstancePtr, Xuint32 Offset);
XStatus XFlash_WriteResume(XFlash *InstancePtr, Xuint32 Offset);

XStatus XFlash_Erase(XFlash *InstancePtr, Xuint32 Offset, Xuint32 Bytes);
XStatus XFlash_EraseSuspend(XFlash *InstancePtr, Xuint32 Offset);
XStatus XFlash_EraseResume(XFlash *InstancePtr, Xuint32 Offset);

XStatus XFlash_Lock(XFlash *InstancePtr, Xuint32 Offset, Xuint32 Bytes);
XStatus XFlash_Unlock(XFlash *InstancePtr, Xuint32 Offset, Xuint32 Bytes);
XStatus XFlash_GetStatus(XFlash *InstancePtr, Xuint32 Offset);

/*
 * Geometry aware API
 */
XStatus XFlash_ReadBlock(XFlash *InstancePtr, Xuint16 Region, Xuint16 Block,
                         Xuint32 Offset, Xuint32 Bytes, void* DestPtr);

XStatus XFlash_WriteBlock(XFlash *InstancePtr, Xuint16 Region, Xuint16 Block,
                          Xuint32 Offset, Xuint32 Bytes, void* SrcPtr);

XStatus XFlash_WriteBlockSuspend(XFlash *InstancePtr, Xuint16 Region,
                                 Xuint16 Block, Xuint32 Offset);

XStatus XFlash_WriteBlockResume(XFlash *InstancePtr, Xuint16 Region,
                                Xuint16 Block, Xuint32 Offset);

XStatus XFlash_EraseBlock(XFlash *InstancePtr, Xuint16 Region, Xuint16 Block,
                          Xuint16 NumBlocks);

XStatus XFlash_EraseBlockSuspend(XFlash *InstancePtr, Xuint16 Region,
                                 Xuint16 Block);

XStatus XFlash_EraseBlockResume(XFlash *InstancePtr, Xuint16 Region,
                                Xuint16 Block);

XStatus XFlash_LockBlock(XFlash *InstancePtr, Xuint16 Region, Xuint16 Block,
                         Xuint16 NumBlocks);

XStatus XFlash_UnlockBlock(XFlash *InstancePtr, Xuint16 Region, Xuint16 Block,
                           Xuint16 NumBlocks);

XStatus XFlash_GetBlockStatus(XFlash *InstancePtr, Xuint16 Region,
                              Xuint16 Block);

/*
 * Other commands
 */
XStatus XFlash_EraseChip(XFlash *InstancePtr);

#endif            /* end of protection macro */
