1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
4  *		      Christophe Ricard <christophe.ricard@gmail.com>
5  *
6  * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com>
7  *
8  * Driver for McSPI controller on OMAP3. Based on davinci_spi.c
9  * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
10  *
11  * Copyright (C) 2007 Atmel Corporation
12  *
13  * Parts taken from linux/drivers/spi/omap2_mcspi.c
14  * Copyright (C) 2005, 2006 Nokia Corporation
15  *
16  * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com>
17  */
18 
19 #include <common.h>
20 #include <dm.h>
21 #include <spi.h>
22 #include <malloc.h>
23 #include <asm/global_data.h>
24 #include <asm/io.h>
25 #include <linux/bitops.h>
26 #include <omap3_spi.h>
27 
28 DECLARE_GLOBAL_DATA_PTR;
29 
30 struct omap2_mcspi_platform_config {
31 	unsigned int regs_offset;
32 };
33 
34 struct omap3_spi_priv {
35 	struct mcspi *regs;
36 	unsigned int cs;
37 	unsigned int freq;
38 	unsigned int mode;
39 	unsigned int wordlen;
40 	unsigned int pin_dir:1;
41 
42 	bool bus_claimed;
43 };
44 
omap3_spi_write_chconf(struct omap3_spi_priv * priv,int val)45 static void omap3_spi_write_chconf(struct omap3_spi_priv *priv, int val)
46 {
47 	writel(val, &priv->regs->channel[priv->cs].chconf);
48 	/* Flash post writes to make immediate effect */
49 	readl(&priv->regs->channel[priv->cs].chconf);
50 }
51 
omap3_spi_set_enable(struct omap3_spi_priv * priv,int enable)52 static void omap3_spi_set_enable(struct omap3_spi_priv *priv, int enable)
53 {
54 	writel(enable, &priv->regs->channel[priv->cs].chctrl);
55 	/* Flash post writes to make immediate effect */
56 	readl(&priv->regs->channel[priv->cs].chctrl);
57 }
58 
omap3_spi_write(struct omap3_spi_priv * priv,unsigned int len,const void * txp,unsigned long flags)59 static int omap3_spi_write(struct omap3_spi_priv *priv, unsigned int len,
60 			   const void *txp, unsigned long flags)
61 {
62 	ulong start;
63 	int i, chconf;
64 
65 	chconf = readl(&priv->regs->channel[priv->cs].chconf);
66 
67 	/* Enable the channel */
68 	omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
69 
70 	chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
71 	chconf |= (priv->wordlen - 1) << 7;
72 	chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
73 	chconf |= OMAP3_MCSPI_CHCONF_FORCE;
74 	omap3_spi_write_chconf(priv, chconf);
75 
76 	for (i = 0; i < len; i++) {
77 		/* wait till TX register is empty (TXS == 1) */
78 		start = get_timer(0);
79 		while (!(readl(&priv->regs->channel[priv->cs].chstat) &
80 			 OMAP3_MCSPI_CHSTAT_TXS)) {
81 			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
82 				printf("SPI TXS timed out, status=0x%08x\n",
83 					readl(&priv->regs->channel[priv->cs].chstat));
84 				return -1;
85 			}
86 		}
87 		/* Write the data */
88 		unsigned int *tx = &priv->regs->channel[priv->cs].tx;
89 		if (priv->wordlen > 16)
90 			writel(((u32 *)txp)[i], tx);
91 		else if (priv->wordlen > 8)
92 			writel(((u16 *)txp)[i], tx);
93 		else
94 			writel(((u8 *)txp)[i], tx);
95 	}
96 
97 	/* wait to finish of transfer */
98 	while ((readl(&priv->regs->channel[priv->cs].chstat) &
99 			(OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) !=
100 			(OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS))
101 		;
102 
103 	/* Disable the channel otherwise the next immediate RX will get affected */
104 	omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
105 
106 	if (flags & SPI_XFER_END) {
107 
108 		chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
109 		omap3_spi_write_chconf(priv, chconf);
110 	}
111 	return 0;
112 }
113 
omap3_spi_read(struct omap3_spi_priv * priv,unsigned int len,void * rxp,unsigned long flags)114 static int omap3_spi_read(struct omap3_spi_priv *priv, unsigned int len,
115 			  void *rxp, unsigned long flags)
116 {
117 	int i, chconf;
118 	ulong start;
119 
120 	chconf = readl(&priv->regs->channel[priv->cs].chconf);
121 
122 	/* Enable the channel */
123 	omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
124 
125 	chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
126 	chconf |= (priv->wordlen - 1) << 7;
127 	chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
128 	chconf |= OMAP3_MCSPI_CHCONF_FORCE;
129 	omap3_spi_write_chconf(priv, chconf);
130 
131 	writel(0, &priv->regs->channel[priv->cs].tx);
132 
133 	for (i = 0; i < len; i++) {
134 		start = get_timer(0);
135 		/* Wait till RX register contains data (RXS == 1) */
136 		while (!(readl(&priv->regs->channel[priv->cs].chstat) &
137 			 OMAP3_MCSPI_CHSTAT_RXS)) {
138 			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
139 				printf("SPI RXS timed out, status=0x%08x\n",
140 					readl(&priv->regs->channel[priv->cs].chstat));
141 				return -1;
142 			}
143 		}
144 
145 		/* Disable the channel to prevent furher receiving */
146 		if (i == (len - 1))
147 			omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
148 
149 		/* Read the data */
150 		unsigned int *rx = &priv->regs->channel[priv->cs].rx;
151 		if (priv->wordlen > 16)
152 			((u32 *)rxp)[i] = readl(rx);
153 		else if (priv->wordlen > 8)
154 			((u16 *)rxp)[i] = (u16)readl(rx);
155 		else
156 			((u8 *)rxp)[i] = (u8)readl(rx);
157 	}
158 
159 	if (flags & SPI_XFER_END) {
160 		chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
161 		omap3_spi_write_chconf(priv, chconf);
162 	}
163 
164 	return 0;
165 }
166 
167 /*McSPI Transmit Receive Mode*/
omap3_spi_txrx(struct omap3_spi_priv * priv,unsigned int len,const void * txp,void * rxp,unsigned long flags)168 static int omap3_spi_txrx(struct omap3_spi_priv *priv, unsigned int len,
169 			  const void *txp, void *rxp, unsigned long flags)
170 {
171 	ulong start;
172 	int chconf, i = 0;
173 
174 	chconf = readl(&priv->regs->channel[priv->cs].chconf);
175 
176 	/*Enable SPI channel*/
177 	omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
178 
179 	/*set TRANSMIT-RECEIVE Mode*/
180 	chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
181 	chconf |= (priv->wordlen - 1) << 7;
182 	chconf |= OMAP3_MCSPI_CHCONF_FORCE;
183 	omap3_spi_write_chconf(priv, chconf);
184 
185 	/*Shift in and out 1 byte at time*/
186 	for (i=0; i < len; i++){
187 		/* Write: wait for TX empty (TXS == 1)*/
188 		start = get_timer(0);
189 		while (!(readl(&priv->regs->channel[priv->cs].chstat) &
190 			 OMAP3_MCSPI_CHSTAT_TXS)) {
191 			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
192 				printf("SPI TXS timed out, status=0x%08x\n",
193 					readl(&priv->regs->channel[priv->cs].chstat));
194 				return -1;
195 			}
196 		}
197 		/* Write the data */
198 		unsigned int *tx = &priv->regs->channel[priv->cs].tx;
199 		if (priv->wordlen > 16)
200 			writel(((u32 *)txp)[i], tx);
201 		else if (priv->wordlen > 8)
202 			writel(((u16 *)txp)[i], tx);
203 		else
204 			writel(((u8 *)txp)[i], tx);
205 
206 		/*Read: wait for RX containing data (RXS == 1)*/
207 		start = get_timer(0);
208 		while (!(readl(&priv->regs->channel[priv->cs].chstat) &
209 			 OMAP3_MCSPI_CHSTAT_RXS)) {
210 			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
211 				printf("SPI RXS timed out, status=0x%08x\n",
212 					readl(&priv->regs->channel[priv->cs].chstat));
213 				return -1;
214 			}
215 		}
216 		/* Read the data */
217 		unsigned int *rx = &priv->regs->channel[priv->cs].rx;
218 		if (priv->wordlen > 16)
219 			((u32 *)rxp)[i] = readl(rx);
220 		else if (priv->wordlen > 8)
221 			((u16 *)rxp)[i] = (u16)readl(rx);
222 		else
223 			((u8 *)rxp)[i] = (u8)readl(rx);
224 	}
225 	/* Disable the channel */
226 	omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
227 
228 	/*if transfer must be terminated disable the channel*/
229 	if (flags & SPI_XFER_END) {
230 		chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
231 		omap3_spi_write_chconf(priv, chconf);
232 	}
233 
234 	return 0;
235 }
236 
_spi_xfer(struct omap3_spi_priv * priv,unsigned int bitlen,const void * dout,void * din,unsigned long flags)237 static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen,
238 		     const void *dout, void *din, unsigned long flags)
239 {
240 	unsigned int	len;
241 	int ret = -1;
242 
243 	if (priv->wordlen < 4 || priv->wordlen > 32) {
244 		printf("omap3_spi: invalid wordlen %d\n", priv->wordlen);
245 		return -1;
246 	}
247 
248 	if (bitlen % priv->wordlen)
249 		return -1;
250 
251 	len = bitlen / priv->wordlen;
252 
253 	if (bitlen == 0) {	 /* only change CS */
254 		int chconf = readl(&priv->regs->channel[priv->cs].chconf);
255 
256 		if (flags & SPI_XFER_BEGIN) {
257 			omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
258 			chconf |= OMAP3_MCSPI_CHCONF_FORCE;
259 			omap3_spi_write_chconf(priv, chconf);
260 		}
261 		if (flags & SPI_XFER_END) {
262 			chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
263 			omap3_spi_write_chconf(priv, chconf);
264 			omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
265 		}
266 		ret = 0;
267 	} else {
268 		if (dout != NULL && din != NULL)
269 			ret = omap3_spi_txrx(priv, len, dout, din, flags);
270 		else if (dout != NULL)
271 			ret = omap3_spi_write(priv, len, dout, flags);
272 		else if (din != NULL)
273 			ret = omap3_spi_read(priv, len, din, flags);
274 	}
275 	return ret;
276 }
277 
_omap3_spi_set_speed(struct omap3_spi_priv * priv)278 static void _omap3_spi_set_speed(struct omap3_spi_priv *priv)
279 {
280 	uint32_t confr, div = 0;
281 
282 	confr = readl(&priv->regs->channel[priv->cs].chconf);
283 
284 	/* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */
285 	if (priv->freq) {
286 		while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div))
287 					> priv->freq)
288 			div++;
289 	} else {
290 		 div = 0xC;
291 	}
292 
293 	/* set clock divisor */
294 	confr &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK;
295 	confr |= div << 2;
296 
297 	omap3_spi_write_chconf(priv, confr);
298 }
299 
_omap3_spi_set_mode(struct omap3_spi_priv * priv)300 static void _omap3_spi_set_mode(struct omap3_spi_priv *priv)
301 {
302 	uint32_t confr;
303 
304 	confr = readl(&priv->regs->channel[priv->cs].chconf);
305 
306 	/* standard 4-wire master mode:  SCK, MOSI/out, MISO/in, nCS
307 	 * REVISIT: this controller could support SPI_3WIRE mode.
308 	 */
309 	if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
310 		confr &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
311 		confr |= OMAP3_MCSPI_CHCONF_DPE0;
312 	} else {
313 		confr &= ~OMAP3_MCSPI_CHCONF_DPE0;
314 		confr |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1;
315 	}
316 
317 	/* set SPI mode 0..3 */
318 	confr &= ~(OMAP3_MCSPI_CHCONF_POL | OMAP3_MCSPI_CHCONF_PHA);
319 	if (priv->mode & SPI_CPHA)
320 		confr |= OMAP3_MCSPI_CHCONF_PHA;
321 	if (priv->mode & SPI_CPOL)
322 		confr |= OMAP3_MCSPI_CHCONF_POL;
323 
324 	/* set chipselect polarity; manage with FORCE */
325 	if (!(priv->mode & SPI_CS_HIGH))
326 		confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */
327 	else
328 		confr &= ~OMAP3_MCSPI_CHCONF_EPOL;
329 
330 	/* Transmit & receive mode */
331 	confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
332 
333 	omap3_spi_write_chconf(priv, confr);
334 }
335 
_omap3_spi_set_wordlen(struct omap3_spi_priv * priv)336 static void _omap3_spi_set_wordlen(struct omap3_spi_priv *priv)
337 {
338 	unsigned int confr;
339 
340 	/* McSPI individual channel configuration */
341 	confr = readl(&priv->regs->channel[priv->cs].chconf);
342 
343 	/* wordlength */
344 	confr &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
345 	confr |= (priv->wordlen - 1) << 7;
346 
347 	omap3_spi_write_chconf(priv, confr);
348 }
349 
spi_reset(struct mcspi * regs)350 static void spi_reset(struct mcspi *regs)
351 {
352 	unsigned int tmp;
353 
354 	writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &regs->sysconfig);
355 	do {
356 		tmp = readl(&regs->sysstatus);
357 	} while (!(tmp & OMAP3_MCSPI_SYSSTATUS_RESETDONE));
358 
359 	writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE |
360 	       OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP |
361 	       OMAP3_MCSPI_SYSCONFIG_SMARTIDLE, &regs->sysconfig);
362 
363 	writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &regs->wakeupenable);
364 }
365 
_omap3_spi_claim_bus(struct omap3_spi_priv * priv)366 static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv)
367 {
368 	unsigned int conf;
369 	/*
370 	 * setup when switching from (reset default) slave mode
371 	 * to single-channel master mode
372 	 */
373 	conf = readl(&priv->regs->modulctrl);
374 	conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS);
375 	conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
376 
377 	writel(conf, &priv->regs->modulctrl);
378 
379 	priv->bus_claimed = true;
380 }
381 
omap3_spi_claim_bus(struct udevice * dev)382 static int omap3_spi_claim_bus(struct udevice *dev)
383 {
384 	struct udevice *bus = dev->parent;
385 	struct omap3_spi_priv *priv = dev_get_priv(bus);
386 	struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
387 
388 	priv->cs = slave_plat->cs;
389 	if (!priv->freq)
390 		priv->freq = slave_plat->max_hz;
391 
392 	_omap3_spi_claim_bus(priv);
393 	_omap3_spi_set_speed(priv);
394 	_omap3_spi_set_mode(priv);
395 
396 	return 0;
397 }
398 
omap3_spi_release_bus(struct udevice * dev)399 static int omap3_spi_release_bus(struct udevice *dev)
400 {
401 	struct udevice *bus = dev->parent;
402 	struct omap3_spi_priv *priv = dev_get_priv(bus);
403 
404 	writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl);
405 
406 	priv->bus_claimed = false;
407 
408 	return 0;
409 }
410 
omap3_spi_set_wordlen(struct udevice * dev,unsigned int wordlen)411 static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
412 {
413 	struct udevice *bus = dev->parent;
414 	struct omap3_spi_priv *priv = dev_get_priv(bus);
415 	struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
416 
417 	priv->cs = slave_plat->cs;
418 	priv->wordlen = wordlen;
419 	_omap3_spi_set_wordlen(priv);
420 
421 	return 0;
422 }
423 
omap3_spi_probe(struct udevice * dev)424 static int omap3_spi_probe(struct udevice *dev)
425 {
426 	struct omap3_spi_priv *priv = dev_get_priv(dev);
427 	struct omap3_spi_plat *plat = dev_get_plat(dev);
428 
429 	priv->regs = plat->regs;
430 	priv->pin_dir = plat->pin_dir;
431 	priv->wordlen = SPI_DEFAULT_WORDLEN;
432 
433 	spi_reset(priv->regs);
434 
435 	return 0;
436 }
437 
omap3_spi_xfer(struct udevice * dev,unsigned int bitlen,const void * dout,void * din,unsigned long flags)438 static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen,
439 			    const void *dout, void *din, unsigned long flags)
440 {
441 	struct udevice *bus = dev->parent;
442 	struct omap3_spi_priv *priv = dev_get_priv(bus);
443 
444 	return _spi_xfer(priv, bitlen, dout, din, flags);
445 }
446 
omap3_spi_set_speed(struct udevice * dev,unsigned int speed)447 static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed)
448 {
449 
450 	struct omap3_spi_priv *priv = dev_get_priv(dev);
451 
452 	priv->freq = speed;
453 	if (priv->bus_claimed)
454 		_omap3_spi_set_speed(priv);
455 
456 	return 0;
457 }
458 
omap3_spi_set_mode(struct udevice * dev,uint mode)459 static int omap3_spi_set_mode(struct udevice *dev, uint mode)
460 {
461 	struct omap3_spi_priv *priv = dev_get_priv(dev);
462 
463 	priv->mode = mode;
464 
465 	if (priv->bus_claimed)
466 		_omap3_spi_set_mode(priv);
467 
468 	return 0;
469 }
470 
471 static const struct dm_spi_ops omap3_spi_ops = {
472 	.claim_bus      = omap3_spi_claim_bus,
473 	.release_bus    = omap3_spi_release_bus,
474 	.set_wordlen    = omap3_spi_set_wordlen,
475 	.xfer	    = omap3_spi_xfer,
476 	.set_speed      = omap3_spi_set_speed,
477 	.set_mode	= omap3_spi_set_mode,
478 	/*
479 	 * cs_info is not needed, since we require all chip selects to be
480 	 * in the device tree explicitly
481 	 */
482 };
483 
484 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
485 static struct omap2_mcspi_platform_config omap2_pdata = {
486 	.regs_offset = 0,
487 };
488 
489 static struct omap2_mcspi_platform_config omap4_pdata = {
490 	.regs_offset = OMAP4_MCSPI_REG_OFFSET,
491 };
492 
omap3_spi_of_to_plat(struct udevice * dev)493 static int omap3_spi_of_to_plat(struct udevice *dev)
494 {
495 	struct omap2_mcspi_platform_config *data =
496 		(struct omap2_mcspi_platform_config *)dev_get_driver_data(dev);
497 	struct omap3_spi_plat *plat = dev_get_plat(dev);
498 
499 	plat->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset);
500 
501 	if (dev_read_bool(dev, "ti,pindir-d0-out-d1-in"))
502 		plat->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
503 	else
504 		plat->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
505 
506 	return 0;
507 }
508 
509 static const struct udevice_id omap3_spi_ids[] = {
510 	{ .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
511 	{ .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
512 	{ }
513 };
514 #endif
515 U_BOOT_DRIVER(omap3_spi) = {
516 	.name   = "omap3_spi",
517 	.id     = UCLASS_SPI,
518 	.flags	= DM_FLAG_PRE_RELOC,
519 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
520 	.of_match = omap3_spi_ids,
521 	.of_to_plat = omap3_spi_of_to_plat,
522 	.plat_auto	= sizeof(struct omap3_spi_plat),
523 #endif
524 	.probe = omap3_spi_probe,
525 	.ops    = &omap3_spi_ops,
526 	.priv_auto	= sizeof(struct omap3_spi_priv),
527 };
528