1 // SPDX-License-Identifier: GPL-2.0
2
3 /* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */
4
5 #include <linux/delay.h>
6 #include <linux/dma-mapping.h>
7 #include <linux/kernel.h>
8
9 #include "sfc.h"
10
11 #define SFC_MAX_IOSIZE_VER3 (1024 * 8)
12 #define SFC_MAX_IOSIZE_VER4 (0xFFFFFFFF)
13
14 static void __iomem *g_sfc_reg;
15
sfc_reset(void)16 static void sfc_reset(void)
17 {
18 int timeout = 10000;
19
20 writel(SFC_RESET, g_sfc_reg + SFC_RCVR);
21
22 while ((readl(g_sfc_reg + SFC_RCVR) == SFC_RESET) && (timeout > 0)) {
23 sfc_delay(1);
24 timeout--;
25 }
26
27 writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR);
28 }
29
sfc_get_version(void)30 u16 sfc_get_version(void)
31 {
32 return (u32)(readl(g_sfc_reg + SFC_VER) & 0xffff);
33 }
34
sfc_get_max_iosize(void)35 u32 sfc_get_max_iosize(void)
36 {
37 if (sfc_get_version() >= SFC_VER_4)
38 return SFC_MAX_IOSIZE_VER4;
39 else
40 return SFC_MAX_IOSIZE_VER3;
41 }
42
sfc_get_max_dll_cells(void)43 u32 sfc_get_max_dll_cells(void)
44 {
45 switch (sfc_get_version()) {
46 case SFC_VER_8:
47 case SFC_VER_6:
48 case SFC_VER_5:
49 return SCLK_SMP_SEL_MAX_V5;
50 case SFC_VER_4:
51 return SCLK_SMP_SEL_MAX_V4;
52 default:
53 return 0;
54 }
55 }
56
sfc_set_delay_lines(u16 cells)57 void sfc_set_delay_lines(u16 cells)
58 {
59 u16 cell_max = (u16)sfc_get_max_dll_cells();
60 u32 val = 0;
61
62 if (cells > cell_max)
63 cells = cell_max;
64
65 if (cells)
66 val = SCLK_SMP_SEL_EN | cells;
67
68 writel(val, g_sfc_reg + SFC_DLL_CTRL0);
69 }
70
sfc_init(void __iomem * reg_addr)71 int sfc_init(void __iomem *reg_addr)
72 {
73 g_sfc_reg = reg_addr;
74 writel(0, g_sfc_reg + SFC_CTRL);
75
76 if (sfc_get_version() >= SFC_VER_4)
77 writel(1, g_sfc_reg + SFC_LEN_CTRL);
78
79 return SFC_OK;
80 }
81
sfc_clean_irq(void)82 void sfc_clean_irq(void)
83 {
84 writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR);
85 writel(0xFFFFFFFF, g_sfc_reg + SFC_IMR);
86 }
87
sfc_request(struct rk_sfc_op * op,u32 addr,void * data,u32 size)88 int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
89 {
90 int ret = SFC_OK;
91 union SFCCMD_DATA cmd;
92 int reg;
93 int timeout = 0;
94
95 reg = readl(g_sfc_reg + SFC_FSR);
96
97 if (!(reg & SFC_TXEMPTY) || !(reg & SFC_RXEMPTY) ||
98 (readl(g_sfc_reg + SFC_SR) & SFC_BUSY))
99 sfc_reset();
100
101 cmd.d32 = op->sfcmd.d32;
102
103 if (cmd.b.addrbits == SFC_ADDR_XBITS) {
104 union SFCCTRL_DATA ctrl;
105
106 ctrl.d32 = op->sfctrl.d32;
107
108 if (!ctrl.b.addrbits)
109 return SFC_PARAM_ERR;
110
111 /* Controller plus 1 automatically */
112 writel(ctrl.b.addrbits - 1, g_sfc_reg + SFC_ABIT);
113 }
114
115 /* shift in the data at negedge sclk_out */
116 op->sfctrl.d32 |= 0x2;
117 cmd.b.datasize = size;
118
119 if (sfc_get_version() >= SFC_VER_4)
120 writel(size, g_sfc_reg + SFC_LEN_EXT);
121 else
122 cmd.b.datasize = size;
123
124 writel(op->sfctrl.d32, g_sfc_reg + SFC_CTRL);
125 writel(cmd.d32, g_sfc_reg + SFC_CMD);
126
127 if (cmd.b.addrbits)
128 writel(addr, g_sfc_reg + SFC_ADDR);
129
130 if (!size)
131 goto exit_wait;
132 if (op->sfctrl.b.enbledma) {
133 unsigned long dma_addr;
134 u8 direction = (cmd.b.rw == SFC_WRITE) ? 1 : 0;
135
136 dma_addr = rksfc_dma_map_single((unsigned long)data,
137 size,
138 direction);
139 rksfc_irq_flag_init();
140 writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR);
141 writel(~((u32)DMA_INT), g_sfc_reg + SFC_IMR);
142 writel((u32)dma_addr, g_sfc_reg + SFC_DMA_ADDR);
143 writel(SFC_DMA_START, g_sfc_reg + SFC_DMA_TRIGGER);
144
145 rksfc_wait_for_irq_completed();
146 timeout = size * 10;
147 while ((readl(g_sfc_reg + SFC_SR) & SFC_BUSY) &&
148 (timeout-- > 0))
149 sfc_delay(1);
150 if (timeout <= 0)
151 ret = SFC_WAIT_TIMEOUT;
152 direction = (cmd.b.rw == SFC_WRITE) ? 1 : 0;
153 rksfc_dma_unmap_single(dma_addr,
154 size,
155 direction);
156 } else {
157 u32 i, words, count, bytes;
158 union SFCFSR_DATA fifostat;
159 u32 *p_data = (u32 *)data;
160
161 if (cmd.b.rw == SFC_WRITE) {
162 words = (size + 3) >> 2;
163
164 while (words) {
165 fifostat.d32 = readl(g_sfc_reg + SFC_FSR);
166
167 if (fifostat.b.txlevel > 0) {
168 count = words < fifostat.b.txlevel ?
169 words : fifostat.b.txlevel;
170
171 for (i = 0; i < count; i++) {
172 writel(*p_data++,
173 g_sfc_reg + SFC_DATA);
174 words--;
175 }
176
177 if (words == 0)
178 break;
179
180 timeout = 0;
181 } else {
182 sfc_delay(1);
183
184 if (timeout++ > 10000) {
185 ret = SFC_TX_TIMEOUT;
186 break;
187 }
188 }
189 }
190 } else {
191 /* SFC_READ == cmd.b.rw */
192 bytes = size & 0x3;
193 words = size >> 2;
194
195 while (words) {
196 fifostat.d32 = readl(g_sfc_reg + SFC_FSR);
197
198 if (fifostat.b.rxlevel > 0) {
199 u32 count;
200
201 count = words < fifostat.b.rxlevel ?
202 words : fifostat.b.rxlevel;
203
204 for (i = 0; i < count; i++) {
205 *p_data++ = readl(g_sfc_reg +
206 SFC_DATA);
207 words--;
208 }
209
210 if (words == 0)
211 break;
212
213 timeout = 0;
214 } else {
215 sfc_delay(1);
216
217 if (timeout++ > 10000) {
218 ret = SFC_RX_TIMEOUT;
219 break;
220 }
221 }
222 }
223
224 timeout = 0;
225
226 while (bytes) {
227 fifostat.d32 = readl(g_sfc_reg + SFC_FSR);
228
229 if (fifostat.b.rxlevel > 0) {
230 u8 *p_data1 = (u8 *)p_data;
231
232 words = readl(g_sfc_reg + SFC_DATA);
233
234 for (i = 0; i < bytes; i++)
235 p_data1[i] =
236 (u8)((words >> (i * 8)) & 0xFF);
237
238 break;
239 }
240
241 sfc_delay(1);
242
243 if (timeout++ > 10000) {
244 ret = SFC_RX_TIMEOUT;
245 break;
246 }
247 }
248 }
249 }
250
251 exit_wait:
252 timeout = 0; /* wait cmd or data send complete */
253
254 while (readl(g_sfc_reg + SFC_SR) & SFC_BUSY) {
255 sfc_delay(1);
256
257 if (timeout++ > 100000) { /* wait 100ms */
258 ret = SFC_TX_TIMEOUT;
259 break;
260 }
261 }
262
263 sfc_delay(1); /* CS# High Time (read/write) >100ns */
264 return ret;
265 }
266