/* * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd * * SPDX-License-Identifier: GPL-2.0 */ #ifndef _SFC_H #define _SFC_H #define SFC_VER_3 0x3 #define SFC_VER_4 0x4 #define SFC_VER_5 0x5 #define SFC_EN_INT (0) /* enable interrupt */ #define SFC_EN_DMA (1) /* enable dma */ #define SFC_FIFO_DEPTH (0x10) /* 16 words */ /* FIFO watermark */ #define SFC_RX_WMARK (SFC_FIFO_DEPTH) /* RX watermark level */ #define SFC_TX_WMARK (SFC_FIFO_DEPTH) /* TX watermark level */ #define SFC_RX_WMARK_SHIFT (8) #define SFC_TX_WMARK_SHIFT (0) /* return value */ #define SFC_OK (0) #define SFC_ERROR (-1) #define SFC_PARAM_ERR (-2) #define SFC_TX_TIMEOUT (-3) #define SFC_RX_TIMEOUT (-4) #define SFC_WAIT_TIMEOUT (-5) #define SFC_BUSY_TIMEOUT (-6) #define SFC_ECC_FAIL (-7) #define SFC_PROG_FAIL (-8) #define SFC_ERASE_FAIL (-9) /* SFC_CMD Register */ #define SFC_ADDR_0BITS (0) #define SFC_ADDR_24BITS (1) #define SFC_ADDR_32BITS (2) #define SFC_ADDR_XBITS (3) #define SFC_WRITE (1) #define SFC_READ (0) /* SFC_CTRL Register */ #define SFC_1BITS_LINE (0) #define SFC_2BITS_LINE (1) #define SFC_4BITS_LINE (2) #define SFC_ENABLE_DMA BIT(14) #define sfc_delay(us) udelay(us) #define DMA_INT BIT(7) /* dma interrupt */ #define NSPIERR_INT BIT(6) /* Nspi error interrupt */ #define AHBERR_INT BIT(5) /* Ahb bus error interrupt */ #define FINISH_INT BIT(4) /* Transfer finish interrupt */ #define TXEMPTY_INT BIT(3) /* Tx fifo empty interrupt */ #define TXOF_INT BIT(2) /* Tx fifo overflow interrupt */ #define RXUF_INT BIT(1) /* Rx fifo underflow interrupt */ #define RXFULL_INT BIT(0) /* Rx fifo full interrupt */ /* SFC_FSR Register*/ #define SFC_RXFULL BIT(3) /* rx fifo full */ #define SFC_RXEMPTY BIT(2) /* rx fifo empty */ #define SFC_TXEMPTY BIT(1) /* tx fifo empty */ #define SFC_TXFULL BIT(0) /* tx fifo full */ /* SFC_RCVR Register */ #define SFC_RESET BIT(0) /* controller reset */ /* SFC_DLL_CTRL Register */ #define SCLK_SMP_SEL_EN BIT(15) /* SCLK Sampling Selection */ #define SCLK_SMP_SEL_MAX_V4 0xFF /* SCLK Sampling Selection */ #define SCLK_SMP_SEL_MAX_V5 0x1FF /* SCLK Sampling Selection */ /* SFC_SR Register */ /* sfc busy flag. When busy, don't try to set the control register */ #define SFC_BUSY BIT(0) /* SFC_DMA_TRIGGER Register */ /* Dma start trigger signal. Auto cleared after write */ #define SFC_DMA_START BIT(0) #define SFC_CTRL 0x00 #define SFC_IMR 0x04 #define SFC_ICLR 0x08 #define SFC_FTLR 0x0C #define SFC_RCVR 0x10 #define SFC_AX 0x14 #define SFC_ABIT 0x18 #define SFC_MASKISR 0x1C #define SFC_FSR 0x20 #define SFC_SR 0x24 #define SFC_RAWISR 0x28 #define SFC_VER 0x2C #define SFC_QOP 0x30 #define SFC_DLL_CTRL0 0x3C #define SFC_DMA_TRIGGER 0x80 #define SFC_DMA_ADDR 0x84 #define SFC_LEN_CTRL 0x88 #define SFC_LEN_EXT 0x8C #define SFC_CMD 0x100 #define SFC_ADDR 0x104 #define SFC_DATA 0x108 union SFCFSR_DATA { u32 d32; struct { unsigned txempty : 1; unsigned txfull : 1; unsigned rxempty : 1; unsigned rxfull : 1; unsigned reserved7_4 : 4; unsigned txlevel : 5; unsigned reserved15_13 : 3; unsigned rxlevel : 5; unsigned reserved31_21 : 11; } b; }; /* Manufactory ID */ #define MID_WINBOND 0xEF #define MID_GIGADEV 0xC8 #define MID_MICRON 0x2C #define MID_MACRONIX 0xC2 #define MID_SPANSION 0x01 #define MID_EON 0x1C #define MID_ST 0x20 #define MID_XTX 0x0B #define MID_PUYA 0x85 #define MID_XMC 0x20 #define MID_DOSILICON 0xF8 #define MID_ZBIT 0x5E /*------------------------------ Global Typedefs -----------------------------*/ enum SFC_DATA_LINES { DATA_LINES_X1 = 0, DATA_LINES_X2, DATA_LINES_X4 }; union SFCCTRL_DATA { /* raw register data */ u32 d32; /* register bits */ struct { /* spi mode select */ unsigned mode : 1; /* * Shift in phase selection * 0: shift in the flash data at posedge sclk_out * 1: shift in the flash data at negedge sclk_out */ unsigned sps : 1; unsigned reserved3_2 : 2; /* sclk_idle_level_cycles */ unsigned scic : 4; /* Cmd bits number */ unsigned cmdlines : 2; /* Address bits number */ unsigned addrlines : 2; /* Data bits number */ unsigned datalines : 2; /* this bit is not exit in regiseter, just use for code param */ unsigned enbledma : 1; unsigned reserved15 : 1; unsigned addrbits : 5; unsigned reserved31_21 : 11; } b; }; union SFCCMD_DATA { /* raw register data */ u32 d32; /* register bits */ struct { /* Command that will send to Serial Flash */ unsigned cmd : 8; /* Dummy bits number */ unsigned dummybits : 4; /* 0: read, 1: write */ unsigned rw : 1; /* Continuous read mode */ unsigned readmode : 1; /* Address bits number */ unsigned addrbits : 2; /* Transferred bytes number */ unsigned datasize : 14; /* Chip select */ unsigned cs : 2; } b; }; struct rk_sfc_op { union SFCCMD_DATA sfcmd; union SFCCTRL_DATA sfctrl; }; #define IDB_BLOCK_TAG_ID 0xFCDC8C3B struct id_block_tag { u32 id; u32 version; u32 flags; u16 boot_img_offset; u8 reserved1[10]; u32 dev_param[8]; u8 reserved2[506 - 56]; u16 data_img_len; u16 boot_img_len; u8 reserved3[512 - 510]; } __packed; int sfc_init(void __iomem *reg_addr); int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size); u16 sfc_get_version(void); void sfc_clean_irq(void); u32 sfc_get_max_iosize(void); void sfc_set_delay_lines(u16 cells); void sfc_disable_delay_lines(void); int rksfc_get_reg_addr(unsigned long *p_sfc_addr); #endif