xref: /rk3399_rockchip-uboot/drivers/rkflash/sfc.h (revision 9371a438f4be7dfddd6136e58bec2a34c531ba5a)
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
12ad309a88SDingqiang Lin 
13ad309a88SDingqiang Lin #define SFC_EN_INT		(0)         /* enable interrupt */
14ad309a88SDingqiang Lin #define SFC_EN_DMA		(1)         /* enable dma */
15ad309a88SDingqiang Lin #define SFC_FIFO_DEPTH		(0x10)      /* 16 words */
16ad309a88SDingqiang Lin 
17ad309a88SDingqiang Lin /* FIFO watermark */
18ad309a88SDingqiang Lin #define SFC_RX_WMARK		(SFC_FIFO_DEPTH)	/* RX watermark level */
19ad309a88SDingqiang Lin #define SFC_TX_WMARK		(SFC_FIFO_DEPTH)	/* TX watermark level */
20ad309a88SDingqiang Lin #define SFC_RX_WMARK_SHIFT	(8)
21ad309a88SDingqiang Lin #define SFC_TX_WMARK_SHIFT	(0)
22ad309a88SDingqiang Lin 
23ad309a88SDingqiang Lin /* return value */
24ad309a88SDingqiang Lin #define SFC_OK                      (0)
25ad309a88SDingqiang Lin #define SFC_ERROR                   (-1)
26ad309a88SDingqiang Lin #define SFC_PARAM_ERR               (-2)
27ad309a88SDingqiang Lin #define SFC_TX_TIMEOUT              (-3)
28ad309a88SDingqiang Lin #define SFC_RX_TIMEOUT              (-4)
29ad309a88SDingqiang Lin #define SFC_WAIT_TIMEOUT            (-5)
30ad309a88SDingqiang Lin #define SFC_BUSY_TIMEOUT            (-6)
31ad309a88SDingqiang Lin #define SFC_ECC_FAIL                (-7)
32ad309a88SDingqiang Lin #define SFC_PROG_FAIL               (-8)
33ad309a88SDingqiang Lin #define SFC_ERASE_FAIL              (-9)
34ad309a88SDingqiang Lin 
35ad309a88SDingqiang Lin /* SFC_CMD Register */
36ad309a88SDingqiang Lin #define SFC_ADDR_0BITS              (0)
37ad309a88SDingqiang Lin #define SFC_ADDR_24BITS             (1)
38ad309a88SDingqiang Lin #define SFC_ADDR_32BITS             (2)
39ad309a88SDingqiang Lin #define SFC_ADDR_XBITS              (3)
40ad309a88SDingqiang Lin 
41ad309a88SDingqiang Lin #define SFC_WRITE                   (1)
42ad309a88SDingqiang Lin #define SFC_READ                    (0)
43ad309a88SDingqiang Lin 
44ad309a88SDingqiang Lin /* SFC_CTRL Register */
45ad309a88SDingqiang Lin #define SFC_1BITS_LINE              (0)
46ad309a88SDingqiang Lin #define SFC_2BITS_LINE              (1)
47ad309a88SDingqiang Lin #define SFC_4BITS_LINE              (2)
48ad309a88SDingqiang Lin 
49ad309a88SDingqiang Lin #define SFC_ENABLE_DMA              BIT(14)
50ad309a88SDingqiang Lin #define sfc_delay(us)	udelay(us)
51ad309a88SDingqiang Lin 
52ad309a88SDingqiang Lin #define DMA_INT		BIT(7)      /* dma interrupt */
53ad309a88SDingqiang Lin #define NSPIERR_INT	BIT(6)      /* Nspi error interrupt */
54ad309a88SDingqiang Lin #define AHBERR_INT	BIT(5)      /* Ahb bus error interrupt */
55ad309a88SDingqiang Lin #define FINISH_INT	BIT(4)      /* Transfer finish interrupt */
56ad309a88SDingqiang Lin #define TXEMPTY_INT	BIT(3)      /* Tx fifo empty interrupt */
57ad309a88SDingqiang Lin #define TXOF_INT	BIT(2)      /* Tx fifo overflow interrupt */
58ad309a88SDingqiang Lin #define RXUF_INT	BIT(1)      /* Rx fifo underflow interrupt */
59ad309a88SDingqiang Lin #define RXFULL_INT	BIT(0)      /* Rx fifo full interrupt */
60ad309a88SDingqiang Lin 
61ad309a88SDingqiang Lin /* SFC_FSR Register*/
62ad309a88SDingqiang Lin #define SFC_RXFULL	BIT(3)      /* rx fifo full */
63ad309a88SDingqiang Lin #define SFC_RXEMPTY	BIT(2)      /* rx fifo empty */
64ad309a88SDingqiang Lin #define SFC_TXEMPTY	BIT(1)      /* tx fifo empty */
65ad309a88SDingqiang Lin #define SFC_TXFULL	BIT(0)      /* tx fifo full */
66ad309a88SDingqiang Lin 
67ad309a88SDingqiang Lin /* SFC_RCVR Register */
68ad309a88SDingqiang Lin #define SFC_RESET	BIT(0)     /* controller reset */
69ad309a88SDingqiang Lin 
70ad309a88SDingqiang Lin /* SFC_SR Register */
71ad309a88SDingqiang Lin /* sfc busy flag. When busy, don't try to set the control register */
72ad309a88SDingqiang Lin #define SFC_BUSY	BIT(0)
73ad309a88SDingqiang Lin 
74ad309a88SDingqiang Lin /* SFC_DMA_TRIGGER Register */
75ad309a88SDingqiang Lin /* Dma start trigger signal. Auto cleared after write */
76ad309a88SDingqiang Lin #define SFC_DMA_START	BIT(0)
77ad309a88SDingqiang Lin 
78ad309a88SDingqiang Lin #define SFC_CTRL	0x00
79ad309a88SDingqiang Lin #define SFC_IMR		0x04
80ad309a88SDingqiang Lin #define SFC_ICLR	0x08
81ad309a88SDingqiang Lin #define SFC_FTLR	0x0C
82ad309a88SDingqiang Lin #define SFC_RCVR	0x10
83ad309a88SDingqiang Lin #define SFC_AX		0x14
84ad309a88SDingqiang Lin #define SFC_ABIT	0x18
85ad309a88SDingqiang Lin #define SFC_MASKISR	0x1C
86ad309a88SDingqiang Lin #define SFC_FSR		0x20
87ad309a88SDingqiang Lin #define SFC_SR		0x24
88ad309a88SDingqiang Lin #define SFC_RAWISR	0x28
89ad309a88SDingqiang Lin #define SFC_VER		0x2C
90ad309a88SDingqiang Lin #define SFC_QOP		0x30
91ad309a88SDingqiang Lin #define SFC_DMA_TRIGGER	0x80
92ad309a88SDingqiang Lin #define SFC_DMA_ADDR	0x84
9358463f4dSJon Lin #define SFC_LEN_CTRL	0x88
9458463f4dSJon Lin #define SFC_LEN_EXT	0x8C
95ad309a88SDingqiang Lin #define SFC_CMD		0x100
96ad309a88SDingqiang Lin #define SFC_ADDR	0x104
97ad309a88SDingqiang Lin #define SFC_DATA	0x108
98ad309a88SDingqiang Lin 
99ad309a88SDingqiang Lin union SFCFSR_DATA {
100ad309a88SDingqiang Lin 	u32 d32;
101ad309a88SDingqiang Lin 	struct {
102ad309a88SDingqiang Lin 		unsigned txempty : 1;
103ad309a88SDingqiang Lin 		unsigned txfull :  1;
104ad309a88SDingqiang Lin 		unsigned rxempty : 1;
105ad309a88SDingqiang Lin 		unsigned rxfull :  1;
106ad309a88SDingqiang Lin 		unsigned reserved7_4 : 4;
107ad309a88SDingqiang Lin 		unsigned txlevel : 5;
108ad309a88SDingqiang Lin 		unsigned reserved15_13 : 3;
109ad309a88SDingqiang Lin 		unsigned rxlevel : 5;
110ad309a88SDingqiang Lin 		unsigned reserved31_21 : 11;
111ad309a88SDingqiang Lin 	} b;
112ad309a88SDingqiang Lin };
113c84f0ed8SJon Lin 
114c84f0ed8SJon Lin /* Manufactory ID */
115c84f0ed8SJon Lin #define MID_WINBOND	0xEF
116c84f0ed8SJon Lin #define MID_GIGADEV	0xC8
117c84f0ed8SJon Lin #define MID_MICRON	0x2C
118c84f0ed8SJon Lin #define MID_MACRONIX	0xC2
119c84f0ed8SJon Lin #define MID_SPANSION	0x01
120c84f0ed8SJon Lin #define MID_EON		0x1C
121c84f0ed8SJon Lin #define MID_ST		0x20
122c84f0ed8SJon Lin #define MID_XTX		0x0B
123c84f0ed8SJon Lin #define MID_PUYA	0x85
124c84f0ed8SJon Lin #define MID_XMC		0x20
125c84f0ed8SJon Lin #define MID_DOSILICON	0xF8
126c84f0ed8SJon Lin #define MID_ZBIT	0x5E
127ad309a88SDingqiang Lin 
128ad309a88SDingqiang Lin /*------------------------------ Global Typedefs -----------------------------*/
129ad309a88SDingqiang Lin enum SFC_DATA_LINES {
130ad309a88SDingqiang Lin 	DATA_LINES_X1 = 0,
131ad309a88SDingqiang Lin 	DATA_LINES_X2,
132ad309a88SDingqiang Lin 	DATA_LINES_X4
133ad309a88SDingqiang Lin };
134ad309a88SDingqiang Lin 
135ad309a88SDingqiang Lin union SFCCTRL_DATA {
136ad309a88SDingqiang Lin 	/* raw register data */
137ad309a88SDingqiang Lin 	u32 d32;
138ad309a88SDingqiang Lin 	/* register bits */
139ad309a88SDingqiang Lin 	struct {
140ad309a88SDingqiang Lin 		/* spi mode select */
141ad309a88SDingqiang Lin 		unsigned mode : 1;
142ad309a88SDingqiang Lin 		/*
143ad309a88SDingqiang Lin 		 * Shift in phase selection
144ad309a88SDingqiang Lin 		 * 0: shift in the flash data at posedge sclk_out
145ad309a88SDingqiang Lin 		 * 1: shift in the flash data at negedge sclk_out
146ad309a88SDingqiang Lin 		 */
147ad309a88SDingqiang Lin 		unsigned sps : 1;
148ad309a88SDingqiang Lin 		unsigned reserved3_2 : 2;
149ad309a88SDingqiang Lin 		/* sclk_idle_level_cycles */
150ad309a88SDingqiang Lin 		unsigned scic : 4;
151ad309a88SDingqiang Lin 		/* Cmd bits number */
152ad309a88SDingqiang Lin 		unsigned cmdlines : 2;
153ad309a88SDingqiang Lin 		/* Address bits number */
154ad309a88SDingqiang Lin 		unsigned addrlines : 2;
155ad309a88SDingqiang Lin 		/* Data bits number */
156ad309a88SDingqiang Lin 		unsigned datalines : 2;
157ad309a88SDingqiang Lin 		/* this bit is not exit in regiseter, just use for code param */
158ad309a88SDingqiang Lin 		unsigned enbledma : 1;
159ad309a88SDingqiang Lin 		unsigned reserved15 : 1;
160ad309a88SDingqiang Lin 		unsigned addrbits : 5;
161ad309a88SDingqiang Lin 		unsigned reserved31_21 : 11;
162ad309a88SDingqiang Lin 	} b;
163ad309a88SDingqiang Lin };
164ad309a88SDingqiang Lin 
165ad309a88SDingqiang Lin union SFCCMD_DATA {
166ad309a88SDingqiang Lin 	/* raw register data */
167ad309a88SDingqiang Lin 	u32 d32;
168ad309a88SDingqiang Lin 	/* register bits */
169ad309a88SDingqiang Lin 	struct {
170ad309a88SDingqiang Lin 		/* Command that will send to Serial Flash */
171ad309a88SDingqiang Lin 		unsigned cmd : 8;
172ad309a88SDingqiang Lin 		/* Dummy bits number */
173ad309a88SDingqiang Lin 		unsigned dummybits : 4;
174ad309a88SDingqiang Lin 		/* 0: read, 1: write */
175ad309a88SDingqiang Lin 		unsigned rw : 1;
176ad309a88SDingqiang Lin 		/* Continuous read mode */
177ad309a88SDingqiang Lin 		unsigned readmode : 1;
178ad309a88SDingqiang Lin 		/* Address bits number */
179ad309a88SDingqiang Lin 		unsigned addrbits : 2;
180ad309a88SDingqiang Lin 		/* Transferred bytes number */
181ad309a88SDingqiang Lin 		unsigned datasize : 14;
182ad309a88SDingqiang Lin 		/* Chip select */
183ad309a88SDingqiang Lin 		unsigned cs : 2;
184ad309a88SDingqiang Lin 	} b;
185ad309a88SDingqiang Lin };
186ad309a88SDingqiang Lin 
18758463f4dSJon Lin struct rk_sfc_op {
18858463f4dSJon Lin 	union SFCCMD_DATA sfcmd;
18958463f4dSJon Lin 	union SFCCTRL_DATA sfctrl;
19058463f4dSJon Lin };
19158463f4dSJon Lin 
192*9371a438SJon Lin #define IDB_BLOCK_TAG_ID	0xFCDC8C3B
193*9371a438SJon Lin 
194*9371a438SJon Lin struct id_block_tag {
195*9371a438SJon Lin 	u32 id;
196*9371a438SJon Lin 	u32 version;
197*9371a438SJon Lin 	u32 flags;
198*9371a438SJon Lin 	u16 boot_img_offset;
199*9371a438SJon Lin 	u8  reserved1[10];
200*9371a438SJon Lin 	u32 dev_param[8];
201*9371a438SJon Lin 	u8  reserved2[506 - 56];
202*9371a438SJon Lin 	u16 data_img_len;
203*9371a438SJon Lin 	u16 boot_img_len;
204*9371a438SJon Lin 	u8  reserved3[512 - 510];
205*9371a438SJon Lin } __packed;
206*9371a438SJon Lin 
207ad309a88SDingqiang Lin int sfc_init(void __iomem *reg_addr);
20858463f4dSJon Lin int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size);
209ad309a88SDingqiang Lin u16 sfc_get_version(void);
210ad309a88SDingqiang Lin void sfc_clean_irq(void);
211534d4d2fSJon Lin u32 sfc_get_max_iosize(void);
212ad309a88SDingqiang Lin int rksfc_get_reg_addr(unsigned long *p_sfc_addr);
213ad309a88SDingqiang Lin 
214ad309a88SDingqiang Lin #endif
215