Skip to content

Commit 348c539

Browse files
author
Jon Lin
committed
drivers: rkflash: Support sfc DLL api
Change-Id: Id4aa6d86ee0fe0a6d4d70ce75d9f15f8be749a1c Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
1 parent f6c3b58 commit 348c539

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

drivers/rkflash/sfc.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ static void sfc_reset(void)
1818
int timeout = 10000;
1919

2020
writel(SFC_RESET, g_sfc_reg + SFC_RCVR);
21+
2122
while ((readl(g_sfc_reg + SFC_RCVR) == SFC_RESET) && (timeout > 0)) {
2223
sfc_delay(1);
2324
timeout--;
2425
}
26+
2527
writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR);
2628
}
2729

@@ -38,10 +40,29 @@ u32 sfc_get_max_iosize(void)
3840
return SFC_MAX_IOSIZE_VER3;
3941
}
4042

43+
void sfc_set_delay_lines(u16 cells)
44+
{
45+
u16 cell_max = SCLK_SMP_SEL_MAX_V4;
46+
47+
if (sfc_get_version() >= SFC_VER_5)
48+
cell_max = SCLK_SMP_SEL_MAX_V5;
49+
50+
if (cells > cell_max)
51+
cells = cell_max;
52+
53+
writel(SCLK_SMP_SEL_EN | cells, g_sfc_reg + SFC_DLL_CTRL0);
54+
}
55+
56+
void sfc_disable_delay_lines(void)
57+
{
58+
writel(0, g_sfc_reg + SFC_DLL_CTRL0);
59+
}
60+
4161
int sfc_init(void __iomem *reg_addr)
4262
{
4363
g_sfc_reg = reg_addr;
4464
writel(0, g_sfc_reg + SFC_CTRL);
65+
4566
if (sfc_get_version() >= SFC_VER_4)
4667
writel(1, g_sfc_reg + SFC_LEN_CTRL);
4768

@@ -62,32 +83,40 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
6283
int timeout = 0;
6384

6485
reg = readl(g_sfc_reg + SFC_FSR);
86+
6587
if (!(reg & SFC_TXEMPTY) || !(reg & SFC_RXEMPTY) ||
6688
(readl(g_sfc_reg + SFC_SR) & SFC_BUSY))
6789
sfc_reset();
6890

6991
cmd.d32 = op->sfcmd.d32;
92+
7093
if (cmd.b.addrbits == SFC_ADDR_XBITS) {
7194
union SFCCTRL_DATA ctrl;
7295

7396
ctrl.d32 = op->sfctrl.d32;
97+
7498
if (!ctrl.b.addrbits)
7599
return SFC_PARAM_ERR;
100+
76101
/* Controller plus 1 automatically */
77102
writel(ctrl.b.addrbits - 1, g_sfc_reg + SFC_ABIT);
78103
}
104+
79105
/* shift in the data at negedge sclk_out */
80106
op->sfctrl.d32 |= 0x2;
81107
cmd.b.datasize = size;
108+
82109
if (sfc_get_version() >= SFC_VER_4)
83110
writel(size, g_sfc_reg + SFC_LEN_EXT);
84111
else
85112
cmd.b.datasize = size;
86113

87114
writel(op->sfctrl.d32, g_sfc_reg + SFC_CTRL);
88115
writel(cmd.d32, g_sfc_reg + SFC_CMD);
116+
89117
if (cmd.b.addrbits)
90118
writel(addr, g_sfc_reg + SFC_ADDR);
119+
91120
if (!size)
92121
goto exit_wait;
93122
if (op->sfctrl.b.enbledma) {
@@ -121,21 +150,27 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
121150

122151
if (cmd.b.rw == SFC_WRITE) {
123152
words = (size + 3) >> 2;
153+
124154
while (words) {
125155
fifostat.d32 = readl(g_sfc_reg + SFC_FSR);
156+
126157
if (fifostat.b.txlevel > 0) {
127158
count = words < fifostat.b.txlevel ?
128159
words : fifostat.b.txlevel;
160+
129161
for (i = 0; i < count; i++) {
130162
writel(*p_data++,
131163
g_sfc_reg + SFC_DATA);
132164
words--;
133165
}
166+
134167
if (words == 0)
135168
break;
169+
136170
timeout = 0;
137171
} else {
138172
sfc_delay(1);
173+
139174
if (timeout++ > 10000) {
140175
ret = SFC_TX_TIMEOUT;
141176
break;
@@ -146,8 +181,10 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
146181
/* SFC_READ == cmd.b.rw */
147182
bytes = size & 0x3;
148183
words = size >> 2;
184+
149185
while (words) {
150186
fifostat.d32 = readl(g_sfc_reg + SFC_FSR);
187+
151188
if (fifostat.b.rxlevel > 0) {
152189
u32 count;
153190

@@ -159,11 +196,14 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
159196
SFC_DATA);
160197
words--;
161198
}
199+
162200
if (words == 0)
163201
break;
202+
164203
timeout = 0;
165204
} else {
166205
sfc_delay(1);
206+
167207
if (timeout++ > 10000) {
168208
ret = SFC_RX_TIMEOUT;
169209
break;
@@ -172,19 +212,24 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
172212
}
173213

174214
timeout = 0;
215+
175216
while (bytes) {
176217
fifostat.d32 = readl(g_sfc_reg + SFC_FSR);
218+
177219
if (fifostat.b.rxlevel > 0) {
178220
u8 *p_data1 = (u8 *)p_data;
179221

180222
words = readl(g_sfc_reg + SFC_DATA);
223+
181224
for (i = 0; i < bytes; i++)
182225
p_data1[i] =
183-
(u8)((words >> (i * 8)) & 0xFF);
226+
(u8)((words >> (i * 8)) & 0xFF);
227+
184228
break;
185229
}
186230

187231
sfc_delay(1);
232+
188233
if (timeout++ > 10000) {
189234
ret = SFC_RX_TIMEOUT;
190235
break;
@@ -195,13 +240,16 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
195240

196241
exit_wait:
197242
timeout = 0; /* wait cmd or data send complete */
243+
198244
while (readl(g_sfc_reg + SFC_SR) & SFC_BUSY) {
199245
sfc_delay(1);
246+
200247
if (timeout++ > 100000) { /* wait 100ms */
201248
ret = SFC_TX_TIMEOUT;
202249
break;
203250
}
204251
}
252+
205253
sfc_delay(1); /* CS# High Time (read/write) >100ns */
206254
return ret;
207255
}

drivers/rkflash/sfc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#define SFC_VER_3 0x3
99
#define SFC_VER_4 0x4
10+
#define SFC_VER_5 0x5
1011

1112
#define SFC_EN_INT (0) /* enable interrupt */
1213
#define SFC_EN_DMA (1) /* enable dma */
@@ -65,6 +66,11 @@
6566
/* SFC_RCVR Register */
6667
#define SFC_RESET BIT(0) /* controller reset */
6768

69+
/* SFC_DLL_CTRL Register */
70+
#define SCLK_SMP_SEL_EN BIT(15) /* SCLK Sampling Selection */
71+
#define SCLK_SMP_SEL_MAX_V4 0xFF /* SCLK Sampling Selection */
72+
#define SCLK_SMP_SEL_MAX_V5 0x1FF /* SCLK Sampling Selection */
73+
6874
/* SFC_SR Register */
6975
/* sfc busy flag. When busy, don't try to set the control register */
7076
#define SFC_BUSY BIT(0)
@@ -86,6 +92,7 @@
8692
#define SFC_RAWISR 0x28
8793
#define SFC_VER 0x2C
8894
#define SFC_QOP 0x30
95+
#define SFC_DLL_CTRL0 0x3C
8996
#define SFC_DMA_TRIGGER 0x80
9097
#define SFC_DMA_ADDR 0x84
9198
#define SFC_LEN_CTRL 0x88
@@ -207,6 +214,8 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size);
207214
u16 sfc_get_version(void);
208215
void sfc_clean_irq(void);
209216
u32 sfc_get_max_iosize(void);
217+
void sfc_set_delay_lines(u16 cells);
218+
void sfc_disable_delay_lines(void);
210219
void sfc_handle_irq(void);
211220
unsigned long rksfc_dma_map_single(unsigned long ptr, int size, int dir);
212221
void rksfc_dma_unmap_single(unsigned long ptr, int size, int dir);

0 commit comments

Comments
 (0)