1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
4 * Christophe Ricard <christophe.ricard@gmail.com>
6 * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com>
8 * Driver for McSPI controller on OMAP3. Based on davinci_spi.c
9 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
11 * Copyright (C) 2007 Atmel Corporation
13 * Parts taken from linux/drivers/spi/omap2_mcspi.c
14 * Copyright (C) 2005, 2006 Nokia Corporation
16 * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com>
23 #include <asm/global_data.h>
25 #include <linux/bitops.h>
26 #include <omap3_spi.h>
28 DECLARE_GLOBAL_DATA_PTR
;
30 struct omap2_mcspi_platform_config
{
31 unsigned int regs_offset
;
34 struct omap3_spi_priv
{
40 unsigned int pin_dir
:1;
45 static void omap3_spi_write_chconf(struct omap3_spi_priv
*priv
, int val
)
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
);
52 static void omap3_spi_set_enable(struct omap3_spi_priv
*priv
, int enable
)
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
);
59 static int omap3_spi_write(struct omap3_spi_priv
*priv
, unsigned int len
,
60 const void *txp
, unsigned long flags
)
65 chconf
= readl(&priv
->regs
->channel
[priv
->cs
].chconf
);
67 /* Enable the channel */
68 omap3_spi_set_enable(priv
, OMAP3_MCSPI_CHCTRL_EN
);
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
);
76 for (i
= 0; i
< len
; i
++) {
77 /* wait till TX register is empty (TXS == 1) */
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
));
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
);
94 writel(((u8
*)txp
)[i
], tx
);
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
))
103 /* Disable the channel otherwise the next immediate RX will get affected */
104 omap3_spi_set_enable(priv
, OMAP3_MCSPI_CHCTRL_DIS
);
106 if (flags
& SPI_XFER_END
) {
108 chconf
&= ~OMAP3_MCSPI_CHCONF_FORCE
;
109 omap3_spi_write_chconf(priv
, chconf
);
114 static int omap3_spi_read(struct omap3_spi_priv
*priv
, unsigned int len
,
115 void *rxp
, unsigned long flags
)
120 chconf
= readl(&priv
->regs
->channel
[priv
->cs
].chconf
);
122 /* Enable the channel */
123 omap3_spi_set_enable(priv
, OMAP3_MCSPI_CHCTRL_EN
);
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
);
131 writel(0, &priv
->regs
->channel
[priv
->cs
].tx
);
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
));
145 /* Disable the channel to prevent furher receiving */
147 omap3_spi_set_enable(priv
, OMAP3_MCSPI_CHCTRL_DIS
);
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
);
156 ((u8
*)rxp
)[i
] = (u8
)readl(rx
);
159 if (flags
& SPI_XFER_END
) {
160 chconf
&= ~OMAP3_MCSPI_CHCONF_FORCE
;
161 omap3_spi_write_chconf(priv
, chconf
);
167 /*McSPI Transmit Receive Mode*/
168 static int omap3_spi_txrx(struct omap3_spi_priv
*priv
, unsigned int len
,
169 const void *txp
, void *rxp
, unsigned long flags
)
174 chconf
= readl(&priv
->regs
->channel
[priv
->cs
].chconf
);
176 /*Enable SPI channel*/
177 omap3_spi_set_enable(priv
, OMAP3_MCSPI_CHCTRL_EN
);
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
);
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
));
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
);
204 writel(((u8
*)txp
)[i
], tx
);
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
));
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
);
223 ((u8
*)rxp
)[i
] = (u8
)readl(rx
);
225 /* Disable the channel */
226 omap3_spi_set_enable(priv
, OMAP3_MCSPI_CHCTRL_DIS
);
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
);
237 static int _spi_xfer(struct omap3_spi_priv
*priv
, unsigned int bitlen
,
238 const void *dout
, void *din
, unsigned long flags
)
243 if (priv
->wordlen
< 4 || priv
->wordlen
> 32) {
244 printf("omap3_spi: invalid wordlen %d\n", priv
->wordlen
);
248 if (bitlen
% priv
->wordlen
)
251 len
= bitlen
/ priv
->wordlen
;
253 if (bitlen
== 0) { /* only change CS */
254 int chconf
= readl(&priv
->regs
->channel
[priv
->cs
].chconf
);
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
);
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
);
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
);
278 static void _omap3_spi_set_speed(struct omap3_spi_priv
*priv
)
280 uint32_t confr
, div
= 0;
282 confr
= readl(&priv
->regs
->channel
[priv
->cs
].chconf
);
284 /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */
286 while (div
<= 0xC && (OMAP3_MCSPI_MAX_FREQ
/ (1 << div
))
293 /* set clock divisor */
294 confr
&= ~OMAP3_MCSPI_CHCONF_CLKD_MASK
;
297 omap3_spi_write_chconf(priv
, confr
);
300 static void _omap3_spi_set_mode(struct omap3_spi_priv
*priv
)
304 confr
= readl(&priv
->regs
->channel
[priv
->cs
].chconf
);
306 /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS
307 * REVISIT: this controller could support SPI_3WIRE mode.
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
;
313 confr
&= ~OMAP3_MCSPI_CHCONF_DPE0
;
314 confr
|= OMAP3_MCSPI_CHCONF_IS
|OMAP3_MCSPI_CHCONF_DPE1
;
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
;
324 /* set chipselect polarity; manage with FORCE */
325 if (!(priv
->mode
& SPI_CS_HIGH
))
326 confr
|= OMAP3_MCSPI_CHCONF_EPOL
; /* active-low; normal */
328 confr
&= ~OMAP3_MCSPI_CHCONF_EPOL
;
330 /* Transmit & receive mode */
331 confr
&= ~OMAP3_MCSPI_CHCONF_TRM_MASK
;
333 omap3_spi_write_chconf(priv
, confr
);
336 static void _omap3_spi_set_wordlen(struct omap3_spi_priv
*priv
)
340 /* McSPI individual channel configuration */
341 confr
= readl(&priv
->regs
->channel
[priv
->cs
].chconf
);
344 confr
&= ~OMAP3_MCSPI_CHCONF_WL_MASK
;
345 confr
|= (priv
->wordlen
- 1) << 7;
347 omap3_spi_write_chconf(priv
, confr
);
350 static void spi_reset(struct mcspi
*regs
)
354 writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET
, ®s
->sysconfig
);
356 tmp
= readl(®s
->sysstatus
);
357 } while (!(tmp
& OMAP3_MCSPI_SYSSTATUS_RESETDONE
));
359 writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE
|
360 OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP
|
361 OMAP3_MCSPI_SYSCONFIG_SMARTIDLE
, ®s
->sysconfig
);
363 writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN
, ®s
->wakeupenable
);
366 static void _omap3_spi_claim_bus(struct omap3_spi_priv
*priv
)
370 * setup when switching from (reset default) slave mode
371 * to single-channel master mode
373 conf
= readl(&priv
->regs
->modulctrl
);
374 conf
&= ~(OMAP3_MCSPI_MODULCTRL_STEST
| OMAP3_MCSPI_MODULCTRL_MS
);
375 conf
|= OMAP3_MCSPI_MODULCTRL_SINGLE
;
377 writel(conf
, &priv
->regs
->modulctrl
);
379 priv
->bus_claimed
= true;
382 static int omap3_spi_claim_bus(struct udevice
*dev
)
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
);
388 priv
->cs
= slave_plat
->cs
;
390 priv
->freq
= slave_plat
->max_hz
;
392 _omap3_spi_claim_bus(priv
);
393 _omap3_spi_set_speed(priv
);
394 _omap3_spi_set_mode(priv
);
399 static int omap3_spi_release_bus(struct udevice
*dev
)
401 struct udevice
*bus
= dev
->parent
;
402 struct omap3_spi_priv
*priv
= dev_get_priv(bus
);
404 writel(OMAP3_MCSPI_MODULCTRL_MS
, &priv
->regs
->modulctrl
);
406 priv
->bus_claimed
= false;
411 static int omap3_spi_set_wordlen(struct udevice
*dev
, unsigned int wordlen
)
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
);
417 priv
->cs
= slave_plat
->cs
;
418 priv
->wordlen
= wordlen
;
419 _omap3_spi_set_wordlen(priv
);
424 static int omap3_spi_probe(struct udevice
*dev
)
426 struct omap3_spi_priv
*priv
= dev_get_priv(dev
);
427 struct omap3_spi_plat
*plat
= dev_get_plat(dev
);
429 priv
->regs
= plat
->regs
;
430 priv
->pin_dir
= plat
->pin_dir
;
431 priv
->wordlen
= SPI_DEFAULT_WORDLEN
;
433 spi_reset(priv
->regs
);
438 static int omap3_spi_xfer(struct udevice
*dev
, unsigned int bitlen
,
439 const void *dout
, void *din
, unsigned long flags
)
441 struct udevice
*bus
= dev
->parent
;
442 struct omap3_spi_priv
*priv
= dev_get_priv(bus
);
444 return _spi_xfer(priv
, bitlen
, dout
, din
, flags
);
447 static int omap3_spi_set_speed(struct udevice
*dev
, unsigned int speed
)
450 struct omap3_spi_priv
*priv
= dev_get_priv(dev
);
453 if (priv
->bus_claimed
)
454 _omap3_spi_set_speed(priv
);
459 static int omap3_spi_set_mode(struct udevice
*dev
, uint mode
)
461 struct omap3_spi_priv
*priv
= dev_get_priv(dev
);
465 if (priv
->bus_claimed
)
466 _omap3_spi_set_mode(priv
);
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
,
479 * cs_info is not needed, since we require all chip selects to be
480 * in the device tree explicitly
484 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
485 static struct omap2_mcspi_platform_config omap2_pdata
= {
489 static struct omap2_mcspi_platform_config omap4_pdata
= {
490 .regs_offset
= OMAP4_MCSPI_REG_OFFSET
,
493 static int omap3_spi_of_to_plat(struct udevice
*dev
)
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
);
499 plat
->regs
= (struct mcspi
*)(dev_read_addr(dev
) + data
->regs_offset
);
501 if (dev_read_bool(dev
, "ti,pindir-d0-out-d1-in"))
502 plat
->pin_dir
= MCSPI_PINDIR_D0_OUT_D1_IN
;
504 plat
->pin_dir
= MCSPI_PINDIR_D0_IN_D1_OUT
;
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
},
515 U_BOOT_DRIVER(omap3_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
),
524 .probe
= omap3_spi_probe
,
525 .ops
= &omap3_spi_ops
,
526 .priv_auto
= sizeof(struct omap3_spi_priv
),