xref: /rk3399_rockchip-uboot/drivers/rkflash/sfc.h (revision 49eba1a38af4a5e597bddd957f12dae2a3d6b9f9)
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