xref: /OK3568_Linux_fs/kernel/drivers/rkflash/sfc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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