hc
2024-05-09 b9d5c334faa47a75f1f28e72d203fc0334e8471d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
 * 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