14952c663b834fae176193f7ec22f25edfe5a889
[openwrt.git] / target / linux / ar71xx / files / drivers / spi / spi_vsc7385.c
1 /*
2  * SPI driver for the Vitesse VSC7385 ethernet switch
3  *
4  * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
5  *
6  * Parts of this file are based on Atheros' 2.6.15 BSP
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License version 2 as published
10  * by the Free Software Foundation.
11  */
12
13 #include <linux/types.h>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/delay.h>
18 #include <linux/device.h>
19 #include <linux/bitops.h>
20 #include <linux/firmware.h>
21 #include <linux/spi/spi.h>
22 #include <linux/spi/vsc7385.h>
23
24 #define DRV_NAME        "spi-vsc7385"
25 #define DRV_DESC        "Vitesse VSC7385 Gbit ethernet switch driver"
26 #define DRV_VERSION     "0.1.0"
27
28 #define VSC73XX_BLOCK_MAC       0x1
29 #define VSC73XX_BLOCK_2         0x2
30 #define VSC73XX_BLOCK_MII       0x3
31 #define VSC73XX_BLOCK_4         0x4
32 #define VSC73XX_BLOCK_5         0x5
33 #define VSC73XX_BLOCK_SYSTEM    0x7
34
35 #define VSC73XX_SUBBLOCK_PORT_0         0
36 #define VSC73XX_SUBBLOCK_PORT_1         1
37 #define VSC73XX_SUBBLOCK_PORT_2         2
38 #define VSC73XX_SUBBLOCK_PORT_3         3
39 #define VSC73XX_SUBBLOCK_PORT_4         4
40 #define VSC73XX_SUBBLOCK_PORT_MAC       6
41
42 /* MAC Block registers */
43 #define VSC73XX_MAC_CFG         0x0
44 #define VSC73XX_ADVPORTM        0x19
45 #define VSC73XX_RXOCT           0x50
46 #define VSC73XX_TXOCT           0x51
47 #define VSC73XX_C_RX0           0x52
48 #define VSC73XX_C_RX1           0x53
49 #define VSC73XX_C_RX2           0x54
50 #define VSC73XX_C_TX0           0x55
51 #define VSC73XX_C_TX1           0x56
52 #define VSC73XX_C_TX2           0x57
53 #define VSC73XX_C_CFG           0x58
54
55 /* MAC_CFG register bits */
56 #define VSC73XX_MAC_CFG_WEXC_DIS        (1 << 31)
57 #define VSC73XX_MAC_CFG_PORT_RST        (1 << 29)
58 #define VSC73XX_MAC_CFG_TX_EN           (1 << 28)
59 #define VSC73XX_MAC_CFG_SEED_LOAD       (1 << 27)
60 #define VSC73XX_MAC_CFG_FDX             (1 << 18)
61 #define VSC73XX_MAC_CFG_GIGE            (1 << 17)
62 #define VSC73XX_MAC_CFG_RX_EN           (1 << 16)
63 #define VSC73XX_MAC_CFG_VLAN_DBLAWR     (1 << 15)
64 #define VSC73XX_MAC_CFG_VLAN_AWR        (1 << 14)
65 #define VSC73XX_MAC_CFG_100_BASE_T      (1 << 13)
66 #define VSC73XX_MAC_CFG_TX_IPG(x)       ((x & 0x1f) << 6)
67 #define VSC73XX_MAC_CFG_MAC_RX_RST      (1 << 5)
68 #define VSC73XX_MAC_CFG_MAC_TX_RST      (1 << 4)
69 #define VSC73XX_MAC_CFG_CLK_SEL(x)      ((x & 0x3) << 0)
70
71 /* ADVPORTM register bits */
72 #define VSC73XX_ADVPORTM_IFG_PPM        (1 << 7)
73 #define VSC73XX_ADVPORTM_EXC_COL_CONT   (1 << 6)
74 #define VSC73XX_ADVPORTM_EXT_PORT       (1 << 5)
75 #define VSC73XX_ADVPORTM_INV_GTX        (1 << 4)
76 #define VSC73XX_ADVPORTM_ENA_GTX        (1 << 3)
77 #define VSC73XX_ADVPORTM_DDR_MODE       (1 << 2)
78 #define VSC73XX_ADVPORTM_IO_LOOPBACK    (1 << 1)
79 #define VSC73XX_ADVPORTM_HOST_LOOPBACK  (1 << 0)
80
81 /* MII Block registers */
82 #define VSC73XX_MII_STAT        0x0
83 #define VSC73XX_MII_CMD         0x1
84 #define VSC73XX_MII_DATA        0x2
85
86 /* System Block registers */
87 #define VSC73XX_ICPU_SIPAD              0x01
88 #define VSC73XX_ICPU_CLOCK_DELAY        0x05
89 #define VSC73XX_ICPU_CTRL               0x10
90 #define VSC73XX_ICPU_ADDR               0x11
91 #define VSC73XX_ICPU_SRAM               0x12
92 #define VSC73XX_ICPU_MBOX_VAL           0x15
93 #define VSC73XX_ICPU_MBOX_SET           0x16
94 #define VSC73XX_ICPU_MBOX_CLR           0x17
95 #define VSC73XX_ICPU_CHIPID             0x18
96 #define VSC73XX_ICPU_GPIO               0x34
97
98 #define VSC73XX_ICPU_CTRL_CLK_DIV       (1 << 8)
99 #define VSC73XX_ICPU_CTRL_SRST_HOLD     (1 << 7)
100 #define VSC73XX_ICPU_CTRL_BOOT_EN       (1 << 3)
101 #define VSC73XX_ICPU_CTRL_EXT_ACC_EN    (1 << 2)
102 #define VSC73XX_ICPU_CTRL_CLK_EN        (1 << 1)
103 #define VSC73XX_ICPU_CTRL_SRST          (1 << 0)
104
105 #define VSC73XX_ICPU_CHIPID_ID_SHIFT    12
106 #define VSC73XX_ICPU_CHIPID_ID_MASK     0xffff
107 #define VSC73XX_ICPU_CHIPID_REV_SHIFT   28
108 #define VSC73XX_ICPU_CHIPID_REV_MASK    0xf
109 #define VSC73XX_ICPU_CHIPID_ID_7385     0x7385
110 #define VSC73XX_ICPU_CHIPID_ID_7395     0x7395
111
112 #define VSC73XX_CMD_MODE_READ           0
113 #define VSC73XX_CMD_MODE_WRITE          1
114 #define VSC73XX_CMD_MODE_SHIFT          4
115 #define VSC73XX_CMD_BLOCK_SHIFT         5
116 #define VSC73XX_CMD_BLOCK_MASK          0x7
117 #define VSC73XX_CMD_SUBBLOCK_MASK       0xf
118
119 #define VSC7385_CLOCK_DELAY             ((3 << 4) | 3)
120 #define VSC7385_CLOCK_DELAY_MASK        ((3 << 4) | 3)
121
122 #define VSC73XX_ICPU_CTRL_STOP  (VSC73XX_ICPU_CTRL_SRST_HOLD | \
123                                  VSC73XX_ICPU_CTRL_BOOT_EN | \
124                                  VSC73XX_ICPU_CTRL_EXT_ACC_EN)
125
126 #define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \
127                                  VSC73XX_ICPU_CTRL_BOOT_EN | \
128                                  VSC73XX_ICPU_CTRL_CLK_EN | \
129                                  VSC73XX_ICPU_CTRL_SRST)
130
131 #define VSC7385_ADVPORTM_MASK   (VSC73XX_ADVPORTM_IFG_PPM | \
132                                  VSC73XX_ADVPORTM_EXC_COL_CONT | \
133                                  VSC73XX_ADVPORTM_EXT_PORT | \
134                                  VSC73XX_ADVPORTM_INV_GTX | \
135                                  VSC73XX_ADVPORTM_ENA_GTX | \
136                                  VSC73XX_ADVPORTM_DDR_MODE | \
137                                  VSC73XX_ADVPORTM_IO_LOOPBACK | \
138                                  VSC73XX_ADVPORTM_HOST_LOOPBACK)
139
140 #define VSC7385_ADVPORTM_INIT   (VSC73XX_ADVPORTM_EXT_PORT | \
141                                  VSC73XX_ADVPORTM_ENA_GTX | \
142                                  VSC73XX_ADVPORTM_DDR_MODE)
143
144 #define VSC7385_MAC_CFG_RESET   (VSC73XX_MAC_CFG_PORT_RST | \
145                                  VSC73XX_MAC_CFG_MAC_RX_RST | \
146                                  VSC73XX_MAC_CFG_MAC_TX_RST)
147
148 #define VSC7385_MAC_CFG_INIT    (VSC73XX_MAC_CFG_TX_EN | \
149                                  VSC73XX_MAC_CFG_FDX | \
150                                  VSC73XX_MAC_CFG_GIGE | \
151                                  VSC73XX_MAC_CFG_RX_EN | \
152                                  VSC73XX_MAC_CFG_TX_IPG(6) | \
153                                  4)
154
155 #define VSC73XX_RESET_DELAY     100
156
157 struct vsc7385 {
158         struct spi_device               *spi;
159         struct mutex                    lock;
160         struct vsc7385_platform_data    *pdata;
161 };
162
163 static int vsc7385_is_addr_valid(u8 block, u8 subblock)
164 {
165         switch (block) {
166         case VSC73XX_BLOCK_MAC:
167                 switch (subblock) {
168                 case 0 ... 4:
169                 case 6:
170                         return 1;
171                 }
172                 break;
173
174         case VSC73XX_BLOCK_2:
175         case VSC73XX_BLOCK_SYSTEM:
176                 switch (subblock) {
177                 case 0:
178                         return 1;
179                 }
180                 break;
181
182         case VSC73XX_BLOCK_MII:
183         case VSC73XX_BLOCK_4:
184         case VSC73XX_BLOCK_5:
185                 switch (subblock) {
186                 case 0 ... 1:
187                         return 1;
188                 }
189                 break;
190         }
191
192         return 0;
193 }
194
195 static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock)
196 {
197         u8 ret;
198
199         ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT;
200         ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT;
201         ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK;
202
203         return ret;
204 }
205
206 static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
207                         u32 *value)
208 {
209         u8 cmd[4];
210         u8 buf[4];
211         struct spi_transfer t[2];
212         struct spi_message m;
213         int err;
214
215         if (!vsc7385_is_addr_valid(block, subblock))
216                 return -EINVAL;
217
218         spi_message_init(&m);
219
220         memset(&t, 0, sizeof(t));
221
222         t[0].tx_buf = cmd;
223         t[0].len = sizeof(cmd);
224         spi_message_add_tail(&t[0], &m);
225
226         t[1].rx_buf = buf;
227         t[1].len = sizeof(buf);
228         spi_message_add_tail(&t[1], &m);
229
230         cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock);
231         cmd[1] = reg;
232         cmd[2] = 0;
233         cmd[3] = 0;
234
235         mutex_lock(&vsc->lock);
236         err = spi_sync(vsc->spi, &m);
237         mutex_unlock(&vsc->lock);
238
239         if (err)
240                 return err;
241
242         *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) |
243                  (((u32) buf[2]) << 8) | ((u32) buf[3]);
244
245         return 0;
246 }
247
248
249 static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg,
250                          u32 value)
251 {
252         u8 cmd[2];
253         u8 buf[4];
254         struct spi_transfer t[2];
255         struct spi_message m;
256         int err;
257
258         if (!vsc7385_is_addr_valid(block, subblock))
259                 return -EINVAL;
260
261         spi_message_init(&m);
262
263         memset(&t, 0, sizeof(t));
264
265         t[0].tx_buf = cmd;
266         t[0].len = sizeof(cmd);
267         spi_message_add_tail(&t[0], &m);
268
269         t[1].tx_buf = buf;
270         t[1].len = sizeof(buf);
271         spi_message_add_tail(&t[1], &m);
272
273         cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock);
274         cmd[1] = reg;
275
276         buf[0] = (value >> 24) & 0xff;
277         buf[1] = (value >> 16) & 0xff;
278         buf[2] = (value >> 8) & 0xff;
279         buf[3] = value & 0xff;
280
281         mutex_lock(&vsc->lock);
282         err = spi_sync(vsc->spi, &m);
283         mutex_unlock(&vsc->lock);
284
285         return err;
286 }
287
288 static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block,
289                                        u8 subblock, u8 reg, u32 value,
290                                        u32 read_mask, u32 read_val)
291 {
292         struct spi_device *spi = vsc->spi;
293         u32 t;
294         int err;
295
296         err = vsc7385_write(vsc, block, subblock, reg, value);
297         if (err)
298                 return err;
299
300         err = vsc7385_read(vsc, block, subblock, reg, &t);
301         if (err)
302                 return err;
303
304         if ((t & read_mask) != read_val) {
305                 dev_err(&spi->dev, "register write error\n");
306                 return -EIO;
307         }
308
309         return 0;
310 }
311
312 static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val)
313 {
314         return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
315                              VSC73XX_ICPU_CLOCK_DELAY, val);
316 }
317
318 static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val)
319 {
320         return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
321                             VSC73XX_ICPU_CLOCK_DELAY, val);
322 }
323
324 static inline int vsc7385_icpu_stop(struct vsc7385 *vsc)
325 {
326         return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
327                              VSC73XX_ICPU_CTRL_STOP);
328 }
329
330 static inline int vsc7385_icpu_start(struct vsc7385 *vsc)
331 {
332         return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL,
333                              VSC73XX_ICPU_CTRL_START);
334 }
335
336 static inline int vsc7385_icpu_reset(struct vsc7385 *vsc)
337 {
338         int rc;
339
340         rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR,
341                            0x0000);
342         if (rc)
343                 dev_err(&vsc->spi->dev,
344                         "could not reset microcode, err=%d\n", rc);
345
346         return rc;
347 }
348
349 static int vsc7385_upload_ucode(struct vsc7385 *vsc)
350 {
351         struct spi_device *spi = vsc->spi;
352         const struct firmware *firmware;
353         char *ucode_name;
354         unsigned char *dp;
355         unsigned int curVal;
356         int i;
357         int diffs;
358         int rc;
359
360         ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name
361                                               : "vsc7385_ucode.bin";
362         rc = request_firmware(&firmware, ucode_name, &spi->dev);
363         if (rc) {
364                 dev_err(&spi->dev, "request_firmware failed, err=%d\n",
365                         rc);
366                 return rc;
367         }
368
369         rc = vsc7385_icpu_stop(vsc);
370         if (rc)
371                 goto out;
372
373         rc = vsc7385_icpu_reset(vsc);
374         if (rc)
375                 goto out;
376
377         dev_info(&spi->dev, "uploading microcode...\n");
378
379         dp = (unsigned char *) firmware->data;
380         for (i = 0; i < firmware->size; i++) {
381                 rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0,
382                                    VSC73XX_ICPU_SRAM, *dp++);
383                 if (rc) {
384                         dev_err(&spi->dev, "could not load microcode, err=%d\n",
385                                 rc);
386                         goto out;
387                 }
388         }
389
390         rc = vsc7385_icpu_reset(vsc);
391         if (rc)
392                 goto out;
393
394         dev_info(&spi->dev, "verifying microcode...\n");
395
396         dp = (unsigned char *) firmware->data;
397         diffs = 0;
398         for (i = 0; i < firmware->size; i++) {
399                 rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
400                                   VSC73XX_ICPU_SRAM, &curVal);
401                 if (rc) {
402                         dev_err(&spi->dev, "could not read microcode %d\n",rc);
403                         goto out;
404                 }
405
406                 if (curVal > 0xff) {
407                         dev_err(&spi->dev, "bad val read: %04x : %02x  %02x\n",
408                                 i, *dp, curVal);
409                         rc = -EIO;
410                         goto out;
411                 }
412
413                 if ((curVal & 0xff) != *dp) {
414                         diffs++;
415                         dev_err(&spi->dev, "verify error: %04x : %02x  %02x\n",
416                                 i, *dp, curVal);
417
418                         if (diffs > 4)
419                                 break;
420                         }
421                 dp++;
422         }
423
424         if (diffs) {
425                 dev_err(&spi->dev, "microcode verification failed\n");
426                 rc = -EIO;
427                 goto out;
428         }
429
430         dev_info(&spi->dev, "microcode uploaded\n");
431
432         rc = vsc7385_icpu_start(vsc);
433
434  out:
435         release_firmware(firmware);
436         return rc;
437 }
438
439 static int vsc7385_setup(struct vsc7385 *vsc)
440 {
441         int err;
442
443         err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0,
444                                    VSC73XX_ICPU_CLOCK_DELAY,
445                                    VSC7385_CLOCK_DELAY,
446                                    VSC7385_CLOCK_DELAY_MASK,
447                                    VSC7385_CLOCK_DELAY);
448         if (err)
449                 goto err;
450
451         err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC,
452                                    VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM,
453                                    VSC7385_ADVPORTM_INIT,
454                                    VSC7385_ADVPORTM_MASK,
455                                    VSC7385_ADVPORTM_INIT);
456         if (err)
457                 goto err;
458
459         err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
460                             VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET);
461         if (err)
462                 goto err;
463
464         err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC,
465                             VSC73XX_MAC_CFG, VSC7385_MAC_CFG_INIT);
466         if (err)
467                 goto err;
468
469         return 0;
470
471  err:
472         return err;
473 }
474
475 static int vsc7385_detect(struct vsc7385 *vsc)
476 {
477         struct spi_device *spi = vsc->spi;
478         u32 t;
479         u32 id;
480         u32 rev;
481         int err;
482
483         err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
484                                 VSC73XX_ICPU_MBOX_VAL, &t);
485         if (err) {
486                 dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err);
487                 return err;
488         }
489
490         if (t == 0xffffffff) {
491                 dev_dbg(&spi->dev, "assert chip reset\n");
492                 if (vsc->pdata->reset)
493                         vsc->pdata->reset();
494
495         }
496
497         err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0,
498                                 VSC73XX_ICPU_CHIPID, &t);
499         if (err) {
500                 dev_err(&spi->dev, "unable to read chip id, err=%d\n", err);
501                 return err;
502         }
503
504         id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK;
505         switch (id) {
506         case VSC73XX_ICPU_CHIPID_ID_7385:
507         case VSC73XX_ICPU_CHIPID_ID_7395:
508                 break;
509         default:
510                 dev_err(&spi->dev, "unsupported chip, id=%04x\n", id);
511                 return -ENODEV;
512         }
513
514         rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) &
515               VSC73XX_ICPU_CHIPID_REV_MASK;
516         dev_info(&spi->dev, "VSC%04X (rev. %d) switch found \n", id, rev);
517
518         return 0;
519 }
520
521 static int __devinit vsc7385_probe(struct spi_device *spi)
522 {
523         struct vsc7385 *vsc;
524         struct vsc7385_platform_data *pdata;
525         int     err;
526
527         printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n");
528
529         pdata = spi->dev.platform_data;
530         if (!pdata) {
531                 dev_err(&spi->dev, "no platform data specified\n");
532                 return-ENODEV;
533         }
534
535         vsc = kzalloc(sizeof(*vsc), GFP_KERNEL);
536         if (!vsc) {
537                 dev_err(&spi->dev, "no memory for private data\n");
538                 return-ENOMEM;
539         }
540
541         mutex_init(&vsc->lock);
542         vsc->pdata = pdata;
543         vsc->spi = spi_dev_get(spi);
544         dev_set_drvdata(&spi->dev, vsc);
545
546         spi->mode = SPI_MODE_0;
547         spi->bits_per_word = 8;
548         err = spi_setup(spi);
549         if (err) {
550                 dev_err(&spi->dev, "spi_setup failed, err=%d \n", err);
551                 goto err_drvdata;
552         }
553
554         err = vsc7385_detect(vsc);
555         if (err) {
556                 dev_err(&spi->dev, "no chip found, err=%d \n", err);
557                 goto err_drvdata;
558         }
559
560         err = vsc7385_upload_ucode(vsc);
561         if (err)
562                 goto err_drvdata;
563
564         err = vsc7385_setup(vsc);
565         if (err)
566                 goto err_drvdata;
567
568         return 0;
569
570  err_drvdata:
571         dev_set_drvdata(&spi->dev, NULL);
572         kfree(vsc);
573         return err;
574 }
575
576 static int __devexit vsc7385_remove(struct spi_device *spi)
577 {
578         struct vsc7385_data     *vsc;
579
580         vsc = dev_get_drvdata(&spi->dev);
581         dev_set_drvdata(&spi->dev, NULL);
582         kfree(vsc);
583
584         return 0;
585 }
586
587 static struct spi_driver vsc7385_driver = {
588         .driver = {
589                 .name           = DRV_NAME,
590                 .bus            = &spi_bus_type,
591                 .owner          = THIS_MODULE,
592         },
593         .probe          = vsc7385_probe,
594         .remove         = __devexit_p(vsc7385_remove),
595 };
596
597 static int __init vsc7385_init(void)
598 {
599         return spi_register_driver(&vsc7385_driver);
600 }
601 module_init(vsc7385_init);
602
603 static void __exit vsc7385_exit(void)
604 {
605         spi_unregister_driver(&vsc7385_driver);
606 }
607 module_exit(vsc7385_exit);
608
609 MODULE_DESCRIPTION(DRV_DESC);
610 MODULE_VERSION(DRV_VERSION);
611 MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
612 MODULE_LICENSE("GPL v2");
613