1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (C) IBM Corporation 2018
3 // FSI master driver for AST2600
4
5 #include <linux/delay.h>
6 #include <linux/io.h>
7 #include <linux/iopoll.h>
8 #include <linux/bug.h>
9 #include <linux/bitops.h>
10
11 #include <common.h>
12 #include <clk.h>
13
14 #include <dm/device.h>
15 #include <dm/fdtaddr.h>
16
17 /* Control Registers */
18 #define FSI_MMODE 0x0 /* R/W: mode */
19 #define FSI_MDLYR 0x4 /* R/W: delay */
20 #define FSI_MCRSP 0x8 /* R/W: clock rate */
21 #define FSI_MENP0 0x10 /* R/W: enable */
22 #define FSI_MLEVP0 0x18 /* R: plug detect */
23 #define FSI_MSENP0 0x18 /* S: Set enable */
24 #define FSI_MCENP0 0x20 /* C: Clear enable */
25 #define FSI_MAEB 0x70 /* R: Error address */
26 #define FSI_MVER 0x74 /* R: master version/type */
27 #define FSI_MSTAP0 0xd0 /* R: Port status */
28 #define FSI_MRESP0 0xd0 /* W: Port reset */
29 #define FSI_MESRB0 0x1d0 /* R: Master error status */
30 #define FSI_MRESB0 0x1d0 /* W: Reset bridge */
31 #define FSI_MSCSB0 0x1d4 /* R: Master sub command stack */
32 #define FSI_MATRB0 0x1d8 /* R: Master address trace */
33 #define FSI_MDTRB0 0x1dc /* R: Master data trace */
34 #define FSI_MECTRL 0x2e0 /* W: Error control */
35
36 /* MMODE: Mode control */
37 #define FSI_MMODE_EIP 0x80000000 /* Enable interrupt polling */
38 #define FSI_MMODE_ECRC 0x40000000 /* Enable error recovery */
39 #define FSI_MMODE_RELA 0x20000000 /* Enable relative address commands */
40 #define FSI_MMODE_EPC 0x10000000 /* Enable parity checking */
41 #define FSI_MMODE_P8_TO_LSB 0x00000010 /* Timeout value LSB */
42 /* MSB=1, LSB=0 is 0.8 ms */
43 /* MSB=0, LSB=1 is 0.9 ms */
44 #define FSI_MMODE_CRS0SHFT 18 /* Clk rate selection 0 shift */
45 #define FSI_MMODE_CRS0MASK 0x3ff /* Clk rate selection 0 mask */
46 #define FSI_MMODE_CRS1SHFT 8 /* Clk rate selection 1 shift */
47 #define FSI_MMODE_CRS1MASK 0x3ff /* Clk rate selection 1 mask */
48
49 /* MRESB: Reset brindge */
50 #define FSI_MRESB_RST_GEN 0x80000000 /* General reset */
51 #define FSI_MRESB_RST_ERR 0x40000000 /* Error Reset */
52
53 /* MRESB: Reset port */
54 #define FSI_MRESP_RST_ALL_MASTER 0x20000000 /* Reset all FSI masters */
55 #define FSI_MRESP_RST_ALL_LINK 0x10000000 /* Reset all FSI port contr. */
56 #define FSI_MRESP_RST_MCR 0x08000000 /* Reset FSI master reg. */
57 #define FSI_MRESP_RST_PYE 0x04000000 /* Reset FSI parity error */
58 #define FSI_MRESP_RST_ALL 0xfc000000 /* Reset any error */
59
60 /* MECTRL: Error control */
61 #define FSI_MECTRL_EOAE 0x8000 /* Enable machine check when */
62 /* master 0 in error */
63 #define FSI_MECTRL_P8_AUTO_TERM 0x4000 /* Auto terminate */
64
65 #define FSI_ENGID_HUB_MASTER 0x1c
66 #define FSI_HUB_LINK_OFFSET 0x80000
67 #define FSI_HUB_LINK_SIZE 0x80000
68 #define FSI_HUB_MASTER_MAX_LINKS 8
69
70 #define FSI_LINK_ENABLE_SETUP_TIME 10 /* in mS */
71
72 #define FSI_NUM_DEBUGFS_ENTRIES 17
73
74 #define DEFAULT_DIVISOR 14
75
76 struct fsi_master_aspeed;
77
78 struct fsi_master_aspeed {
79 struct udevice *dev;
80 void __iomem *base;
81 struct clk clk;
82 };
83
84 #define to_fsi_master_aspeed(m) \
85 container_of(m, struct fsi_master_aspeed, master)
86
87 /* Control register (size 0x400) */
88 static const u32 ctrl_base = 0x80000000;
89
90 static const u32 fsi_base = 0xa0000000;
91
92 #define OPB_FSI_VER 0x00
93 #define OPB_TRIGGER 0x04
94 #define OPB_CTRL_BASE 0x08
95 #define OPB_FSI_BASE 0x0c
96 #define OPB_CLK_SYNC 0x3c
97 #define OPB_IRQ_CLEAR 0x40
98 #define OPB_IRQ_MASK 0x44
99 #define OPB_IRQ_STATUS 0x48
100
101 #define OPB0_SELECT 0x10
102 #define OPB0_RW 0x14
103 #define OPB0_XFER_SIZE 0x18
104 #define OPB0_FSI_ADDR 0x1c
105 #define OPB0_FSI_DATA_W 0x20
106 #define OPB0_STATUS 0x80
107 /* half world */
108 #define STATUS_HW_ACK BIT(0)
109 /* full word */
110 #define STATUS_FW_ACK BIT(1)
111 #define STATUS_ERR_ACK BIT(2)
112 #define OPB0_FSI_DATA_R 0x84
113
114 #define OPB0_W_ENDIAN 0x4c
115 #define OPB0_R_ENDIAN 0x5c
116
117 /* OPB_IRQ_MASK */
118 #define OPB1_XFER_ACK_EN BIT(17)
119 #define OPB0_XFER_ACK_EN BIT(16)
120
121 #define OPB_IRQ_CH0_DMA_EOT BIT(0)
122 #define OPB_IRQ_CH1_DMA_EOT BIT(1)
123 #define OPB_IRQ_CH2_DMA_EOT BIT(2)
124 #define OPB_IRQ_CH3_DMA_EOT BIT(3)
125 #define OPB_IRQ_CH0_DMA_FIFO_FULL BIT(4)
126 #define OPB_IRQ_CH1_DMA_FIFO_FULL BIT(5)
127 #define OPB_IRQ_CH2_DMA_FIFO_FULL BIT(6)
128 #define OPB_IRQ_CH3_DMA_FIFO_FULL BIT(7)
129 #define OPB_IRQ_CH0_DMA_FIFO_EMPTY BIT(8)
130 #define OPB_IRQ_CH1_DMA_FIFO_EMPTY BIT(9)
131 #define OPB_IRQ_CH2_DMA_FIFO_EMPTY BIT(10)
132 #define OPB_IRQ_CH3_DMA_FIFO_EMPTY BIT(11)
133 #define OPB_IRQ_CH0_DMA_TCONT_DONE BIT(12)
134 #define OPB_IRQ_CH1_DMA_TCONT_DONE BIT(13)
135 #define OPB_IRQ_CH2_DMA_TCONT_DONE BIT(14)
136 #define OPB_IRQ_CH3_DMA_TCONT_DONE BIT(15)
137 #define OPB_IRQ_OPB1_XFER_ACK BIT(16)
138 #define OPB_IRQ_OPB0_XFER_ACK BIT(17)
139 #define OPB_IRQ_SLAVE0 BIT(18)
140 #define OPB_IRQ_SLAVE1 BIT(19)
141 #define OPB_IRQ_SLAVE2 BIT(20)
142 #define OPB_IRQ_SLAVE3 BIT(21)
143 #define OPB_IRQ_SLAVE4 BIT(22)
144 #define OPB_IRQ_SLAVE5 BIT(23)
145 #define OPB_IRQ_SLAVE6 BIT(24)
146 #define OPB_IRQ_SLAVE7 BIT(25)
147 #define OPB_IRQ_ANY_HOTPLUG BIT(26)
148 #define OPB_IRQ_ANY_PORT_ERROR BIT(27)
149 #define OPB_IRQ_ANY_MST_ERROR BIT(28)
150
151 /* OPB_RW */
152 #define CMD_READ BIT(0)
153 #define CMD_WRITE 0
154
155 /* OPBx_XFER_SIZE */
156 #define XFER_WORD (BIT(1) | BIT(0))
157 #define XFER_NIBBLE (BIT(0))
158 #define XFER_BYTE (0)
159
160 #define trace_aspeed_fsi_opb_write(addr, val, size, status, reg) \
161 debug("aspeed_opb_write: addr %08x val %08x size %d status %08x reg %08x\n", \
162 addr, val, size, status, reg)
163
164 #define trace_aspeed_fsi_opb_read(addr, size, result, status, reg) \
165 debug("aspeed_opb_read: addr %08x size %d result %08x status %08x reg %08x\n", \
166 addr, size, result, status, reg)
167
168 #define trace_aspeed_fsi_opb_error(mresp0, mstap0, mesrb0) \
169 debug("aspeed_opb_error: mresp %08x mstap %08x mesrb %08x\n", \
170 mresp0, mstap0, mesrb0)
171
172 #define trace_aspeed_fsi_opb_error_enabled() (_DEBUG)
173
opb_write(struct fsi_master_aspeed * aspeed,uint32_t addr,uint32_t val,size_t size)174 static u32 opb_write(struct fsi_master_aspeed *aspeed, uint32_t addr,
175 uint32_t val, size_t size)
176 {
177 void __iomem *base = aspeed->base;
178 u32 reg, ret, status;
179
180 /* TODO: implement other sizes, see 0x18 */
181 WARN_ON(size != 4);
182
183 writel(CMD_WRITE, base + OPB0_RW);
184 writel(XFER_WORD, base + OPB0_XFER_SIZE);
185 writel(addr, base + OPB0_FSI_ADDR);
186 writel(val, base + OPB0_FSI_DATA_W);
187 writel(0x1, base + OPB_IRQ_CLEAR);
188 writel(0x1, base + OPB_TRIGGER);
189
190 ret = readl_poll_timeout(base + OPB_IRQ_STATUS, reg,
191 (reg & OPB0_XFER_ACK_EN) != 0,
192 10000);
193
194 status = readl(base + OPB0_STATUS);
195
196 trace_aspeed_fsi_opb_write(addr, val, size, status, reg);
197
198 /* Return error when poll timed out */
199 if (ret)
200 return ret;
201
202 /* Command failed, master will reset */
203 if (status & STATUS_ERR_ACK)
204 return -EIO;
205
206 return 0;
207 }
208
opb_read(struct fsi_master_aspeed * aspeed,uint32_t addr,size_t size,u32 * out)209 static int opb_read(struct fsi_master_aspeed *aspeed, uint32_t addr,
210 size_t size, u32 *out)
211 {
212 void __iomem *base = aspeed->base;
213 u32 result, reg;
214 int status, ret;
215
216 /* TODO: implement other sizes, see 0x18 */
217 WARN_ON(size != 4);
218
219 writel(CMD_READ, base + OPB0_RW);
220 writel(XFER_WORD, base + OPB0_XFER_SIZE);
221 writel(addr, base + OPB0_FSI_ADDR);
222 writel(0x1, base + OPB_IRQ_CLEAR);
223 writel(0x1, base + OPB_TRIGGER);
224
225 ret = readl_poll_timeout(base + OPB_IRQ_STATUS, reg,
226 (reg & OPB0_XFER_ACK_EN) != 0,
227 10000);
228
229 status = readl(base + OPB0_STATUS);
230
231 result = readl(base + OPB0_FSI_DATA_R);
232
233 trace_aspeed_fsi_opb_read(addr, size, result,
234 readl(base + OPB0_STATUS),
235 reg);
236
237 /* Return error when poll timed out */
238 if (ret)
239 return ret;
240
241 /* Command failed, master will reset */
242 if (status & STATUS_ERR_ACK)
243 return -EIO;
244
245 if (out)
246 *out = result;
247
248 return 0;
249 }
250
check_errors(struct fsi_master_aspeed * aspeed,int err)251 static int check_errors(struct fsi_master_aspeed *aspeed, int err)
252 {
253 int ret;
254
255 if (trace_aspeed_fsi_opb_error_enabled()) {
256 __be32 mresp0, mstap0, mesrb0;
257
258 opb_read(aspeed, ctrl_base + FSI_MRESP0, 4, &mresp0);
259 opb_read(aspeed, ctrl_base + FSI_MSTAP0, 4, &mstap0);
260 opb_read(aspeed, ctrl_base + FSI_MESRB0, 4, &mesrb0);
261
262 trace_aspeed_fsi_opb_error(
263 be32_to_cpu(mresp0),
264 be32_to_cpu(mstap0),
265 be32_to_cpu(mesrb0));
266 };
267
268 if (err == -EIO) {
269 /* Check MAEB (0x70) ? */
270
271 /* Then clear errors in master */
272 ret = opb_write(aspeed, ctrl_base + 0xd0,
273 cpu_to_be32(0x20000000), 4);
274 if (ret) {
275 /* TODO: log? return different code? */
276 return ret;
277 }
278 /* TODO: confirm that 0x70 was okay */
279 }
280
281 /* This will pass through timeout errors */
282 return err;
283 }
284
aspeed_fsi_read(struct fsi_master_aspeed * aspeed,int link,uint32_t addr,void * val,size_t size)285 int aspeed_fsi_read(struct fsi_master_aspeed *aspeed, int link,
286 uint32_t addr, void *val, size_t size)
287 {
288 int ret;
289
290 addr += link * FSI_HUB_LINK_SIZE;
291 ret = opb_read(aspeed, fsi_base + addr, size, val);
292
293 ret = check_errors(aspeed, ret);
294 if (ret)
295 return ret;
296
297 return 0;
298 }
299
aspeed_fsi_write(struct fsi_master_aspeed * aspeed,int link,uint8_t id,uint32_t addr,const void * val,size_t size)300 int aspeed_fsi_write(struct fsi_master_aspeed *aspeed, int link,
301 uint8_t id, uint32_t addr, const void *val, size_t size)
302 {
303 int ret;
304
305 if (id != 0)
306 return -EINVAL;
307
308 addr += link * FSI_HUB_LINK_SIZE;
309 ret = opb_write(aspeed, fsi_base + addr, *(uint32_t *)val, size);
310
311 ret = check_errors(aspeed, ret);
312 if (ret)
313 return ret;
314
315 return 0;
316 }
317
aspeed_fsi_link_enable(struct fsi_master_aspeed * aspeed,int link)318 int aspeed_fsi_link_enable(struct fsi_master_aspeed *aspeed, int link)
319 {
320 int idx, bit, ret;
321 __be32 reg, result;
322
323 idx = link / 32;
324 bit = link % 32;
325
326 reg = cpu_to_be32(0x80000000 >> bit);
327
328 result = opb_write(aspeed, ctrl_base + FSI_MSENP0 + (4 * idx),
329 reg, 4);
330
331 mdelay(FSI_LINK_ENABLE_SETUP_TIME);
332
333 ret = opb_read(aspeed, ctrl_base + FSI_MENP0 + (4 * idx),
334 4, &result);
335 if (ret)
336 return ret;
337
338 if (result != reg) {
339 dev_err(aspeed->dev, "%s failed: %08x\n", __func__, result);
340 return -EIO;
341 }
342
343 return 0;
344 }
345
aspeed_fsi_break(struct fsi_master_aspeed * aspeed,int link)346 int aspeed_fsi_break(struct fsi_master_aspeed *aspeed, int link)
347 {
348 uint32_t addr;
349 __be32 cmd;
350 int rc;
351
352 addr = 0x0;
353 cmd = cpu_to_be32(0xc0de0000);
354
355 dev_dbg(aspeed->dev, "sending break to link %d\n", link);
356
357 rc = aspeed_fsi_write(aspeed, link, 0, addr, &cmd, 4);
358
359 dev_dbg(aspeed->dev, "break done (%d)\n", rc);
360
361 return rc;
362 }
363
aspeed_fsi_status(struct fsi_master_aspeed * aspeed)364 void aspeed_fsi_status(struct fsi_master_aspeed *aspeed)
365 {
366 __be32 mmode, mresp0, mstap0, mesrb0;
367
368 printf("%s\n", aspeed->dev->name);
369
370 opb_read(aspeed, ctrl_base + FSI_MMODE, 4, &mmode);
371 opb_read(aspeed, ctrl_base + FSI_MRESP0, 4, &mresp0);
372 opb_read(aspeed, ctrl_base + FSI_MSTAP0, 4, &mstap0);
373 opb_read(aspeed, ctrl_base + FSI_MESRB0, 4, &mesrb0);
374
375 printf("mmode %08x\n", be32_to_cpu(mmode));
376 printf("mresp %08x\n", be32_to_cpu(mresp0));
377 printf("mstap %08x\n", be32_to_cpu(mstap0));
378 printf("mesrb %08x\n", be32_to_cpu(mesrb0));
379 }
380
aspeed_fsi_divisor(struct fsi_master_aspeed * aspeed,uint16_t divisor)381 int aspeed_fsi_divisor(struct fsi_master_aspeed *aspeed, uint16_t divisor)
382 {
383 __be32 reg;
384 u32 mmode;
385 int rc;
386
387 rc = opb_read(aspeed, ctrl_base + FSI_MMODE, 4, ®);
388 if (rc)
389 return rc;
390
391 mmode = be32_to_cpu(reg);
392
393 if (!divisor)
394 return (mmode >> 18) & 0x3ff;
395
396 if (divisor > 0x3ff)
397 return -EINVAL;
398
399 mmode &= ~(0x3ff << 18);
400 mmode |= (divisor & 0x3ff) << 18;
401
402 return opb_write(aspeed, ctrl_base + FSI_MMODE, cpu_to_be32(mmode), 4);
403 }
404
405 /* mmode encoders */
fsi_mmode_crs0(u32 x)406 static inline u32 fsi_mmode_crs0(u32 x)
407 {
408 return (x & FSI_MMODE_CRS0MASK) << FSI_MMODE_CRS0SHFT;
409 }
410
fsi_mmode_crs1(u32 x)411 static inline u32 fsi_mmode_crs1(u32 x)
412 {
413 return (x & FSI_MMODE_CRS1MASK) << FSI_MMODE_CRS1SHFT;
414 }
415
aspeed_fsi_init(struct fsi_master_aspeed * aspeed)416 static int aspeed_fsi_init(struct fsi_master_aspeed *aspeed)
417 {
418 __be32 reg;
419
420 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK
421 | FSI_MRESP_RST_MCR | FSI_MRESP_RST_PYE);
422 opb_write(aspeed, ctrl_base + FSI_MRESP0, reg, 4);
423
424 /* Initialize the MFSI (hub master) engine */
425 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK
426 | FSI_MRESP_RST_MCR | FSI_MRESP_RST_PYE);
427 opb_write(aspeed, ctrl_base + FSI_MRESP0, reg, 4);
428
429 reg = cpu_to_be32(FSI_MECTRL_EOAE | FSI_MECTRL_P8_AUTO_TERM);
430 opb_write(aspeed, ctrl_base + FSI_MECTRL, reg, 4);
431
432 reg = cpu_to_be32(FSI_MMODE_ECRC | FSI_MMODE_EPC | FSI_MMODE_RELA
433 | fsi_mmode_crs0(DEFAULT_DIVISOR)
434 | fsi_mmode_crs1(DEFAULT_DIVISOR)
435 | FSI_MMODE_P8_TO_LSB);
436 opb_write(aspeed, ctrl_base + FSI_MMODE, reg, 4);
437
438 reg = cpu_to_be32(0xffff0000);
439 opb_write(aspeed, ctrl_base + FSI_MDLYR, reg, 4);
440
441 reg = cpu_to_be32(~0);
442 opb_write(aspeed, ctrl_base + FSI_MSENP0, reg, 4);
443
444 /* Leave enabled long enough for master logic to set up */
445 mdelay(FSI_LINK_ENABLE_SETUP_TIME);
446
447 opb_write(aspeed, ctrl_base + FSI_MCENP0, reg, 4);
448
449 opb_read(aspeed, ctrl_base + FSI_MAEB, 4, NULL);
450
451 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK);
452 opb_write(aspeed, ctrl_base + FSI_MRESP0, reg, 4);
453
454 opb_read(aspeed, ctrl_base + FSI_MLEVP0, 4, NULL);
455
456 /* Reset the master bridge */
457 reg = cpu_to_be32(FSI_MRESB_RST_GEN);
458 opb_write(aspeed, ctrl_base + FSI_MRESB0, reg, 4);
459
460 reg = cpu_to_be32(FSI_MRESB_RST_ERR);
461 opb_write(aspeed, ctrl_base + FSI_MRESB0, reg, 4);
462
463 return 0;
464 }
465
aspeed_fsi_probe(struct udevice * dev)466 static int aspeed_fsi_probe(struct udevice *dev)
467 {
468 struct fsi_master_aspeed *aspeed = dev_get_priv(dev);
469 int ret, links, reg;
470 __be32 raw;
471
472 aspeed->dev = dev;
473
474 aspeed->base = (void *)devfdt_get_addr(dev);
475
476 ret = clk_get_by_index(dev, 0, &aspeed->clk);
477 if (ret < 0) {
478 dev_err(dev, "Can't get clock for %s: %d\n", dev->name, ret);
479 return ret;
480 }
481
482 ret = clk_enable(&aspeed->clk);
483 if (ret) {
484 dev_err(dev, "failed to enable fsi clock (%d)\n", ret);
485 return ret;
486 }
487
488 writel(0x1, aspeed->base + OPB_CLK_SYNC);
489 writel(OPB1_XFER_ACK_EN | OPB0_XFER_ACK_EN,
490 aspeed->base + OPB_IRQ_MASK);
491
492 writel(ctrl_base, aspeed->base + OPB_CTRL_BASE);
493 writel(fsi_base, aspeed->base + OPB_FSI_BASE);
494
495 /* Set read data order */
496 writel(0x00030b1b, aspeed->base + OPB0_R_ENDIAN);
497
498 /* Set write data order */
499 writel(0x0011bb1b, aspeed->base + OPB0_W_ENDIAN);
500 writel(0xffaa5500, aspeed->base + 0x50);
501
502 /*
503 * Select OPB0 for all operations.
504 * Will need to be reworked when enabling DMA or anything that uses
505 * OPB1.
506 */
507 writel(0x1, aspeed->base + OPB0_SELECT);
508
509 ret = opb_read(aspeed, ctrl_base + FSI_MVER, 4, &raw);
510 if (ret) {
511 dev_err(&pdev->dev, "failed to read hub version\n");
512 goto err;
513 }
514
515 reg = be32_to_cpu(raw);
516 links = (reg >> 8) & 0xff;
517 dev_info(&pdev->dev, "hub version %08x (%d links)\n", reg, links);
518
519 aspeed_fsi_init(aspeed);
520
521 printf("FSI: probed %p\n", aspeed->base);
522
523 return 0;
524
525 err:
526 clk_disable(&aspeed->clk);
527 return ret;
528 }
529
aspeed_fsi_remove(struct udevice * dev)530 static int aspeed_fsi_remove(struct udevice *dev)
531 {
532 struct fsi_master_aspeed *aspeed = dev_get_priv(dev);
533
534 clk_disable(&aspeed->clk);
535
536 return 0;
537 }
538
539 static const struct udevice_id aspeed_fsi_ids[] = {
540 { .compatible = "aspeed,ast2600-fsi-master" },
541 { }
542 };
543
544 U_BOOT_DRIVER(aspeed_fsi) = {
545 .name = "aspeed_fsi",
546 .id = UCLASS_MISC,
547 .of_match = aspeed_fsi_ids,
548 .probe = aspeed_fsi_probe,
549 .remove = aspeed_fsi_remove,
550 .priv_auto_alloc_size = sizeof(struct fsi_master_aspeed),
551 };
552