[lantiq]
[openwrt.git] / target / linux / lantiq / patches / 915-falcon-spi-flash.patch
1 --- a/drivers/spi/Makefile
2 +++ b/drivers/spi/Makefile
3 @@ -22,6 +22,7 @@ obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.
4 obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o
5 obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o
6 obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o
7 +obj-$(CONFIG_SPI_FALCON) += spi_falcon.o
8 obj-$(CONFIG_SPI_GPIO) += spi_gpio.o
9 obj-$(CONFIG_SPI_GPIO_OLD) += spi_gpio_old.o
10 obj-$(CONFIG_SPI_IMX) += spi_imx.o
11 --- /dev/null
12 +++ b/drivers/spi/spi_falcon.c
13 @@ -0,0 +1,471 @@
14 +/*
15 + * This program is free software; you can redistribute it and/or modify
16 + * it under the terms of the GNU General Public License as published by
17 + * the Free Software Foundation; either version 2 of the License, or
18 + * (at your option) any later version.
19 + *
20 + * This program is distributed in the hope that it will be useful,
21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 + * GNU General Public License for more details.
24 + *
25 + * You should have received a copy of the GNU General Public License
26 + * along with this program; if not, write to the Free Software
27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
28 + */
29 +
30 +#include <linux/module.h>
31 +#include <linux/device.h>
32 +#include <linux/platform_device.h>
33 +#include <linux/spi/spi.h>
34 +#include <linux/delay.h>
35 +#include <linux/workqueue.h>
36 +
37 +#include <lantiq.h> /* ebu_lock */
38 +#include <falcon/ebu_reg.h>
39 +#include <falcon/sys1_reg.h>
40 +
41 +#define DRV_NAME "falcon_spi"
42 +
43 +#define FALCON_SPI_XFER_BEGIN (1 << 0)
44 +#define FALCON_SPI_XFER_END (1 << 1)
45 +
46 +/* mapping for access macros */
47 +#define reg_r32(reg) __raw_readl(reg)
48 +#define reg_w32(val, reg) __raw_writel(val, reg)
49 +#define reg_w32_mask(clear, set, reg) reg_w32((reg_r32(reg) \
50 + & ~(clear)) | (set), reg)
51 +#define reg_r32_table(reg, idx) reg_r32(&((uint32_t *)&reg)[idx])
52 +#define reg_w32_table(val, reg, idx) reg_w32(val, &((uint32_t *)&reg)[idx])
53 +
54 +#define ebu (priv->ebu_membase)
55 +#define sys1 (priv->sys1_membase)
56 +
57 +struct falcon_spi {
58 + u32 sfcmd; /* for caching of opcode, direction, ... */
59 +
60 + struct spi_master *master;
61 +
62 + struct gpon_reg_ebu __iomem *ebu_membase;
63 + struct gpon_reg_sys1 __iomem *sys1_membase;
64 +};
65 +
66 +int falcon_spi_xfer(struct spi_device *spi,
67 + struct spi_transfer *t,
68 + unsigned long flags)
69 +{
70 + struct device *dev = &spi->dev;
71 + struct falcon_spi *priv = spi_master_get_devdata(spi->master);
72 + const u8 *txp = t->tx_buf;
73 + u8 *rxp = t->rx_buf;
74 + unsigned int bytelen = ((8 * t->len + 7) / 8);
75 + unsigned int len, alen, dumlen;
76 + u32 val;
77 + enum {
78 + state_init,
79 + state_command_prepare,
80 + state_write,
81 + state_read,
82 + state_disable_cs,
83 + state_end
84 + } state = state_init;
85 +
86 + do {
87 + switch (state) {
88 + case state_init: /* detect phase of upper layer sequence */
89 + {
90 + /* initial write ? */
91 + if (flags & FALCON_SPI_XFER_BEGIN) {
92 + if (!txp) {
93 + dev_err(dev,
94 + "BEGIN without tx data!\n");
95 + return -1;
96 + }
97 + /*
98 + * Prepare the parts of the sfcmd register,
99 + * which should not
100 + * change during a sequence!
101 + * Only exception are the length fields,
102 + * especially alen and dumlen.
103 + */
104 +
105 + priv->sfcmd = ((spi->chip_select
106 + << SFCMD_CS_OFFSET)
107 + & SFCMD_CS_MASK);
108 + priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
109 + priv->sfcmd |= *txp;
110 + txp++;
111 + bytelen--;
112 + if (bytelen) {
113 + /* more data:
114 + * maybe address and/or dummy */
115 + state = state_command_prepare;
116 + break;
117 + } else {
118 + dev_dbg(dev, "write cmd %02X\n",
119 + priv->sfcmd & SFCMD_OPC_MASK);
120 + }
121 + }
122 + /* continued write ? */
123 + if (txp && bytelen) {
124 + state = state_write;
125 + break;
126 + }
127 + /* read data? */
128 + if (rxp && bytelen) {
129 + state = state_read;
130 + break;
131 + }
132 + /* end of sequence? */
133 + if (flags & FALCON_SPI_XFER_END)
134 + state = state_disable_cs;
135 + else
136 + state = state_end;
137 + break;
138 + }
139 + case state_command_prepare: /* collect tx data for
140 + address and dummy phase */
141 + {
142 + /* txp is valid, already checked */
143 + val = 0;
144 + alen = 0;
145 + dumlen = 0;
146 + while (bytelen > 0) {
147 + if (alen < 3) {
148 + val = (val<<8)|(*txp++);
149 + alen++;
150 + } else if ((dumlen < 15) && (*txp == 0)) {
151 + /*
152 + * assume dummy bytes are set to 0
153 + * from upper layer
154 + */
155 + dumlen++;
156 + txp++;
157 + } else
158 + break;
159 + bytelen--;
160 + }
161 + priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK);
162 + priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) |
163 + (dumlen << SFCMD_DUMLEN_OFFSET);
164 + if (alen > 0)
165 + ebu_w32(val, sfaddr);
166 +
167 + dev_dbg(dev, "write cmd %02X, alen=%d "
168 + "(addr=%06X) dumlen=%d\n",
169 + priv->sfcmd & SFCMD_OPC_MASK,
170 + alen, val, dumlen);
171 +
172 + if (bytelen > 0) {
173 + /* continue with write */
174 + state = state_write;
175 + } else if (flags & FALCON_SPI_XFER_END) {
176 + /* end of sequence? */
177 + state = state_disable_cs;
178 + } else {
179 + /* go to end and expect another
180 + * call (read or write) */
181 + state = state_end;
182 + }
183 + break;
184 + }
185 + case state_write:
186 + {
187 + /* txp still valid */
188 + priv->sfcmd |= SFCMD_DIR_WRITE;
189 + len = 0;
190 + val = 0;
191 + do {
192 + if (bytelen--)
193 + val |= (*txp++) << (8 * len++);
194 + if ((flags & FALCON_SPI_XFER_END)
195 + && (bytelen == 0)) {
196 + priv->sfcmd &=
197 + ~SFCMD_KEEP_CS_KEEP_SELECTED;
198 + }
199 + if ((len == 4) || (bytelen == 0)) {
200 + ebu_w32(val, sfdata);
201 + ebu_w32(priv->sfcmd
202 + | (len<<SFCMD_DLEN_OFFSET),
203 + sfcmd);
204 + len = 0;
205 + val = 0;
206 + priv->sfcmd &= ~(SFCMD_ALEN_MASK
207 + | SFCMD_DUMLEN_MASK);
208 + }
209 + } while (bytelen);
210 + state = state_end;
211 + break;
212 + }
213 + case state_read:
214 + {
215 + /* read data */
216 + priv->sfcmd &= ~SFCMD_DIR_WRITE;
217 + do {
218 + if ((flags & FALCON_SPI_XFER_END)
219 + && (bytelen <= 4)) {
220 + priv->sfcmd &=
221 + ~SFCMD_KEEP_CS_KEEP_SELECTED;
222 + }
223 + len = (bytelen > 4) ? 4 : bytelen;
224 + bytelen -= len;
225 + ebu_w32(priv->sfcmd
226 + |(len<<SFCMD_DLEN_OFFSET), sfcmd);
227 + priv->sfcmd &= ~(SFCMD_ALEN_MASK
228 + | SFCMD_DUMLEN_MASK);
229 + do {
230 + val = ebu_r32(sfstat);
231 + if (val & SFSTAT_CMD_ERR) {
232 + /* reset error status */
233 + dev_err(dev, "SFSTAT: CMD_ERR "
234 + "(%x)\n", val);
235 + ebu_w32(SFSTAT_CMD_ERR, sfstat);
236 + return -1;
237 + }
238 + } while (val & SFSTAT_CMD_PEND);
239 + val = ebu_r32(sfdata);
240 + do {
241 + *rxp = (val & 0xFF);
242 + rxp++;
243 + val >>= 8;
244 + len--;
245 + } while (len);
246 + } while (bytelen);
247 + state = state_end;
248 + break;
249 + }
250 + case state_disable_cs:
251 + {
252 + priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED;
253 + ebu_w32(priv->sfcmd | (0<<SFCMD_DLEN_OFFSET), sfcmd);
254 + val = ebu_r32(sfstat);
255 + if (val & SFSTAT_CMD_ERR) {
256 + /* reset error status */
257 + dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
258 + ebu_w32(SFSTAT_CMD_ERR, sfstat);
259 + return -1;
260 + }
261 + state = state_end;
262 + break;
263 + }
264 + case state_end:
265 + break;
266 + }
267 + } while (state != state_end);
268 +
269 + return 0;
270 +}
271 +
272 +static int falcon_spi_setup(struct spi_device *spi)
273 +{
274 + struct device *dev = &spi->dev;
275 + struct falcon_spi *priv = spi_master_get_devdata(spi->master);
276 + const u32 ebuclk = 100*1000*1000;
277 + unsigned int i;
278 + unsigned long flags;
279 +
280 + dev_dbg(dev, "setup\n");
281 +
282 + if (spi->master->bus_num > 0 || spi->chip_select > 0)
283 + return -ENODEV;
284 +
285 + spin_lock_irqsave(&ebu_lock, flags);
286 +
287 + if (ebuclk < spi->max_speed_hz) {
288 + /* set EBU clock to 100 MHz */
289 + sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, ebucc);
290 + i = 1; /* divider */
291 + } else {
292 + /* set EBU clock to 50 MHz */
293 + sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, ebucc);
294 +
295 + /* search for suitable divider */
296 + for (i = 1; i < 7; i++) {
297 + if (ebuclk / i <= spi->max_speed_hz)
298 + break;
299 + }
300 + }
301 +
302 + /* setup period of serial clock */
303 + ebu_w32_mask(SFTIME_SCKF_POS_MASK
304 + | SFTIME_SCKR_POS_MASK
305 + | SFTIME_SCK_PER_MASK,
306 + (i << SFTIME_SCKR_POS_OFFSET)
307 + | (i << (SFTIME_SCK_PER_OFFSET + 1)),
308 + sftime);
309 +
310 + /* set some bits of unused_wd, to not trigger HOLD/WP
311 + * signals on non QUAD flashes */
312 + ebu_w32((SFIO_UNUSED_WD_MASK & (0x8|0x4)), sfio);
313 +
314 + ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
315 + busrcon0);
316 + ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, buswcon0);
317 + /* set address wrap around to maximum for 24-bit addresses */
318 + ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, sfcon);
319 +
320 + spin_unlock_irqrestore(&ebu_lock, flags);
321 +
322 + return 0;
323 +}
324 +
325 +static int falcon_spi_transfer(struct spi_device *spi, struct spi_message *m)
326 +{
327 + struct falcon_spi *priv = spi_master_get_devdata(spi->master);
328 + struct spi_transfer *t;
329 + unsigned long spi_flags;
330 + unsigned long flags;
331 + int ret = 0;
332 +
333 + priv->sfcmd = 0;
334 + m->actual_length = 0;
335 +
336 + spi_flags = FALCON_SPI_XFER_BEGIN;
337 + list_for_each_entry(t, &m->transfers, transfer_list) {
338 + if (list_is_last(&t->transfer_list, &m->transfers))
339 + spi_flags |= FALCON_SPI_XFER_END;
340 +
341 + spin_lock_irqsave(&ebu_lock, flags);
342 + ret = falcon_spi_xfer(spi, t, spi_flags);
343 + spin_unlock_irqrestore(&ebu_lock, flags);
344 +
345 + if (ret)
346 + break;
347 +
348 + m->actual_length += t->len;
349 +
350 + if (t->delay_usecs || t->cs_change)
351 + BUG();
352 +
353 + spi_flags = 0;
354 + }
355 +
356 + m->status = ret;
357 + m->complete(m->context);
358 +
359 + return 0;
360 +}
361 +
362 +static void falcon_spi_cleanup(struct spi_device *spi)
363 +{
364 + struct device *dev = &spi->dev;
365 +
366 + dev_dbg(dev, "cleanup\n");
367 +}
368 +
369 +static int __devinit falcon_spi_probe(struct platform_device *pdev)
370 +{
371 + struct device *dev = &pdev->dev;
372 + struct falcon_spi *priv;
373 + struct spi_master *master;
374 + struct resource *memres_ebu, *memres_sys1;
375 + int ret;
376 +
377 + dev_dbg(dev, "probing\n");
378 +
379 + memres_ebu = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ebu");
380 + memres_sys1 = platform_get_resource_byname(pdev, IORESOURCE_MEM,
381 + "sys1");
382 +
383 + if (!memres_ebu || !memres_sys1) {
384 + dev_err(dev, "no resources\n");
385 + return -ENODEV;
386 + }
387 +
388 + master = spi_alloc_master(&pdev->dev, sizeof(*priv));
389 + if (!master) {
390 + dev_err(dev, "no memory for spi_master\n");
391 + return -ENOMEM;
392 + }
393 +
394 + priv = spi_master_get_devdata(master);
395 +
396 + priv->ebu_membase = ioremap_nocache(memres_ebu->start & ~KSEG1,
397 + resource_size(memres_ebu));
398 +
399 + if (!priv->ebu_membase) {
400 + dev_err(dev, "can't map ebu memory\n");
401 +
402 + ret = -ENOMEM;
403 + goto free_master;
404 + }
405 +
406 + priv->sys1_membase = ioremap_nocache(memres_sys1->start & ~KSEG1,
407 + resource_size(memres_sys1));
408 +
409 + if (!priv->sys1_membase) {
410 + dev_err(dev, "can't map sys1 memory\n");
411 +
412 + ret = -ENOMEM;
413 + goto unmap_ebu;
414 + }
415 +
416 + priv->master = master;
417 +
418 + master->mode_bits = SPI_MODE_3;
419 + master->num_chipselect = 1;
420 + master->bus_num = 0;
421 +
422 + master->setup = falcon_spi_setup;
423 + master->transfer = falcon_spi_transfer;
424 + master->cleanup = falcon_spi_cleanup;
425 +
426 + platform_set_drvdata(pdev, priv);
427 +
428 + ret = spi_register_master(master);
429 + if (ret)
430 + goto unmap_sys1;
431 +
432 + return 0;
433 +
434 +unmap_sys1:
435 + iounmap(priv->sys1_membase);
436 +
437 +unmap_ebu:
438 + iounmap(priv->ebu_membase);
439 +
440 +free_master:
441 + spi_master_put(master);
442 +
443 + return ret;
444 +}
445 +
446 +static int __devexit falcon_spi_remove(struct platform_device *pdev)
447 +{
448 + struct device *dev = &pdev->dev;
449 + struct falcon_spi *priv = platform_get_drvdata(pdev);
450 +
451 + dev_dbg(dev, "removed\n");
452 +
453 + spi_unregister_master(priv->master);
454 +
455 + iounmap(priv->sys1_membase);
456 + iounmap(priv->ebu_membase);
457 +
458 + return 0;
459 +}
460 +
461 +static struct platform_driver falcon_spi_driver = {
462 + .probe = falcon_spi_probe,
463 + .remove = __devexit_p(falcon_spi_remove),
464 + .driver = {
465 + .name = DRV_NAME,
466 + .owner = THIS_MODULE
467 + }
468 +};
469 +
470 +static int __init falcon_spi_init(void)
471 +{
472 + return platform_driver_register(&falcon_spi_driver);
473 +}
474 +
475 +static void __exit falcon_spi_exit(void)
476 +{
477 + platform_driver_unregister(&falcon_spi_driver);
478 +}
479 +
480 +module_init(falcon_spi_init);
481 +module_exit(falcon_spi_exit);
482 +
483 +MODULE_LICENSE("GPL");
484 +MODULE_DESCRIPTION("Lantiq Falcon SPI controller driver");
485 --- a/drivers/spi/Kconfig
486 +++ b/drivers/spi/Kconfig
487 @@ -169,6 +169,10 @@ config SPI_LM70_LLP
488 which interfaces to an LM70 temperature sensor using
489 a parallel port.
490
491 +config SPI_FALCON
492 + tristate "Falcon SPI controller support"
493 + depends on SOC_LANTIQ_FALCON
494 +
495 config SPI_MPC52xx
496 tristate "Freescale MPC52xx SPI (non-PSC) controller support"
497 depends on PPC_MPC52xx && SPI
This page took 0.065047 seconds and 5 git commands to generate.