1ad309a88SDingqiang Lin /* 2ad309a88SDingqiang Lin * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 3ad309a88SDingqiang Lin * 4ba0501acSDingqiang Lin * SPDX-License-Identifier: GPL-2.0 5ad309a88SDingqiang Lin */ 6ad309a88SDingqiang Lin 7ad309a88SDingqiang Lin #ifndef _SFC_H 8ad309a88SDingqiang Lin #define _SFC_H 9ad309a88SDingqiang Lin 10534d4d2fSJon Lin #define SFC_VER_3 0x3 11534d4d2fSJon Lin #define SFC_VER_4 0x4 12*49eba1a3SJon Lin #define SFC_VER_5 0x5 13ad309a88SDingqiang Lin 14ad309a88SDingqiang Lin #define SFC_EN_INT (0) /* enable interrupt */ 15ad309a88SDingqiang Lin #define SFC_EN_DMA (1) /* enable dma */ 16ad309a88SDingqiang Lin #define SFC_FIFO_DEPTH (0x10) /* 16 words */ 17ad309a88SDingqiang Lin 18ad309a88SDingqiang Lin /* FIFO watermark */ 19ad309a88SDingqiang Lin #define SFC_RX_WMARK (SFC_FIFO_DEPTH) /* RX watermark level */ 20ad309a88SDingqiang Lin #define SFC_TX_WMARK (SFC_FIFO_DEPTH) /* TX watermark level */ 21ad309a88SDingqiang Lin #define SFC_RX_WMARK_SHIFT (8) 22ad309a88SDingqiang Lin #define SFC_TX_WMARK_SHIFT (0) 23ad309a88SDingqiang Lin 24ad309a88SDingqiang Lin /* return value */ 25ad309a88SDingqiang Lin #define SFC_OK (0) 26ad309a88SDingqiang Lin #define SFC_ERROR (-1) 27ad309a88SDingqiang Lin #define SFC_PARAM_ERR (-2) 28ad309a88SDingqiang Lin #define SFC_TX_TIMEOUT (-3) 29ad309a88SDingqiang Lin #define SFC_RX_TIMEOUT (-4) 30ad309a88SDingqiang Lin #define SFC_WAIT_TIMEOUT (-5) 31ad309a88SDingqiang Lin #define SFC_BUSY_TIMEOUT (-6) 32ad309a88SDingqiang Lin #define SFC_ECC_FAIL (-7) 33ad309a88SDingqiang Lin #define SFC_PROG_FAIL (-8) 34ad309a88SDingqiang Lin #define SFC_ERASE_FAIL (-9) 35ad309a88SDingqiang Lin 36ad309a88SDingqiang Lin /* SFC_CMD Register */ 37ad309a88SDingqiang Lin #define SFC_ADDR_0BITS (0) 38ad309a88SDingqiang Lin #define SFC_ADDR_24BITS (1) 39ad309a88SDingqiang Lin #define SFC_ADDR_32BITS (2) 40ad309a88SDingqiang Lin #define SFC_ADDR_XBITS (3) 41ad309a88SDingqiang Lin 42ad309a88SDingqiang Lin #define SFC_WRITE (1) 43ad309a88SDingqiang Lin #define SFC_READ (0) 44ad309a88SDingqiang Lin 45ad309a88SDingqiang Lin /* SFC_CTRL Register */ 46ad309a88SDingqiang Lin #define SFC_1BITS_LINE (0) 47ad309a88SDingqiang Lin #define SFC_2BITS_LINE (1) 48ad309a88SDingqiang Lin #define SFC_4BITS_LINE (2) 49ad309a88SDingqiang Lin 50ad309a88SDingqiang Lin #define SFC_ENABLE_DMA BIT(14) 51ad309a88SDingqiang Lin #define sfc_delay(us) udelay(us) 52ad309a88SDingqiang Lin 53ad309a88SDingqiang Lin #define DMA_INT BIT(7) /* dma interrupt */ 54ad309a88SDingqiang Lin #define NSPIERR_INT BIT(6) /* Nspi error interrupt */ 55ad309a88SDingqiang Lin #define AHBERR_INT BIT(5) /* Ahb bus error interrupt */ 56ad309a88SDingqiang Lin #define FINISH_INT BIT(4) /* Transfer finish interrupt */ 57ad309a88SDingqiang Lin #define TXEMPTY_INT BIT(3) /* Tx fifo empty interrupt */ 58ad309a88SDingqiang Lin #define TXOF_INT BIT(2) /* Tx fifo overflow interrupt */ 59ad309a88SDingqiang Lin #define RXUF_INT BIT(1) /* Rx fifo underflow interrupt */ 60ad309a88SDingqiang Lin #define RXFULL_INT BIT(0) /* Rx fifo full interrupt */ 61ad309a88SDingqiang Lin 62ad309a88SDingqiang Lin /* SFC_FSR Register*/ 63ad309a88SDingqiang Lin #define SFC_RXFULL BIT(3) /* rx fifo full */ 64ad309a88SDingqiang Lin #define SFC_RXEMPTY BIT(2) /* rx fifo empty */ 65ad309a88SDingqiang Lin #define SFC_TXEMPTY BIT(1) /* tx fifo empty */ 66ad309a88SDingqiang Lin #define SFC_TXFULL BIT(0) /* tx fifo full */ 67ad309a88SDingqiang Lin 68ad309a88SDingqiang Lin /* SFC_RCVR Register */ 69ad309a88SDingqiang Lin #define SFC_RESET BIT(0) /* controller reset */ 70ad309a88SDingqiang Lin 71*49eba1a3SJon Lin /* SFC_DLL_CTRL Register */ 72*49eba1a3SJon Lin #define SCLK_SMP_SEL_EN BIT(15) /* SCLK Sampling Selection */ 73*49eba1a3SJon Lin #define SCLK_SMP_SEL_MAX_V4 0xFF /* SCLK Sampling Selection */ 74*49eba1a3SJon Lin #define SCLK_SMP_SEL_MAX_V5 0x1FF /* SCLK Sampling Selection */ 75*49eba1a3SJon Lin 76ad309a88SDingqiang Lin /* SFC_SR Register */ 77ad309a88SDingqiang Lin /* sfc busy flag. When busy, don't try to set the control register */ 78ad309a88SDingqiang Lin #define SFC_BUSY BIT(0) 79ad309a88SDingqiang Lin 80ad309a88SDingqiang Lin /* SFC_DMA_TRIGGER Register */ 81ad309a88SDingqiang Lin /* Dma start trigger signal. Auto cleared after write */ 82ad309a88SDingqiang Lin #define SFC_DMA_START BIT(0) 83ad309a88SDingqiang Lin 84ad309a88SDingqiang Lin #define SFC_CTRL 0x00 85ad309a88SDingqiang Lin #define SFC_IMR 0x04 86ad309a88SDingqiang Lin #define SFC_ICLR 0x08 87ad309a88SDingqiang Lin #define SFC_FTLR 0x0C 88ad309a88SDingqiang Lin #define SFC_RCVR 0x10 89ad309a88SDingqiang Lin #define SFC_AX 0x14 90ad309a88SDingqiang Lin #define SFC_ABIT 0x18 91ad309a88SDingqiang Lin #define SFC_MASKISR 0x1C 92ad309a88SDingqiang Lin #define SFC_FSR 0x20 93ad309a88SDingqiang Lin #define SFC_SR 0x24 94ad309a88SDingqiang Lin #define SFC_RAWISR 0x28 95ad309a88SDingqiang Lin #define SFC_VER 0x2C 96ad309a88SDingqiang Lin #define SFC_QOP 0x30 97*49eba1a3SJon Lin #define SFC_DLL_CTRL0 0x3C 98ad309a88SDingqiang Lin #define SFC_DMA_TRIGGER 0x80 99ad309a88SDingqiang Lin #define SFC_DMA_ADDR 0x84 10058463f4dSJon Lin #define SFC_LEN_CTRL 0x88 10158463f4dSJon Lin #define SFC_LEN_EXT 0x8C 102ad309a88SDingqiang Lin #define SFC_CMD 0x100 103ad309a88SDingqiang Lin #define SFC_ADDR 0x104 104ad309a88SDingqiang Lin #define SFC_DATA 0x108 105ad309a88SDingqiang Lin 106ad309a88SDingqiang Lin union SFCFSR_DATA { 107ad309a88SDingqiang Lin u32 d32; 108ad309a88SDingqiang Lin struct { 109ad309a88SDingqiang Lin unsigned txempty : 1; 110ad309a88SDingqiang Lin unsigned txfull : 1; 111ad309a88SDingqiang Lin unsigned rxempty : 1; 112ad309a88SDingqiang Lin unsigned rxfull : 1; 113ad309a88SDingqiang Lin unsigned reserved7_4 : 4; 114ad309a88SDingqiang Lin unsigned txlevel : 5; 115ad309a88SDingqiang Lin unsigned reserved15_13 : 3; 116ad309a88SDingqiang Lin unsigned rxlevel : 5; 117ad309a88SDingqiang Lin unsigned reserved31_21 : 11; 118ad309a88SDingqiang Lin } b; 119ad309a88SDingqiang Lin }; 120c84f0ed8SJon Lin 121c84f0ed8SJon Lin /* Manufactory ID */ 122c84f0ed8SJon Lin #define MID_WINBOND 0xEF 123c84f0ed8SJon Lin #define MID_GIGADEV 0xC8 124c84f0ed8SJon Lin #define MID_MICRON 0x2C 125c84f0ed8SJon Lin #define MID_MACRONIX 0xC2 126c84f0ed8SJon Lin #define MID_SPANSION 0x01 127c84f0ed8SJon Lin #define MID_EON 0x1C 128c84f0ed8SJon Lin #define MID_ST 0x20 129c84f0ed8SJon Lin #define MID_XTX 0x0B 130c84f0ed8SJon Lin #define MID_PUYA 0x85 131c84f0ed8SJon Lin #define MID_XMC 0x20 132c84f0ed8SJon Lin #define MID_DOSILICON 0xF8 133c84f0ed8SJon Lin #define MID_ZBIT 0x5E 134ad309a88SDingqiang Lin 135ad309a88SDingqiang Lin /*------------------------------ Global Typedefs -----------------------------*/ 136ad309a88SDingqiang Lin enum SFC_DATA_LINES { 137ad309a88SDingqiang Lin DATA_LINES_X1 = 0, 138ad309a88SDingqiang Lin DATA_LINES_X2, 139ad309a88SDingqiang Lin DATA_LINES_X4 140ad309a88SDingqiang Lin }; 141ad309a88SDingqiang Lin 142ad309a88SDingqiang Lin union SFCCTRL_DATA { 143ad309a88SDingqiang Lin /* raw register data */ 144ad309a88SDingqiang Lin u32 d32; 145ad309a88SDingqiang Lin /* register bits */ 146ad309a88SDingqiang Lin struct { 147ad309a88SDingqiang Lin /* spi mode select */ 148ad309a88SDingqiang Lin unsigned mode : 1; 149ad309a88SDingqiang Lin /* 150ad309a88SDingqiang Lin * Shift in phase selection 151ad309a88SDingqiang Lin * 0: shift in the flash data at posedge sclk_out 152ad309a88SDingqiang Lin * 1: shift in the flash data at negedge sclk_out 153ad309a88SDingqiang Lin */ 154ad309a88SDingqiang Lin unsigned sps : 1; 155ad309a88SDingqiang Lin unsigned reserved3_2 : 2; 156ad309a88SDingqiang Lin /* sclk_idle_level_cycles */ 157ad309a88SDingqiang Lin unsigned scic : 4; 158ad309a88SDingqiang Lin /* Cmd bits number */ 159ad309a88SDingqiang Lin unsigned cmdlines : 2; 160ad309a88SDingqiang Lin /* Address bits number */ 161ad309a88SDingqiang Lin unsigned addrlines : 2; 162ad309a88SDingqiang Lin /* Data bits number */ 163ad309a88SDingqiang Lin unsigned datalines : 2; 164ad309a88SDingqiang Lin /* this bit is not exit in regiseter, just use for code param */ 165ad309a88SDingqiang Lin unsigned enbledma : 1; 166ad309a88SDingqiang Lin unsigned reserved15 : 1; 167ad309a88SDingqiang Lin unsigned addrbits : 5; 168ad309a88SDingqiang Lin unsigned reserved31_21 : 11; 169ad309a88SDingqiang Lin } b; 170ad309a88SDingqiang Lin }; 171ad309a88SDingqiang Lin 172ad309a88SDingqiang Lin union SFCCMD_DATA { 173ad309a88SDingqiang Lin /* raw register data */ 174ad309a88SDingqiang Lin u32 d32; 175ad309a88SDingqiang Lin /* register bits */ 176ad309a88SDingqiang Lin struct { 177ad309a88SDingqiang Lin /* Command that will send to Serial Flash */ 178ad309a88SDingqiang Lin unsigned cmd : 8; 179ad309a88SDingqiang Lin /* Dummy bits number */ 180ad309a88SDingqiang Lin unsigned dummybits : 4; 181ad309a88SDingqiang Lin /* 0: read, 1: write */ 182ad309a88SDingqiang Lin unsigned rw : 1; 183ad309a88SDingqiang Lin /* Continuous read mode */ 184ad309a88SDingqiang Lin unsigned readmode : 1; 185ad309a88SDingqiang Lin /* Address bits number */ 186ad309a88SDingqiang Lin unsigned addrbits : 2; 187ad309a88SDingqiang Lin /* Transferred bytes number */ 188ad309a88SDingqiang Lin unsigned datasize : 14; 189ad309a88SDingqiang Lin /* Chip select */ 190ad309a88SDingqiang Lin unsigned cs : 2; 191ad309a88SDingqiang Lin } b; 192ad309a88SDingqiang Lin }; 193ad309a88SDingqiang Lin 19458463f4dSJon Lin struct rk_sfc_op { 19558463f4dSJon Lin union SFCCMD_DATA sfcmd; 19658463f4dSJon Lin union SFCCTRL_DATA sfctrl; 19758463f4dSJon Lin }; 19858463f4dSJon Lin 1999371a438SJon Lin #define IDB_BLOCK_TAG_ID 0xFCDC8C3B 2009371a438SJon Lin 2019371a438SJon Lin struct id_block_tag { 2029371a438SJon Lin u32 id; 2039371a438SJon Lin u32 version; 2049371a438SJon Lin u32 flags; 2059371a438SJon Lin u16 boot_img_offset; 2069371a438SJon Lin u8 reserved1[10]; 2079371a438SJon Lin u32 dev_param[8]; 2089371a438SJon Lin u8 reserved2[506 - 56]; 2099371a438SJon Lin u16 data_img_len; 2109371a438SJon Lin u16 boot_img_len; 2119371a438SJon Lin u8 reserved3[512 - 510]; 2129371a438SJon Lin } __packed; 2139371a438SJon Lin 214ad309a88SDingqiang Lin int sfc_init(void __iomem *reg_addr); 21558463f4dSJon Lin int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size); 216ad309a88SDingqiang Lin u16 sfc_get_version(void); 217ad309a88SDingqiang Lin void sfc_clean_irq(void); 218534d4d2fSJon Lin u32 sfc_get_max_iosize(void); 219*49eba1a3SJon Lin void sfc_set_delay_lines(u16 cells); 220*49eba1a3SJon Lin void sfc_disable_delay_lines(void); 221ad309a88SDingqiang Lin int rksfc_get_reg_addr(unsigned long *p_sfc_addr); 222ad309a88SDingqiang Lin 223ad309a88SDingqiang Lin #endif 224