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 - https://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
28DECLARE_GLOBAL_DATA_PTR;
29
30struct omap2_mcspi_platform_config {
31	unsigned int regs_offset;
32};
33
34struct 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
45static 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
52static 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
59static 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
114static 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 further 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*/
168static 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
237static 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
278static 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
300static 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
336static 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
350static void spi_reset(struct omap3_spi_priv *priv)
351{
352	unsigned int tmp;
353
354	writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &priv->regs->sysconfig);
355	do {
356		tmp = readl(&priv->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, &priv->regs->sysconfig);
362
363	writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &priv->regs->wakeupenable);
364
365	/*
366	 * Set the same default mode for each channel, especially CS polarity
367	 * which must be common for all SPI slaves before any transfer.
368	 */
369	for (priv->cs = 0 ; priv->cs < OMAP4_MCSPI_CHAN_NB ; priv->cs++)
370		_omap3_spi_set_mode(priv);
371	priv->cs = 0;
372}
373
374static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv)
375{
376	unsigned int conf;
377	/*
378	 * setup when switching from (reset default) slave mode
379	 * to single-channel master mode
380	 */
381	conf = readl(&priv->regs->modulctrl);
382	conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS);
383	conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
384
385	writel(conf, &priv->regs->modulctrl);
386
387	priv->bus_claimed = true;
388}
389
390static int omap3_spi_claim_bus(struct udevice *dev)
391{
392	struct udevice *bus = dev->parent;
393	struct omap3_spi_priv *priv = dev_get_priv(bus);
394	struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
395
396	priv->cs = slave_plat->cs;
397	if (!priv->freq)
398		priv->freq = slave_plat->max_hz;
399
400	_omap3_spi_claim_bus(priv);
401	_omap3_spi_set_speed(priv);
402	_omap3_spi_set_mode(priv);
403
404	return 0;
405}
406
407static int omap3_spi_release_bus(struct udevice *dev)
408{
409	struct udevice *bus = dev->parent;
410	struct omap3_spi_priv *priv = dev_get_priv(bus);
411
412	writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl);
413
414	priv->bus_claimed = false;
415
416	return 0;
417}
418
419static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
420{
421	struct udevice *bus = dev->parent;
422	struct omap3_spi_priv *priv = dev_get_priv(bus);
423	struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
424
425	priv->cs = slave_plat->cs;
426	priv->wordlen = wordlen;
427	_omap3_spi_set_wordlen(priv);
428
429	return 0;
430}
431
432static int omap3_spi_probe(struct udevice *dev)
433{
434	struct omap3_spi_priv *priv = dev_get_priv(dev);
435	struct omap3_spi_plat *plat = dev_get_plat(dev);
436
437	priv->regs = plat->regs;
438	priv->pin_dir = plat->pin_dir;
439	priv->wordlen = SPI_DEFAULT_WORDLEN;
440
441	spi_reset(priv);
442
443	return 0;
444}
445
446static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen,
447			    const void *dout, void *din, unsigned long flags)
448{
449	struct udevice *bus = dev->parent;
450	struct omap3_spi_priv *priv = dev_get_priv(bus);
451
452	return _spi_xfer(priv, bitlen, dout, din, flags);
453}
454
455static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed)
456{
457
458	struct omap3_spi_priv *priv = dev_get_priv(dev);
459
460	priv->freq = speed;
461	if (priv->bus_claimed)
462		_omap3_spi_set_speed(priv);
463
464	return 0;
465}
466
467static int omap3_spi_set_mode(struct udevice *dev, uint mode)
468{
469	struct omap3_spi_priv *priv = dev_get_priv(dev);
470
471	priv->mode = mode;
472
473	if (priv->bus_claimed)
474		_omap3_spi_set_mode(priv);
475
476	return 0;
477}
478
479static const struct dm_spi_ops omap3_spi_ops = {
480	.claim_bus      = omap3_spi_claim_bus,
481	.release_bus    = omap3_spi_release_bus,
482	.set_wordlen    = omap3_spi_set_wordlen,
483	.xfer	    = omap3_spi_xfer,
484	.set_speed      = omap3_spi_set_speed,
485	.set_mode	= omap3_spi_set_mode,
486	/*
487	 * cs_info is not needed, since we require all chip selects to be
488	 * in the device tree explicitly
489	 */
490};
491
492#if CONFIG_IS_ENABLED(OF_REAL)
493static struct omap2_mcspi_platform_config omap2_pdata = {
494	.regs_offset = 0,
495};
496
497static struct omap2_mcspi_platform_config omap4_pdata = {
498	.regs_offset = OMAP4_MCSPI_REG_OFFSET,
499};
500
501static int omap3_spi_of_to_plat(struct udevice *dev)
502{
503	struct omap2_mcspi_platform_config *data =
504		(struct omap2_mcspi_platform_config *)dev_get_driver_data(dev);
505	struct omap3_spi_plat *plat = dev_get_plat(dev);
506
507	plat->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset);
508
509	if (dev_read_bool(dev, "ti,pindir-d0-out-d1-in"))
510		plat->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
511	else
512		plat->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
513
514	return 0;
515}
516
517static const struct udevice_id omap3_spi_ids[] = {
518	{ .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
519	{ .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
520	{ }
521};
522#endif
523U_BOOT_DRIVER(omap3_spi) = {
524	.name   = "omap3_spi",
525	.id     = UCLASS_SPI,
526	.flags	= DM_FLAG_PRE_RELOC,
527#if CONFIG_IS_ENABLED(OF_REAL)
528	.of_match = omap3_spi_ids,
529	.of_to_plat = omap3_spi_of_to_plat,
530	.plat_auto	= sizeof(struct omap3_spi_plat),
531#endif
532	.probe = omap3_spi_probe,
533	.ops    = &omap3_spi_ops,
534	.priv_auto	= sizeof(struct omap3_spi_priv),
535};
536