1
2
3
4
5#include <linux/clk.h>
6#include <linux/delay.h>
7#include <linux/fsi.h>
8#include <linux/io.h>
9#include <linux/mfd/syscon.h>
10#include <linux/module.h>
11#include <linux/mutex.h>
12#include <linux/of.h>
13#include <linux/platform_device.h>
14#include <linux/regmap.h>
15#include <linux/slab.h>
16#include <linux/iopoll.h>
17#include <linux/gpio/consumer.h>
18
19#include "fsi-master.h"
20
21struct fsi_master_aspeed {
22 struct fsi_master master;
23 struct mutex lock;
24 struct device *dev;
25 void __iomem *base;
26 struct clk *clk;
27 struct gpio_desc *cfam_reset_gpio;
28};
29
30#define to_fsi_master_aspeed(m) \
31 container_of(m, struct fsi_master_aspeed, master)
32
33
34static const u32 ctrl_base = 0x80000000;
35
36static const u32 fsi_base = 0xa0000000;
37
38#define OPB_FSI_VER 0x00
39#define OPB_TRIGGER 0x04
40#define OPB_CTRL_BASE 0x08
41#define OPB_FSI_BASE 0x0c
42#define OPB_CLK_SYNC 0x3c
43#define OPB_IRQ_CLEAR 0x40
44#define OPB_IRQ_MASK 0x44
45#define OPB_IRQ_STATUS 0x48
46
47#define OPB0_SELECT 0x10
48#define OPB0_RW 0x14
49#define OPB0_XFER_SIZE 0x18
50#define OPB0_FSI_ADDR 0x1c
51#define OPB0_FSI_DATA_W 0x20
52#define OPB0_STATUS 0x80
53#define OPB0_FSI_DATA_R 0x84
54
55#define OPB0_WRITE_ORDER1 0x4c
56#define OPB0_WRITE_ORDER2 0x50
57#define OPB1_WRITE_ORDER1 0x54
58#define OPB1_WRITE_ORDER2 0x58
59#define OPB0_READ_ORDER1 0x5c
60#define OPB1_READ_ORDER2 0x60
61
62#define OPB_RETRY_COUNTER 0x64
63
64
65#define STATUS_HALFWORD_ACK BIT(0)
66#define STATUS_FULLWORD_ACK BIT(1)
67#define STATUS_ERR_ACK BIT(2)
68#define STATUS_RETRY BIT(3)
69#define STATUS_TIMEOUT BIT(4)
70
71
72#define OPB1_XFER_ACK_EN BIT(17)
73#define OPB0_XFER_ACK_EN BIT(16)
74
75
76#define CMD_READ BIT(0)
77#define CMD_WRITE 0
78
79
80#define XFER_FULLWORD (BIT(1) | BIT(0))
81#define XFER_HALFWORD (BIT(0))
82#define XFER_BYTE (0)
83
84#define CREATE_TRACE_POINTS
85#include <trace/events/fsi_master_aspeed.h>
86
87#define FSI_LINK_ENABLE_SETUP_TIME 10
88
89
90#define FSI_DIVISOR_DEFAULT 1
91#define FSI_DIVISOR_CABLED 2
92static u16 aspeed_fsi_divisor = FSI_DIVISOR_DEFAULT;
93module_param_named(bus_div,aspeed_fsi_divisor, ushort, 0);
94
95#define OPB_POLL_TIMEOUT 10000
96
97static int __opb_write(struct fsi_master_aspeed *aspeed, u32 addr,
98 u32 val, u32 transfer_size)
99{
100 void __iomem *base = aspeed->base;
101 u32 reg, status;
102 int ret;
103
104 writel(CMD_WRITE, base + OPB0_RW);
105 writel(transfer_size, base + OPB0_XFER_SIZE);
106 writel(addr, base + OPB0_FSI_ADDR);
107 writel(val, base + OPB0_FSI_DATA_W);
108 writel(0x1, base + OPB_IRQ_CLEAR);
109 writel(0x1, base + OPB_TRIGGER);
110
111 ret = readl_poll_timeout(base + OPB_IRQ_STATUS, reg,
112 (reg & OPB0_XFER_ACK_EN) != 0,
113 0, OPB_POLL_TIMEOUT);
114
115 status = readl(base + OPB0_STATUS);
116
117 trace_fsi_master_aspeed_opb_write(addr, val, transfer_size, status, reg);
118
119
120 if (ret)
121 return ret;
122
123
124 if (status & STATUS_ERR_ACK)
125 return -EIO;
126
127 return 0;
128}
129
130static int opb_writeb(struct fsi_master_aspeed *aspeed, u32 addr, u8 val)
131{
132 return __opb_write(aspeed, addr, val, XFER_BYTE);
133}
134
135static int opb_writew(struct fsi_master_aspeed *aspeed, u32 addr, __be16 val)
136{
137 return __opb_write(aspeed, addr, (__force u16)val, XFER_HALFWORD);
138}
139
140static int opb_writel(struct fsi_master_aspeed *aspeed, u32 addr, __be32 val)
141{
142 return __opb_write(aspeed, addr, (__force u32)val, XFER_FULLWORD);
143}
144
145static int __opb_read(struct fsi_master_aspeed *aspeed, uint32_t addr,
146 u32 transfer_size, void *out)
147{
148 void __iomem *base = aspeed->base;
149 u32 result, reg;
150 int status, ret;
151
152 writel(CMD_READ, base + OPB0_RW);
153 writel(transfer_size, base + OPB0_XFER_SIZE);
154 writel(addr, base + OPB0_FSI_ADDR);
155 writel(0x1, base + OPB_IRQ_CLEAR);
156 writel(0x1, base + OPB_TRIGGER);
157
158 ret = readl_poll_timeout(base + OPB_IRQ_STATUS, reg,
159 (reg & OPB0_XFER_ACK_EN) != 0,
160 0, OPB_POLL_TIMEOUT);
161
162 status = readl(base + OPB0_STATUS);
163
164 result = readl(base + OPB0_FSI_DATA_R);
165
166 trace_fsi_master_aspeed_opb_read(addr, transfer_size, result,
167 readl(base + OPB0_STATUS),
168 reg);
169
170
171 if (ret)
172 return ret;
173
174
175 if (status & STATUS_ERR_ACK)
176 return -EIO;
177
178 if (out) {
179 switch (transfer_size) {
180 case XFER_BYTE:
181 *(u8 *)out = result;
182 break;
183 case XFER_HALFWORD:
184 *(u16 *)out = result;
185 break;
186 case XFER_FULLWORD:
187 *(u32 *)out = result;
188 break;
189 default:
190 return -EINVAL;
191 }
192
193 }
194
195 return 0;
196}
197
198static int opb_readl(struct fsi_master_aspeed *aspeed, uint32_t addr, __be32 *out)
199{
200 return __opb_read(aspeed, addr, XFER_FULLWORD, out);
201}
202
203static int opb_readw(struct fsi_master_aspeed *aspeed, uint32_t addr, __be16 *out)
204{
205 return __opb_read(aspeed, addr, XFER_HALFWORD, (void *)out);
206}
207
208static int opb_readb(struct fsi_master_aspeed *aspeed, uint32_t addr, u8 *out)
209{
210 return __opb_read(aspeed, addr, XFER_BYTE, (void *)out);
211}
212
213static int check_errors(struct fsi_master_aspeed *aspeed, int err)
214{
215 int ret;
216
217 if (trace_fsi_master_aspeed_opb_error_enabled()) {
218 __be32 mresp0, mstap0, mesrb0;
219
220 opb_readl(aspeed, ctrl_base + FSI_MRESP0, &mresp0);
221 opb_readl(aspeed, ctrl_base + FSI_MSTAP0, &mstap0);
222 opb_readl(aspeed, ctrl_base + FSI_MESRB0, &mesrb0);
223
224 trace_fsi_master_aspeed_opb_error(
225 be32_to_cpu(mresp0),
226 be32_to_cpu(mstap0),
227 be32_to_cpu(mesrb0));
228 }
229
230 if (err == -EIO) {
231
232
233
234 ret = opb_writel(aspeed, ctrl_base + FSI_MRESP0,
235 cpu_to_be32(FSI_MRESP_RST_ALL_MASTER));
236 if (ret) {
237
238 return ret;
239 }
240
241 }
242
243
244 return err;
245}
246
247static int aspeed_master_read(struct fsi_master *master, int link,
248 uint8_t id, uint32_t addr, void *val, size_t size)
249{
250 struct fsi_master_aspeed *aspeed = to_fsi_master_aspeed(master);
251 int ret;
252
253 if (id > 0x3)
254 return -EINVAL;
255
256 addr |= id << 21;
257 addr += link * FSI_HUB_LINK_SIZE;
258
259 mutex_lock(&aspeed->lock);
260
261 switch (size) {
262 case 1:
263 ret = opb_readb(aspeed, fsi_base + addr, val);
264 break;
265 case 2:
266 ret = opb_readw(aspeed, fsi_base + addr, val);
267 break;
268 case 4:
269 ret = opb_readl(aspeed, fsi_base + addr, val);
270 break;
271 default:
272 ret = -EINVAL;
273 goto done;
274 }
275
276 ret = check_errors(aspeed, ret);
277done:
278 mutex_unlock(&aspeed->lock);
279 return ret;
280}
281
282static int aspeed_master_write(struct fsi_master *master, int link,
283 uint8_t id, uint32_t addr, const void *val, size_t size)
284{
285 struct fsi_master_aspeed *aspeed = to_fsi_master_aspeed(master);
286 int ret;
287
288 if (id > 0x3)
289 return -EINVAL;
290
291 addr |= id << 21;
292 addr += link * FSI_HUB_LINK_SIZE;
293
294 mutex_lock(&aspeed->lock);
295
296 switch (size) {
297 case 1:
298 ret = opb_writeb(aspeed, fsi_base + addr, *(u8 *)val);
299 break;
300 case 2:
301 ret = opb_writew(aspeed, fsi_base + addr, *(__be16 *)val);
302 break;
303 case 4:
304 ret = opb_writel(aspeed, fsi_base + addr, *(__be32 *)val);
305 break;
306 default:
307 ret = -EINVAL;
308 goto done;
309 }
310
311 ret = check_errors(aspeed, ret);
312done:
313 mutex_unlock(&aspeed->lock);
314 return ret;
315}
316
317static int aspeed_master_link_enable(struct fsi_master *master, int link,
318 bool enable)
319{
320 struct fsi_master_aspeed *aspeed = to_fsi_master_aspeed(master);
321 int idx, bit, ret;
322 __be32 reg;
323
324 idx = link / 32;
325 bit = link % 32;
326
327 reg = cpu_to_be32(0x80000000 >> bit);
328
329 mutex_lock(&aspeed->lock);
330
331 if (!enable) {
332 ret = opb_writel(aspeed, ctrl_base + FSI_MCENP0 + (4 * idx), reg);
333 goto done;
334 }
335
336 ret = opb_writel(aspeed, ctrl_base + FSI_MSENP0 + (4 * idx), reg);
337 if (ret)
338 goto done;
339
340 mdelay(FSI_LINK_ENABLE_SETUP_TIME);
341done:
342 mutex_unlock(&aspeed->lock);
343 return ret;
344}
345
346static int aspeed_master_term(struct fsi_master *master, int link, uint8_t id)
347{
348 uint32_t addr;
349 __be32 cmd;
350
351 addr = 0x4;
352 cmd = cpu_to_be32(0xecc00000);
353
354 return aspeed_master_write(master, link, id, addr, &cmd, 4);
355}
356
357static int aspeed_master_break(struct fsi_master *master, int link)
358{
359 uint32_t addr;
360 __be32 cmd;
361
362 addr = 0x0;
363 cmd = cpu_to_be32(0xc0de0000);
364
365 return aspeed_master_write(master, link, 0, addr, &cmd, 4);
366}
367
368static void aspeed_master_release(struct device *dev)
369{
370 struct fsi_master_aspeed *aspeed =
371 to_fsi_master_aspeed(dev_to_fsi_master(dev));
372
373 kfree(aspeed);
374}
375
376
377static inline u32 fsi_mmode_crs0(u32 x)
378{
379 return (x & FSI_MMODE_CRS0MASK) << FSI_MMODE_CRS0SHFT;
380}
381
382static inline u32 fsi_mmode_crs1(u32 x)
383{
384 return (x & FSI_MMODE_CRS1MASK) << FSI_MMODE_CRS1SHFT;
385}
386
387static int aspeed_master_init(struct fsi_master_aspeed *aspeed)
388{
389 __be32 reg;
390
391 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK
392 | FSI_MRESP_RST_MCR | FSI_MRESP_RST_PYE);
393 opb_writel(aspeed, ctrl_base + FSI_MRESP0, reg);
394
395
396 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK
397 | FSI_MRESP_RST_MCR | FSI_MRESP_RST_PYE);
398 opb_writel(aspeed, ctrl_base + FSI_MRESP0, reg);
399
400 reg = cpu_to_be32(FSI_MECTRL_EOAE | FSI_MECTRL_P8_AUTO_TERM);
401 opb_writel(aspeed, ctrl_base + FSI_MECTRL, reg);
402
403 reg = cpu_to_be32(FSI_MMODE_ECRC | FSI_MMODE_EPC | FSI_MMODE_RELA
404 | fsi_mmode_crs0(aspeed_fsi_divisor)
405 | fsi_mmode_crs1(aspeed_fsi_divisor)
406 | FSI_MMODE_P8_TO_LSB);
407 dev_info(aspeed->dev, "mmode set to %08x (divisor %d)\n",
408 be32_to_cpu(reg), aspeed_fsi_divisor);
409 opb_writel(aspeed, ctrl_base + FSI_MMODE, reg);
410
411 reg = cpu_to_be32(0xffff0000);
412 opb_writel(aspeed, ctrl_base + FSI_MDLYR, reg);
413
414 reg = cpu_to_be32(~0);
415 opb_writel(aspeed, ctrl_base + FSI_MSENP0, reg);
416
417
418 mdelay(FSI_LINK_ENABLE_SETUP_TIME);
419
420 opb_writel(aspeed, ctrl_base + FSI_MCENP0, reg);
421
422 opb_readl(aspeed, ctrl_base + FSI_MAEB, NULL);
423
424 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK);
425 opb_writel(aspeed, ctrl_base + FSI_MRESP0, reg);
426
427 opb_readl(aspeed, ctrl_base + FSI_MLEVP0, NULL);
428
429
430 reg = cpu_to_be32(FSI_MRESB_RST_GEN);
431 opb_writel(aspeed, ctrl_base + FSI_MRESB0, reg);
432
433 reg = cpu_to_be32(FSI_MRESB_RST_ERR);
434 opb_writel(aspeed, ctrl_base + FSI_MRESB0, reg);
435
436 return 0;
437}
438
439static ssize_t cfam_reset_store(struct device *dev, struct device_attribute *attr,
440 const char *buf, size_t count)
441{
442 struct fsi_master_aspeed *aspeed = dev_get_drvdata(dev);
443
444 mutex_lock(&aspeed->lock);
445 gpiod_set_value(aspeed->cfam_reset_gpio, 1);
446 usleep_range(900, 1000);
447 gpiod_set_value(aspeed->cfam_reset_gpio, 0);
448 mutex_unlock(&aspeed->lock);
449
450 return count;
451}
452
453static DEVICE_ATTR(cfam_reset, 0200, NULL, cfam_reset_store);
454
455static int setup_cfam_reset(struct fsi_master_aspeed *aspeed)
456{
457 struct device *dev = aspeed->dev;
458 struct gpio_desc *gpio;
459 int rc;
460
461 gpio = devm_gpiod_get_optional(dev, "cfam-reset", GPIOD_OUT_LOW);
462 if (IS_ERR(gpio))
463 return PTR_ERR(gpio);
464 if (!gpio)
465 return 0;
466
467 aspeed->cfam_reset_gpio = gpio;
468
469 rc = device_create_file(dev, &dev_attr_cfam_reset);
470 if (rc) {
471 devm_gpiod_put(dev, gpio);
472 return rc;
473 }
474
475 return 0;
476}
477
478static int tacoma_cabled_fsi_fixup(struct device *dev)
479{
480 struct gpio_desc *routing_gpio, *mux_gpio;
481 int gpio;
482
483
484
485
486
487 routing_gpio = devm_gpiod_get_optional(dev, "fsi-routing",
488 GPIOD_IN | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
489 if (IS_ERR(routing_gpio))
490 return PTR_ERR(routing_gpio);
491 if (!routing_gpio)
492 return 0;
493
494 mux_gpio = devm_gpiod_get_optional(dev, "fsi-mux", GPIOD_ASIS);
495 if (IS_ERR(mux_gpio))
496 return PTR_ERR(mux_gpio);
497 if (!mux_gpio)
498 return 0;
499
500 gpio = gpiod_get_value(routing_gpio);
501 if (gpio < 0)
502 return gpio;
503
504
505 if (gpio) {
506
507
508
509
510
511 if (aspeed_fsi_divisor == FSI_DIVISOR_DEFAULT)
512 aspeed_fsi_divisor = FSI_DIVISOR_CABLED;
513
514 gpiod_direction_output(mux_gpio, 0);
515 dev_info(dev, "FSI configured for external cable\n");
516 } else {
517 gpiod_direction_output(mux_gpio, 1);
518 }
519
520 devm_gpiod_put(dev, routing_gpio);
521
522 return 0;
523}
524
525static int fsi_master_aspeed_probe(struct platform_device *pdev)
526{
527 struct fsi_master_aspeed *aspeed;
528 struct resource *res;
529 int rc, links, reg;
530 __be32 raw;
531
532 rc = tacoma_cabled_fsi_fixup(&pdev->dev);
533 if (rc) {
534 dev_err(&pdev->dev, "Tacoma FSI cable fixup failed\n");
535 return rc;
536 }
537
538 aspeed = devm_kzalloc(&pdev->dev, sizeof(*aspeed), GFP_KERNEL);
539 if (!aspeed)
540 return -ENOMEM;
541
542 aspeed->dev = &pdev->dev;
543
544 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
545 aspeed->base = devm_ioremap_resource(&pdev->dev, res);
546 if (IS_ERR(aspeed->base))
547 return PTR_ERR(aspeed->base);
548
549 aspeed->clk = devm_clk_get(aspeed->dev, NULL);
550 if (IS_ERR(aspeed->clk)) {
551 dev_err(aspeed->dev, "couldn't get clock\n");
552 return PTR_ERR(aspeed->clk);
553 }
554 rc = clk_prepare_enable(aspeed->clk);
555 if (rc) {
556 dev_err(aspeed->dev, "couldn't enable clock\n");
557 return rc;
558 }
559
560 rc = setup_cfam_reset(aspeed);
561 if (rc) {
562 dev_err(&pdev->dev, "CFAM reset GPIO setup failed\n");
563 }
564
565 writel(0x1, aspeed->base + OPB_CLK_SYNC);
566 writel(OPB1_XFER_ACK_EN | OPB0_XFER_ACK_EN,
567 aspeed->base + OPB_IRQ_MASK);
568
569
570 writel(0x10, aspeed->base + OPB_RETRY_COUNTER);
571
572 writel(ctrl_base, aspeed->base + OPB_CTRL_BASE);
573 writel(fsi_base, aspeed->base + OPB_FSI_BASE);
574
575
576 writel(0x00030b1b, aspeed->base + OPB0_READ_ORDER1);
577
578
579 writel(0x0011101b, aspeed->base + OPB0_WRITE_ORDER1);
580 writel(0x0c330f3f, aspeed->base + OPB0_WRITE_ORDER2);
581
582
583
584
585
586
587 writel(0x1, aspeed->base + OPB0_SELECT);
588
589 rc = opb_readl(aspeed, ctrl_base + FSI_MVER, &raw);
590 if (rc) {
591 dev_err(&pdev->dev, "failed to read hub version\n");
592 return rc;
593 }
594
595 reg = be32_to_cpu(raw);
596 links = (reg >> 8) & 0xff;
597 dev_info(&pdev->dev, "hub version %08x (%d links)\n", reg, links);
598
599 aspeed->master.dev.parent = &pdev->dev;
600 aspeed->master.dev.release = aspeed_master_release;
601 aspeed->master.dev.of_node = of_node_get(dev_of_node(&pdev->dev));
602
603 aspeed->master.n_links = links;
604 aspeed->master.read = aspeed_master_read;
605 aspeed->master.write = aspeed_master_write;
606 aspeed->master.send_break = aspeed_master_break;
607 aspeed->master.term = aspeed_master_term;
608 aspeed->master.link_enable = aspeed_master_link_enable;
609
610 dev_set_drvdata(&pdev->dev, aspeed);
611
612 mutex_init(&aspeed->lock);
613 aspeed_master_init(aspeed);
614
615 rc = fsi_master_register(&aspeed->master);
616 if (rc)
617 goto err_release;
618
619
620
621
622
623
624
625
626 get_device(&aspeed->master.dev);
627 return 0;
628
629err_release:
630 clk_disable_unprepare(aspeed->clk);
631 return rc;
632}
633
634static int fsi_master_aspeed_remove(struct platform_device *pdev)
635{
636 struct fsi_master_aspeed *aspeed = platform_get_drvdata(pdev);
637
638 fsi_master_unregister(&aspeed->master);
639 clk_disable_unprepare(aspeed->clk);
640
641 return 0;
642}
643
644static const struct of_device_id fsi_master_aspeed_match[] = {
645 { .compatible = "aspeed,ast2600-fsi-master" },
646 { },
647};
648
649static struct platform_driver fsi_master_aspeed_driver = {
650 .driver = {
651 .name = "fsi-master-aspeed",
652 .of_match_table = fsi_master_aspeed_match,
653 },
654 .probe = fsi_master_aspeed_probe,
655 .remove = fsi_master_aspeed_remove,
656};
657
658module_platform_driver(fsi_master_aspeed_driver);
659MODULE_LICENSE("GPL");
660