blob: 0bd4f88926f142bd264625a8ede2f84128f554d7 [file] [log] [blame]
Sekhar Nori4708b172010-01-27 11:10:40 -05001/*
2 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Driver for SPI controller on DaVinci. Based on atmel_spi.c
5 * by Atmel Corporation
6 *
7 * Copyright (C) 2007 Atmel Corporation
8 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02009 * SPDX-License-Identifier: GPL-2.0+
Sekhar Nori4708b172010-01-27 11:10:40 -050010 */
Jagan Tekiccaa8fc2015-06-27 00:51:29 +053011
Sekhar Nori4708b172010-01-27 11:10:40 -050012#include <common.h>
13#include <spi.h>
14#include <malloc.h>
15#include <asm/io.h>
16#include <asm/arch/hardware.h>
Jagan Teki742d53d2015-06-27 00:51:28 +053017
Jagan Teki742d53d2015-06-27 00:51:28 +053018/* SPIGCR0 */
19#define SPIGCR0_SPIENA_MASK 0x1
20#define SPIGCR0_SPIRST_MASK 0x0
21
22/* SPIGCR0 */
23#define SPIGCR1_CLKMOD_MASK BIT(1)
24#define SPIGCR1_MASTER_MASK BIT(0)
25#define SPIGCR1_SPIENA_MASK BIT(24)
26
27/* SPIPC0 */
28#define SPIPC0_DIFUN_MASK BIT(11) /* SIMO */
29#define SPIPC0_DOFUN_MASK BIT(10) /* SOMI */
30#define SPIPC0_CLKFUN_MASK BIT(9) /* CLK */
31#define SPIPC0_EN0FUN_MASK BIT(0)
32
33/* SPIFMT0 */
34#define SPIFMT_SHIFTDIR_SHIFT 20
35#define SPIFMT_POLARITY_SHIFT 17
36#define SPIFMT_PHASE_SHIFT 16
37#define SPIFMT_PRESCALE_SHIFT 8
38
39/* SPIDAT1 */
40#define SPIDAT1_CSHOLD_SHIFT 28
41#define SPIDAT1_CSNR_SHIFT 16
42
43/* SPIDELAY */
44#define SPI_C2TDELAY_SHIFT 24
45#define SPI_T2CDELAY_SHIFT 16
46
47/* SPIBUF */
48#define SPIBUF_RXEMPTY_MASK BIT(31)
49#define SPIBUF_TXFULL_MASK BIT(29)
50
51/* SPIDEF */
52#define SPIDEF_CSDEF0_MASK BIT(0)
53
54#define SPI0_BUS 0
55#define SPI0_BASE CONFIG_SYS_SPI_BASE
56/*
57 * Define default SPI0_NUM_CS as 1 for existing platforms that uses this
58 * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS
59 * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
60 */
61#ifndef CONFIG_SYS_SPI0
62#define SPI0_NUM_CS 1
63#else
64#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS
65#endif
66
67/*
68 * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
69 * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus
70 */
71#ifdef CONFIG_SYS_SPI1
72#define SPI1_BUS 1
73#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS
74#define SPI1_BASE CONFIG_SYS_SPI1_BASE
75#endif
76
77/*
78 * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
79 * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus
80 */
81#ifdef CONFIG_SYS_SPI2
82#define SPI2_BUS 2
83#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS
84#define SPI2_BASE CONFIG_SYS_SPI2_BASE
85#endif
86
Jagan Tekiccaa8fc2015-06-27 00:51:29 +053087/* davinci spi register set */
88struct davinci_spi_regs {
89 dv_reg gcr0; /* 0x00 */
90 dv_reg gcr1; /* 0x04 */
91 dv_reg int0; /* 0x08 */
92 dv_reg lvl; /* 0x0c */
93 dv_reg flg; /* 0x10 */
94 dv_reg pc0; /* 0x14 */
95 dv_reg pc1; /* 0x18 */
96 dv_reg pc2; /* 0x1c */
97 dv_reg pc3; /* 0x20 */
98 dv_reg pc4; /* 0x24 */
99 dv_reg pc5; /* 0x28 */
100 dv_reg rsvd[3];
101 dv_reg dat0; /* 0x38 */
102 dv_reg dat1; /* 0x3c */
103 dv_reg buf; /* 0x40 */
104 dv_reg emu; /* 0x44 */
105 dv_reg delay; /* 0x48 */
106 dv_reg def; /* 0x4c */
107 dv_reg fmt0; /* 0x50 */
108 dv_reg fmt1; /* 0x54 */
109 dv_reg fmt2; /* 0x58 */
110 dv_reg fmt3; /* 0x5c */
111 dv_reg intvec0; /* 0x60 */
112 dv_reg intvec1; /* 0x64 */
113};
114
115/* davinci spi slave */
Jagan Teki742d53d2015-06-27 00:51:28 +0530116struct davinci_spi_slave {
117 struct spi_slave slave;
118 struct davinci_spi_regs *regs;
119 unsigned int freq;
120};
121
122static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave)
123{
124 return container_of(slave, struct davinci_spi_slave, slave);
125}
Sekhar Nori4708b172010-01-27 11:10:40 -0500126
Nick Thompson213e4762010-06-22 11:06:01 -0400127/*
128 * This functions needs to act like a macro to avoid pipeline reloads in the
129 * loops below. Use always_inline. This gains us about 160KiB/s and the bloat
130 * appears to be zero bytes (da830).
131 */
132__attribute__((always_inline))
133static inline u32 davinci_spi_xfer_data(struct davinci_spi_slave *ds, u32 data)
134{
135 u32 buf_reg_val;
136
137 /* send out data */
138 writel(data, &ds->regs->dat1);
139
140 /* wait for the data to clock in/out */
141 while ((buf_reg_val = readl(&ds->regs->buf)) & SPIBUF_RXEMPTY_MASK)
142 ;
143
144 return buf_reg_val;
145}
146
147static int davinci_spi_read(struct spi_slave *slave, unsigned int len,
148 u8 *rxp, unsigned long flags)
149{
150 struct davinci_spi_slave *ds = to_davinci_spi(slave);
151 unsigned int data1_reg_val;
152
153 /* enable CS hold, CS[n] and clear the data bits */
154 data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
155 (slave->cs << SPIDAT1_CSNR_SHIFT));
156
157 /* wait till TXFULL is deasserted */
158 while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
159 ;
160
161 /* preload the TX buffer to avoid clock starvation */
162 writel(data1_reg_val, &ds->regs->dat1);
163
164 /* keep reading 1 byte until only 1 byte left */
165 while ((len--) > 1)
166 *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val);
167
168 /* clear CS hold when we reach the end */
169 if (flags & SPI_XFER_END)
170 data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
171
172 /* read the last byte */
173 *rxp = davinci_spi_xfer_data(ds, data1_reg_val);
174
175 return 0;
176}
177
178static int davinci_spi_write(struct spi_slave *slave, unsigned int len,
Nick Thompson4bbd91f2010-07-05 20:00:40 -0400179 const u8 *txp, unsigned long flags)
Nick Thompson213e4762010-06-22 11:06:01 -0400180{
181 struct davinci_spi_slave *ds = to_davinci_spi(slave);
182 unsigned int data1_reg_val;
183
184 /* enable CS hold and clear the data bits */
185 data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
186 (slave->cs << SPIDAT1_CSNR_SHIFT));
187
188 /* wait till TXFULL is deasserted */
189 while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
190 ;
191
192 /* preload the TX buffer to avoid clock starvation */
193 if (len > 2) {
194 writel(data1_reg_val | *txp++, &ds->regs->dat1);
195 len--;
196 }
197
198 /* keep writing 1 byte until only 1 byte left */
199 while ((len--) > 1)
200 davinci_spi_xfer_data(ds, data1_reg_val | *txp++);
201
202 /* clear CS hold when we reach the end */
203 if (flags & SPI_XFER_END)
204 data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
205
206 /* write the last byte */
207 davinci_spi_xfer_data(ds, data1_reg_val | *txp);
208
209 return 0;
210}
211
212#ifndef CONFIG_SPI_HALF_DUPLEX
213static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len,
214 u8 *rxp, const u8 *txp, unsigned long flags)
215{
216 struct davinci_spi_slave *ds = to_davinci_spi(slave);
217 unsigned int data1_reg_val;
218
219 /* enable CS hold and clear the data bits */
220 data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
221 (slave->cs << SPIDAT1_CSNR_SHIFT));
222
223 /* wait till TXFULL is deasserted */
224 while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
225 ;
226
227 /* keep reading and writing 1 byte until only 1 byte left */
228 while ((len--) > 1)
229 *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val | *txp++);
230
231 /* clear CS hold when we reach the end */
232 if (flags & SPI_XFER_END)
233 data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
234
235 /* read and write the last byte */
236 *rxp = davinci_spi_xfer_data(ds, data1_reg_val | *txp);
237
238 return 0;
239}
240#endif
241
Jagan Tekiccaa8fc2015-06-27 00:51:29 +0530242int spi_cs_is_valid(unsigned int bus, unsigned int cs)
243{
244 int ret = 0;
245
246 switch (bus) {
247 case SPI0_BUS:
248 if (cs < SPI0_NUM_CS)
249 ret = 1;
250 break;
251#ifdef CONFIG_SYS_SPI1
252 case SPI1_BUS:
253 if (cs < SPI1_NUM_CS)
254 ret = 1;
255 break;
256#endif
257#ifdef CONFIG_SYS_SPI2
258 case SPI2_BUS:
259 if (cs < SPI2_NUM_CS)
260 ret = 1;
261 break;
262#endif
263 default:
264 /* Invalid bus number. Do nothing */
265 break;
266 }
267 return ret;
268}
269
270void spi_cs_activate(struct spi_slave *slave)
271{
272 /* do nothing */
273}
274
275void spi_cs_deactivate(struct spi_slave *slave)
276{
277 /* do nothing */
278}
279
280void spi_init(void)
281{
282 /* do nothing */
283}
284
285struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
286 unsigned int max_hz, unsigned int mode)
287{
288 struct davinci_spi_slave *ds;
289
290 if (!spi_cs_is_valid(bus, cs))
291 return NULL;
292
293 ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs);
294 if (!ds)
295 return NULL;
296
297 switch (bus) {
298 case SPI0_BUS:
299 ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
300 break;
301#ifdef CONFIG_SYS_SPI1
302 case SPI1_BUS:
303 ds->regs = (struct davinci_spi_regs *)SPI1_BASE;
304 break;
305#endif
306#ifdef CONFIG_SYS_SPI2
307 case SPI2_BUS:
308 ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
309 break;
310#endif
311 default: /* Invalid bus number */
312 return NULL;
313 }
314
315 ds->freq = max_hz;
316
317 return &ds->slave;
318}
319
320void spi_free_slave(struct spi_slave *slave)
321{
322 struct davinci_spi_slave *ds = to_davinci_spi(slave);
323
324 free(ds);
325}
326
327int spi_claim_bus(struct spi_slave *slave)
328{
329 struct davinci_spi_slave *ds = to_davinci_spi(slave);
330 unsigned int scalar;
331
332 /* Enable the SPI hardware */
333 writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
334 udelay(1000);
335 writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0);
336
337 /* Set master mode, powered up and not activated */
338 writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
339
340 /* CS, CLK, SIMO and SOMI are functional pins */
341 writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
342 SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
343
344 /* setup format */
345 scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF;
346
347 /*
348 * Use following format:
349 * character length = 8,
350 * clock signal delayed by half clk cycle,
351 * clock low in idle state - Mode 0,
352 * MSB shifted out first
353 */
354 writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
355 (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
356
357 /*
358 * Including a minor delay. No science here. Should be good even with
359 * no delay
360 */
361 writel((50 << SPI_C2TDELAY_SHIFT) |
362 (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay);
363
364 /* default chip select register */
365 writel(SPIDEF_CSDEF0_MASK, &ds->regs->def);
366
367 /* no interrupts */
368 writel(0, &ds->regs->int0);
369 writel(0, &ds->regs->lvl);
370
371 /* enable SPI */
372 writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
373
374 return 0;
375}
376
377void spi_release_bus(struct spi_slave *slave)
378{
379 struct davinci_spi_slave *ds = to_davinci_spi(slave);
380
381 /* Disable the SPI hardware */
382 writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
383}
384
Sekhar Nori4708b172010-01-27 11:10:40 -0500385int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
Nick Thompson4bbd91f2010-07-05 20:00:40 -0400386 const void *dout, void *din, unsigned long flags)
Sekhar Nori4708b172010-01-27 11:10:40 -0500387{
Nick Thompson213e4762010-06-22 11:06:01 -0400388 unsigned int len;
Sekhar Nori4708b172010-01-27 11:10:40 -0500389
Sekhar Nori4708b172010-01-27 11:10:40 -0500390 if (bitlen == 0)
391 /* Finish any previously submitted transfers */
392 goto out;
393
394 /*
395 * It's not clear how non-8-bit-aligned transfers are supposed to be
396 * represented as a stream of bytes...this is a limitation of
397 * the current SPI interface - here we terminate on receiving such a
398 * transfer request.
399 */
400 if (bitlen % 8) {
401 /* Errors always terminate an ongoing transfer */
402 flags |= SPI_XFER_END;
403 goto out;
404 }
405
406 len = bitlen / 8;
407
Nick Thompson213e4762010-06-22 11:06:01 -0400408 if (!dout)
409 return davinci_spi_read(slave, len, din, flags);
410 else if (!din)
411 return davinci_spi_write(slave, len, dout, flags);
412#ifndef CONFIG_SPI_HALF_DUPLEX
413 else
414 return davinci_spi_read_write(slave, len, din, dout, flags);
Nick Thompson4bbd91f2010-07-05 20:00:40 -0400415#else
416 printf("SPI full duplex transaction requested with "
417 "CONFIG_SPI_HALF_DUPLEX defined.\n");
418 flags |= SPI_XFER_END;
Nick Thompson213e4762010-06-22 11:06:01 -0400419#endif
Sekhar Nori4708b172010-01-27 11:10:40 -0500420
421out:
422 if (flags & SPI_XFER_END) {
Nick Thompson213e4762010-06-22 11:06:01 -0400423 u8 dummy = 0;
424 davinci_spi_write(slave, 1, &dummy, flags);
Sekhar Nori4708b172010-01-27 11:10:40 -0500425 }
426 return 0;
427}