/****************************************************************************** ** ** FILE NAME : ifxmips_sflash.h ** PROJECT : IFX UEIP ** MODULES : Serial Flash ** ** DATE : 03 July 2009 ** AUTHOR : Lei Chuanhua ** DESCRIPTION : SPI Flash MTD Driver ** COPYRIGHT : Copyright (c) 2009 ** Infineon Technologies AG ** Am Campeon 1-12, 85579 Neubiberg, Germany ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** HISTORY ** $Date $Author $Comment ** 03,July,2009 Lei Chuanhua Initial UEIP release *******************************************************************************/ /*! \file ifxmips_sflash.h \ingroup IFX_SFLASH \brief ifx serial flash driver header file */ #ifndef IFXMIPS_SFLASH_H #define IFXMIPS_SFLASH_H /* Flash related definition */ #define IFX_FLASH_128KB 0 #define IFX_FLASH_256KB 1 #define IFX_FLASH_512KB 2 #define IFX_FLASH_1MB 3 #define IFX_FLASH_2MB 4 #define IFX_FLASH_4MB 5 #define IFX_FLASH_8MB 6 #define IFX_FLASH_16MB 7 #define IFX_SPI_MAX_FLASH 8 #define IFX_FLASH_INVALID_SIZE -1 #define IFX_SFLASH_PAGESIZE 256 /* Flash opcodes. */ #define IFX_OPCODE_WREN 0x06 /* Write enable */ #define IFX_OPCODE_RDSR 0x05 /* Read status register */ #define IFX_OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ #define IFX_OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ #define IFX_OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ #define IFX_OPCODE_BE_4K 0x20 /* Erase 4KiB block */ #define IFX_OPCODE_BE_32K 0x52 /* Erase 32KiB block */ #define IFX_OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */ #define IFX_OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ #define IFX_OPCODE_RDID 0x9f /* Read JEDEC ID */ #define IFX_MAX_ADDRESS_NUM 5 #define IFX_MAX_DUMMY_CYCLES 10 /* Status Register bits. */ #define IFX_SR_WIP 1 /* Write in progress */ #define IFX_SR_WEL 2 /* Write enable latch */ /* meaning of other SR_* bits may differ between vendors */ #define IFX_SR_BP0 4 /* Block protect 0 */ #define IFX_SR_BP1 8 /* Block protect 1 */ #define IFX_SR_BP2 0x10 /* Block protect 2 */ #define IFX_SR_SRWD 0x80 /* SR write protect */ /*--- status bits ---*/ #define WIP (1 << 0) #define WEL (1 << 1) #define BP0 (1 << 2) #define BP1 (1 << 3) #define BP2 (1 << 4) #define BP3 (1 << 5) #define PROG_ERROR (1 << 6) #define REG_WRITE_PROTECT (1 << 7) #define IFX_SFLASH_DETECT_COUNTER 100000 /* XXX, check if flash mounted */ /* Define max times to check status register before we give up. */ #define IFX_MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */ /* * 32 should be maximum requirement for DMA alignment at the low level, * keep it here for future change */ #define IFX_SFLASH_DMA_MAX_BURST_LEN 32 #define IFX_SFLASH_MAX_WRITE_SIZE (IFX_SFLASH_PAGESIZE * 2) #define IFX_SFLASH_MAX_READ_SIZE (IFX_SFLASH_PAGESIZE * 8) /* Tunable */ #define IFX_SFLASH_MAX_FLASH_TYPE 12 /* Per Vendor */ /* Define fast read/normal read, fast read for higher frequence*/ #define CONFIG_SPI_FLASH_SLOW_READ #ifdef CONFIG_SPI_FLASH_SLOW_READ #define IFX_OPCODE_READ IFX_OPCODE_NORM_READ #define IFX_FAST_READ_DUMMY_BYTE 0 #else #define IFX_OPCODE_READ IFX_OPCODE_FAST_READ #define IFX_FAST_READ_DUMMY_BYTE 1 #endif struct ifx_sflash_info { char *name; /* JEDEC id zero means "no ID" (most older chips); otherwise it has * a high byte of zero plus three data bytes: the manufacturer id, * then a two byte device id. */ u16 id; /* The size listed here is what works with IFX_OPCODE_SE, which isn't * necessarily called a "sector" by the vendor. */ unsigned int sector_size; u16 num_sectors; u16 flags; #define SECT_4K 0x01 /* IFX_OPCODE_BE_4K works uniformly */ }; struct ifx_sflash_manufacturer_info { char *name; u8 id; struct ifx_sflash_info flashes[IFX_SFLASH_MAX_FLASH_TYPE]; }; enum { JED_MANU_SPANSION = 0x01, JED_MANU_ST = 0x20, JED_MANU_SST = 0xBF, JED_MANU_ATMEL = 0x1F, JED_MANU_WINBOND = 0xEF, JED_MANU_MX = 0xC2, }; /* Driver private data */ typedef struct { struct mtd_info *mtd; struct mtd_partition *parsed_parts; /* parsed partitions */ char *flash_tx_org_buf; /* Original write buffer */ char *flash_tx_buf; /* Aligned write buffer */ char *flash_rx_org_buf; /* Orignal read buffer */ char *flash_rx_buf; /* Aligned read buffer */ u8 addr_cycles; IFX_SSC_HANDLE sflash_handler; struct ifx_sflash_manufacturer_info *manufacturer; struct ifx_sflash_info *flash; u8 erase_opcode; u8 manufacturer_id, device_id1, device_id2; unsigned int write_length; unsigned long sector_size, num_sectors, size; int dummy_cycles; // AVM/TKL: unsigned int panic_mode; } ifx_spi_dev_t; #if defined(CONFIG_DANUBE) #include "ifxmips_sflash_danube.h" #elif defined(CONFIG_AMAZON_SE) #include "ifxmips_sflash_amazon_se.h" #elif defined(CONFIG_AR9) #include "ifxmips_sflash_ar9.h" #elif defined(CONFIG_VR9) #include "ifxmips_sflash_vr9.h" #elif defined(CONFIG_AR10) #include "ifxmips_sflash_ar10.h" #else #error "Platform not specified!" #endif /*------------------------------------------------------------------------------------------*\ * \*------------------------------------------------------------------------------------------*/ #if defined(CONFIG_TFFS_DEV_MTDNOR) || defined(CONFIG_TFFS_DEV_LEGACY) #if defined(CONFIG_VR9) #define SPI_CSx (10 & 0xF) /* P0.10 *//*--- CS4 ---*/ #define SPI_DIN (0 & 0xF) /* P1.0 */ #define SPI_DOUT (1 & 0xF) /* P1.1 */ #define SPI_CLK (2 & 0xF) /* P1.2 */ #define IFX_SSC_CSx IFX_SSC_CS4 #elif defined(CONFIG_AR10)/*--- #if defined(CONFIG_VR9) ---*/ #define SPI_CSx (15 & 0xF) /* P0.15 *//*--- CS1 ---*/ #define SPI_DIN (0 & 0xF) /* P1.0 */ #define SPI_DOUT (1 & 0xF) /* P1.1 */ #define SPI_CLK (2 & 0xF) /* P1.2 */ #define IFX_SSC_CSx IFX_SSC_CS1 #else /*--- #elif defined(CONFIG_AR10) ---*//*--- #if defined(CONFIG_VR9) ---*/ #error: unsupported platform #endif/*--- #else ---*//*--- #elif defined(CONFIG_AR10) ---*//*--- #if defined(CONFIG_VR9) ---*/ #define DATA_WIDTH 8 #define RXFIFO_SIZE 8 #define TXFIFO_SIZE 8 #define SFLASH_BAUDRATE 2000000 enum spi_cs { IFX_SSC_CS1 = 0, IFX_SSC_CS2, IFX_SSC_CS3, IFX_SSC_CS4, IFX_SSC_CS5, IFX_SSC_CS6, IFX_SSC_CS7, }; enum spi_cs_enum { select, deselect }; #define SPI_CLK_OFF 0x00 #define SPI_CFG_OFF 0x04 #define SPI_CMD_OFF 0x08 #define SPI_STAT_OFF 0x0C #define SPI_DATA_OFF 0x10 #define SPI_CLK_EN (1<<31) #define SPI_CMD_READ (1 << 16) #define SPI_CMD_WRITE (2 << 16) #define SPI_WORD_LEN_8 ((8-1) << 19) #define SPI_WORD_LEN_16 ((16-1) << 19) #define SPI_WORD_LEN_24 ((24-1) << 19) #define SPI_WORD_LEN_32 ((32-1) << 19) #define SPI_USE_CS0 (0 << 28) #define SPI_USE_CS1 (1 << 28) #define SPI_USE_CS2 (2 << 28) #define SPI_USE_CS3 (3 << 28) #define SPI_MAX_FRAME_LEN 4096 /*--- 11 Bit Framelänge, es können 32 Bit pro Frame übertragen werden ---*/ /*------------------------------------------------------------------------------------------*\ * SPI_CON_REGISTER \*------------------------------------------------------------------------------------------*/ #define SPI_CON_TXOFF 1 #define SPI_CON_RXOFF 2 #if !defined(_ASSEMBLER_) union _spi_con { volatile unsigned int Register; struct __spi_con { volatile unsigned int reserved2 : 7; volatile unsigned int em : 1; volatile unsigned int idle : 1; volatile unsigned int enbv : 1; volatile unsigned int reserved1 : 1; volatile unsigned int bm : 5; volatile unsigned int reserved0 : 1; volatile unsigned int cdel : 2; volatile unsigned int ruen : 1; volatile unsigned int tuen : 1; volatile unsigned int aen : 1; volatile unsigned int ren : 1; volatile unsigned int ten : 1; volatile unsigned int lb : 1; volatile unsigned int po : 1; volatile unsigned int ph : 1; volatile unsigned int hb : 1; volatile unsigned int csben : 1; volatile unsigned int csbinv : 1; volatile unsigned int rxoff : 1; volatile unsigned int txoff : 1; } Bits; }; #define CON_TXOFF (1 << 0) #define CON_RXOFF (1 << 1) #define CON_HB (1 << 4) #define CON_PH (1 << 5) #define CON_BM_8BIT (7 << 16) #define CON_BM_16BIT (15 << 16) #define CON_BM_32BIT (31 << 16) #define CON_ENBV (1 << 22) union _spi_status { volatile unsigned int Register; struct __spi_stat { volatile unsigned int rxeom : 1; volatile unsigned int rxbv : 3; volatile unsigned int txeom : 1; volatile unsigned int txbv : 3; unsigned int reserved2 : 3; volatile unsigned int bc : 5; unsigned int reserved1 : 2; volatile unsigned int bsy : 1; volatile unsigned int rue : 1; volatile unsigned int tue : 1; volatile unsigned int ae : 1; volatile unsigned int re : 1; volatile unsigned int te : 1; volatile unsigned int me : 1; unsigned int reserved0 : 4; volatile unsigned int ssel : 1; volatile unsigned int ms : 1; volatile unsigned int en : 1; } Bits; }; union _spi_fifo_ctrl { volatile unsigned int Register; struct __spi_fifo_ctrl { unsigned int reserved1 : 18; volatile unsigned int intlevel : 6; unsigned int reserved0 : 6; volatile unsigned int flush : 1; volatile unsigned int en : 1; } Bits; }; union _spi_fifo_stat { volatile unsigned int Register; struct __spi_fifo_stat { unsigned int reserved1 : 18; volatile unsigned int txffl : 6; unsigned int reserved0 : 2; volatile unsigned int rxffl : 6; } Bits; }; union _spi_pisel { volatile unsigned int Register; struct __spi_pisel { unsigned int reserved0 : 29; volatile unsigned int cis : 1; volatile unsigned int sis : 1; volatile unsigned int mis : 1; } Bits; }; union _spi_sfcon { volatile unsigned int Register; struct __spi_sfcon { volatile unsigned int plen : 10; unsigned int reserved1 : 1; volatile unsigned int stop : 1; volatile unsigned int iclk : 2; volatile unsigned int idat : 2; volatile unsigned int dlen : 12; volatile unsigned int iaen : 1; volatile unsigned int iben : 1; unsigned int reserved0 : 1; volatile unsigned int sfen : 1; } Bits; }; union _spi_sfstat { volatile unsigned int Register; struct __spi_sfstat { volatile unsigned int pcnt : 10; unsigned int reserved1 : 6; volatile unsigned int dcnt : 12; unsigned int reserved0 : 2; volatile unsigned int pbsy : 1; volatile unsigned int dbsy : 1; } Bits; }; union _spi_id { volatile unsigned int Register; struct __spi_id { unsigned int reserved0 : 2; volatile unsigned int txfs : 6; unsigned int reserved1 : 2; volatile unsigned int rxfs : 6; volatile unsigned int id : 8; unsigned int reserved2 : 2; volatile unsigned int cfg : 1; volatile unsigned int rev : 5; } Bits; }; union _spi_data { volatile unsigned int Register; struct __spi_data_short { volatile unsigned short reserved; volatile unsigned short Bytes; } Short; struct __spi_data_char { volatile unsigned char reserved[3]; volatile unsigned char Byte; } Char; }; struct _spi_register { volatile unsigned int CLC; /*--- 0x00 ---*/ union _spi_pisel PISEL; /*--- 0x04 ---*/ union _spi_id ID; /*--- 0x08 ---*/ unsigned int reserved_0x0c; /*--- 0x0C ---*/ union _spi_con CON; /*--- 0x10 ---*/ union _spi_status STAT; /*--- 0x14 ---*/ volatile unsigned int WHBSTATE; /*--- 0x18 ---*/ unsigned int reserved_0x1c; /*--- 0x1C ---*/ union _spi_data TB; /*--- 0x20 ---*/ volatile unsigned int RB; /*--- 0x24 ---*/ unsigned int reserved_0x28; /*--- 0x28 ---*/ unsigned int reserved_0x2C; /*--- 0x2C ---*/ union _spi_fifo_ctrl RXFCON; /*--- 0x30 ---*/ union _spi_fifo_ctrl TXFCON; /*--- 0x34 ---*/ union _spi_fifo_stat FSTAT; /*--- 0x38 ---*/ unsigned int reserved_0x3C; /*--- 0x3C ---*/ volatile unsigned int BRT; /*--- 0x40 ---*/ volatile unsigned int BRSTAT; /*--- 0x44 ---*/ unsigned int reserved_0x3C_0x60[(0x60-0x48)/4]; /*--- 0x48-0x60 ---*/ union _spi_sfcon SFCON; /*--- 0x60 ---*/ union _spi_sfstat SFSTAT; /*--- 0x64 ---*/ unsigned int reserved_0x68; /*--- 0x68 ---*/ unsigned int reserved_0x6C; /*--- 0x6C ---*/ volatile unsigned int GPOCON; /*--- 0x70 ---*/ volatile unsigned int GPOSTAT; /*--- 0x74 ---*/ volatile unsigned int FGPO; /*--- 0x78 ---*/ unsigned int reserved_0x7C; /*--- 0x7C ---*/ volatile unsigned int RXREQ; /*--- 0x80 ---*/ volatile unsigned int RXCNT; /*--- 0x84 ---*/ unsigned int reserved_0x88_0xEC[(0xEC-0x88)/4]; /*--- 0x88-0xEC ---*/ volatile unsigned int DMACON; /*--- 0xEC ---*/ unsigned int reserved_0xF0; /*--- 0xF0 ---*/ volatile unsigned int IRNEN; /*--- 0xF4 ---*/ volatile unsigned int IRNICR; /*--- 0xF8 ---*/ volatile unsigned int IRNCR; /*--- 0xFC ---*/ }; #endif /*--- #if !defined(_ASSEMBLER_) ---*/ #endif // defined(CONFIG_TFFS_DEV_MTDNOR) || defined(CONFIG_TFFS_DEV_LEGACY) #endif /* IFXMIPS_SFLASH_H */