1 // SPDX-License-Identifier: GPL-2.0-or-later
2 // Copyright (C) IBM Corporation 2018
3 // FSI master driver for AST2600
6 #include <linux/delay.h>
9 #include <linux/mfd/syscon.h>
10 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
14 #include <linux/slab.h>
15 #include <linux/iopoll.h>
16 #include <linux/gpio/consumer.h>
18 #include "fsi-master.h"
20 struct fsi_master_aspeed
{
21 struct fsi_master master
;
25 struct gpio_desc
*cfam_reset_gpio
;
28 #define to_fsi_master_aspeed(m) \
29 container_of(m, struct fsi_master_aspeed, master)
31 /* Control register (size 0x400) */
32 static const u32 ctrl_base
= 0x80000000;
34 static const u32 fsi_base
= 0xa0000000;
36 #define OPB_FSI_VER 0x00
37 #define OPB_TRIGGER 0x04
38 #define OPB_CTRL_BASE 0x08
39 #define OPB_FSI_BASE 0x0c
40 #define OPB_CLK_SYNC 0x3c
41 #define OPB_IRQ_CLEAR 0x40
42 #define OPB_IRQ_MASK 0x44
43 #define OPB_IRQ_STATUS 0x48
45 #define OPB0_SELECT 0x10
47 #define OPB0_XFER_SIZE 0x18
48 #define OPB0_FSI_ADDR 0x1c
49 #define OPB0_FSI_DATA_W 0x20
50 #define OPB0_STATUS 0x80
51 #define OPB0_FSI_DATA_R 0x84
53 #define OPB0_WRITE_ORDER1 0x4c
54 #define OPB0_WRITE_ORDER2 0x50
55 #define OPB1_WRITE_ORDER1 0x54
56 #define OPB1_WRITE_ORDER2 0x58
57 #define OPB0_READ_ORDER1 0x5c
58 #define OPB1_READ_ORDER2 0x60
60 #define OPB_RETRY_COUNTER 0x64
63 #define STATUS_HALFWORD_ACK BIT(0)
64 #define STATUS_FULLWORD_ACK BIT(1)
65 #define STATUS_ERR_ACK BIT(2)
66 #define STATUS_RETRY BIT(3)
67 #define STATUS_TIMEOUT BIT(4)
70 #define OPB1_XFER_ACK_EN BIT(17)
71 #define OPB0_XFER_ACK_EN BIT(16)
74 #define CMD_READ BIT(0)
78 #define XFER_FULLWORD (BIT(1) | BIT(0))
79 #define XFER_HALFWORD (BIT(0))
82 #define CREATE_TRACE_POINTS
83 #include <trace/events/fsi_master_aspeed.h>
85 #define FSI_LINK_ENABLE_SETUP_TIME 10 /* in mS */
87 /* Run the bus at maximum speed by default */
88 #define FSI_DIVISOR_DEFAULT 1
89 #define FSI_DIVISOR_CABLED 2
90 static u16 aspeed_fsi_divisor
= FSI_DIVISOR_DEFAULT
;
91 module_param_named(bus_div
,aspeed_fsi_divisor
, ushort
, 0);
93 #define OPB_POLL_TIMEOUT 10000
95 static int __opb_write(struct fsi_master_aspeed
*aspeed
, u32 addr
,
96 u32 val
, u32 transfer_size
)
98 void __iomem
*base
= aspeed
->base
;
102 writel(CMD_WRITE
, base
+ OPB0_RW
);
103 writel(transfer_size
, base
+ OPB0_XFER_SIZE
);
104 writel(addr
, base
+ OPB0_FSI_ADDR
);
105 writel(val
, base
+ OPB0_FSI_DATA_W
);
106 writel(0x1, base
+ OPB_IRQ_CLEAR
);
107 writel(0x1, base
+ OPB_TRIGGER
);
109 ret
= readl_poll_timeout(base
+ OPB_IRQ_STATUS
, reg
,
110 (reg
& OPB0_XFER_ACK_EN
) != 0,
111 0, OPB_POLL_TIMEOUT
);
113 status
= readl(base
+ OPB0_STATUS
);
115 trace_fsi_master_aspeed_opb_write(addr
, val
, transfer_size
, status
, reg
);
117 /* Return error when poll timed out */
121 /* Command failed, master will reset */
122 if (status
& STATUS_ERR_ACK
)
128 static int opb_writeb(struct fsi_master_aspeed
*aspeed
, u32 addr
, u8 val
)
130 return __opb_write(aspeed
, addr
, val
, XFER_BYTE
);
133 static int opb_writew(struct fsi_master_aspeed
*aspeed
, u32 addr
, __be16 val
)
135 return __opb_write(aspeed
, addr
, (__force u16
)val
, XFER_HALFWORD
);
138 static int opb_writel(struct fsi_master_aspeed
*aspeed
, u32 addr
, __be32 val
)
140 return __opb_write(aspeed
, addr
, (__force u32
)val
, XFER_FULLWORD
);
143 static int __opb_read(struct fsi_master_aspeed
*aspeed
, uint32_t addr
,
144 u32 transfer_size
, void *out
)
146 void __iomem
*base
= aspeed
->base
;
150 writel(CMD_READ
, base
+ OPB0_RW
);
151 writel(transfer_size
, base
+ OPB0_XFER_SIZE
);
152 writel(addr
, base
+ OPB0_FSI_ADDR
);
153 writel(0x1, base
+ OPB_IRQ_CLEAR
);
154 writel(0x1, base
+ OPB_TRIGGER
);
156 ret
= readl_poll_timeout(base
+ OPB_IRQ_STATUS
, reg
,
157 (reg
& OPB0_XFER_ACK_EN
) != 0,
158 0, OPB_POLL_TIMEOUT
);
160 status
= readl(base
+ OPB0_STATUS
);
162 result
= readl(base
+ OPB0_FSI_DATA_R
);
164 trace_fsi_master_aspeed_opb_read(addr
, transfer_size
, result
,
165 readl(base
+ OPB0_STATUS
),
168 /* Return error when poll timed out */
172 /* Command failed, master will reset */
173 if (status
& STATUS_ERR_ACK
)
177 switch (transfer_size
) {
182 *(u16
*)out
= result
;
185 *(u32
*)out
= result
;
196 static int opb_readl(struct fsi_master_aspeed
*aspeed
, uint32_t addr
, __be32
*out
)
198 return __opb_read(aspeed
, addr
, XFER_FULLWORD
, out
);
201 static int opb_readw(struct fsi_master_aspeed
*aspeed
, uint32_t addr
, __be16
*out
)
203 return __opb_read(aspeed
, addr
, XFER_HALFWORD
, (void *)out
);
206 static int opb_readb(struct fsi_master_aspeed
*aspeed
, uint32_t addr
, u8
*out
)
208 return __opb_read(aspeed
, addr
, XFER_BYTE
, (void *)out
);
211 static int check_errors(struct fsi_master_aspeed
*aspeed
, int err
)
215 if (trace_fsi_master_aspeed_opb_error_enabled()) {
216 __be32 mresp0
, mstap0
, mesrb0
;
218 opb_readl(aspeed
, ctrl_base
+ FSI_MRESP0
, &mresp0
);
219 opb_readl(aspeed
, ctrl_base
+ FSI_MSTAP0
, &mstap0
);
220 opb_readl(aspeed
, ctrl_base
+ FSI_MESRB0
, &mesrb0
);
222 trace_fsi_master_aspeed_opb_error(
225 be32_to_cpu(mesrb0
));
229 /* Check MAEB (0x70) ? */
231 /* Then clear errors in master */
232 ret
= opb_writel(aspeed
, ctrl_base
+ FSI_MRESP0
,
233 cpu_to_be32(FSI_MRESP_RST_ALL_MASTER
));
235 /* TODO: log? return different code? */
238 /* TODO: confirm that 0x70 was okay */
241 /* This will pass through timeout errors */
245 static int aspeed_master_read(struct fsi_master
*master
, int link
,
246 uint8_t id
, uint32_t addr
, void *val
, size_t size
)
248 struct fsi_master_aspeed
*aspeed
= to_fsi_master_aspeed(master
);
255 addr
+= link
* FSI_HUB_LINK_SIZE
;
259 ret
= opb_readb(aspeed
, fsi_base
+ addr
, val
);
262 ret
= opb_readw(aspeed
, fsi_base
+ addr
, val
);
265 ret
= opb_readl(aspeed
, fsi_base
+ addr
, val
);
271 ret
= check_errors(aspeed
, ret
);
278 static int aspeed_master_write(struct fsi_master
*master
, int link
,
279 uint8_t id
, uint32_t addr
, const void *val
, size_t size
)
281 struct fsi_master_aspeed
*aspeed
= to_fsi_master_aspeed(master
);
288 addr
+= link
* FSI_HUB_LINK_SIZE
;
292 ret
= opb_writeb(aspeed
, fsi_base
+ addr
, *(u8
*)val
);
295 ret
= opb_writew(aspeed
, fsi_base
+ addr
, *(__be16
*)val
);
298 ret
= opb_writel(aspeed
, fsi_base
+ addr
, *(__be32
*)val
);
304 ret
= check_errors(aspeed
, ret
);
311 static int aspeed_master_link_enable(struct fsi_master
*master
, int link
,
314 struct fsi_master_aspeed
*aspeed
= to_fsi_master_aspeed(master
);
321 reg
= cpu_to_be32(0x80000000 >> bit
);
324 return opb_writel(aspeed
, ctrl_base
+ FSI_MCENP0
+ (4 * idx
),
327 ret
= opb_writel(aspeed
, ctrl_base
+ FSI_MSENP0
+ (4 * idx
), reg
);
331 mdelay(FSI_LINK_ENABLE_SETUP_TIME
);
336 static int aspeed_master_term(struct fsi_master
*master
, int link
, uint8_t id
)
342 cmd
= cpu_to_be32(0xecc00000);
344 return aspeed_master_write(master
, link
, id
, addr
, &cmd
, 4);
347 static int aspeed_master_break(struct fsi_master
*master
, int link
)
353 cmd
= cpu_to_be32(0xc0de0000);
355 return aspeed_master_write(master
, link
, 0, addr
, &cmd
, 4);
358 static void aspeed_master_release(struct device
*dev
)
360 struct fsi_master_aspeed
*aspeed
=
361 to_fsi_master_aspeed(dev_to_fsi_master(dev
));
367 static inline u32
fsi_mmode_crs0(u32 x
)
369 return (x
& FSI_MMODE_CRS0MASK
) << FSI_MMODE_CRS0SHFT
;
372 static inline u32
fsi_mmode_crs1(u32 x
)
374 return (x
& FSI_MMODE_CRS1MASK
) << FSI_MMODE_CRS1SHFT
;
377 static int aspeed_master_init(struct fsi_master_aspeed
*aspeed
)
381 reg
= cpu_to_be32(FSI_MRESP_RST_ALL_MASTER
| FSI_MRESP_RST_ALL_LINK
382 | FSI_MRESP_RST_MCR
| FSI_MRESP_RST_PYE
);
383 opb_writel(aspeed
, ctrl_base
+ FSI_MRESP0
, reg
);
385 /* Initialize the MFSI (hub master) engine */
386 reg
= cpu_to_be32(FSI_MRESP_RST_ALL_MASTER
| FSI_MRESP_RST_ALL_LINK
387 | FSI_MRESP_RST_MCR
| FSI_MRESP_RST_PYE
);
388 opb_writel(aspeed
, ctrl_base
+ FSI_MRESP0
, reg
);
390 reg
= cpu_to_be32(FSI_MECTRL_EOAE
| FSI_MECTRL_P8_AUTO_TERM
);
391 opb_writel(aspeed
, ctrl_base
+ FSI_MECTRL
, reg
);
393 reg
= cpu_to_be32(FSI_MMODE_ECRC
| FSI_MMODE_EPC
| FSI_MMODE_RELA
394 | fsi_mmode_crs0(aspeed_fsi_divisor
)
395 | fsi_mmode_crs1(aspeed_fsi_divisor
)
396 | FSI_MMODE_P8_TO_LSB
);
397 dev_info(aspeed
->dev
, "mmode set to %08x (divisor %d)\n",
398 be32_to_cpu(reg
), aspeed_fsi_divisor
);
399 opb_writel(aspeed
, ctrl_base
+ FSI_MMODE
, reg
);
401 reg
= cpu_to_be32(0xffff0000);
402 opb_writel(aspeed
, ctrl_base
+ FSI_MDLYR
, reg
);
404 reg
= cpu_to_be32(~0);
405 opb_writel(aspeed
, ctrl_base
+ FSI_MSENP0
, reg
);
407 /* Leave enabled long enough for master logic to set up */
408 mdelay(FSI_LINK_ENABLE_SETUP_TIME
);
410 opb_writel(aspeed
, ctrl_base
+ FSI_MCENP0
, reg
);
412 opb_readl(aspeed
, ctrl_base
+ FSI_MAEB
, NULL
);
414 reg
= cpu_to_be32(FSI_MRESP_RST_ALL_MASTER
| FSI_MRESP_RST_ALL_LINK
);
415 opb_writel(aspeed
, ctrl_base
+ FSI_MRESP0
, reg
);
417 opb_readl(aspeed
, ctrl_base
+ FSI_MLEVP0
, NULL
);
419 /* Reset the master bridge */
420 reg
= cpu_to_be32(FSI_MRESB_RST_GEN
);
421 opb_writel(aspeed
, ctrl_base
+ FSI_MRESB0
, reg
);
423 reg
= cpu_to_be32(FSI_MRESB_RST_ERR
);
424 opb_writel(aspeed
, ctrl_base
+ FSI_MRESB0
, reg
);
429 static ssize_t
cfam_reset_store(struct device
*dev
, struct device_attribute
*attr
,
430 const char *buf
, size_t count
)
432 struct fsi_master_aspeed
*aspeed
= dev_get_drvdata(dev
);
434 gpiod_set_value(aspeed
->cfam_reset_gpio
, 1);
435 usleep_range(900, 1000);
436 gpiod_set_value(aspeed
->cfam_reset_gpio
, 0);
441 static DEVICE_ATTR(cfam_reset
, 0200, NULL
, cfam_reset_store
);
443 static int setup_cfam_reset(struct fsi_master_aspeed
*aspeed
)
445 struct device
*dev
= aspeed
->dev
;
446 struct gpio_desc
*gpio
;
449 gpio
= devm_gpiod_get_optional(dev
, "cfam-reset", GPIOD_OUT_LOW
);
451 return PTR_ERR(gpio
);
455 aspeed
->cfam_reset_gpio
= gpio
;
457 rc
= device_create_file(dev
, &dev_attr_cfam_reset
);
459 devm_gpiod_put(dev
, gpio
);
466 static int tacoma_cabled_fsi_fixup(struct device
*dev
)
468 struct gpio_desc
*routing_gpio
, *mux_gpio
;
472 * The routing GPIO is a jumper indicating we should mux for the
473 * externally connected FSI cable.
475 routing_gpio
= devm_gpiod_get_optional(dev
, "fsi-routing",
476 GPIOD_IN
| GPIOD_FLAGS_BIT_NONEXCLUSIVE
);
477 if (IS_ERR(routing_gpio
))
478 return PTR_ERR(routing_gpio
);
482 mux_gpio
= devm_gpiod_get_optional(dev
, "fsi-mux", GPIOD_ASIS
);
483 if (IS_ERR(mux_gpio
))
484 return PTR_ERR(mux_gpio
);
488 gpio
= gpiod_get_value(routing_gpio
);
492 /* If the routing GPIO is high we should set the mux to low. */
495 * Cable signal integrity means we should run the bus
496 * slightly slower. Do not override if a kernel param
497 * has already overridden.
499 if (aspeed_fsi_divisor
== FSI_DIVISOR_DEFAULT
)
500 aspeed_fsi_divisor
= FSI_DIVISOR_CABLED
;
502 gpiod_direction_output(mux_gpio
, 0);
503 dev_info(dev
, "FSI configured for external cable\n");
505 gpiod_direction_output(mux_gpio
, 1);
508 devm_gpiod_put(dev
, routing_gpio
);
513 static int fsi_master_aspeed_probe(struct platform_device
*pdev
)
515 struct fsi_master_aspeed
*aspeed
;
516 struct resource
*res
;
520 rc
= tacoma_cabled_fsi_fixup(&pdev
->dev
);
522 dev_err(&pdev
->dev
, "Tacoma FSI cable fixup failed\n");
526 aspeed
= devm_kzalloc(&pdev
->dev
, sizeof(*aspeed
), GFP_KERNEL
);
530 aspeed
->dev
= &pdev
->dev
;
532 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
533 aspeed
->base
= devm_ioremap_resource(&pdev
->dev
, res
);
534 if (IS_ERR(aspeed
->base
))
535 return PTR_ERR(aspeed
->base
);
537 aspeed
->clk
= devm_clk_get(aspeed
->dev
, NULL
);
538 if (IS_ERR(aspeed
->clk
)) {
539 dev_err(aspeed
->dev
, "couldn't get clock\n");
540 return PTR_ERR(aspeed
->clk
);
542 rc
= clk_prepare_enable(aspeed
->clk
);
544 dev_err(aspeed
->dev
, "couldn't enable clock\n");
548 rc
= setup_cfam_reset(aspeed
);
550 dev_err(&pdev
->dev
, "CFAM reset GPIO setup failed\n");
553 writel(0x1, aspeed
->base
+ OPB_CLK_SYNC
);
554 writel(OPB1_XFER_ACK_EN
| OPB0_XFER_ACK_EN
,
555 aspeed
->base
+ OPB_IRQ_MASK
);
557 /* TODO: determine an appropriate value */
558 writel(0x10, aspeed
->base
+ OPB_RETRY_COUNTER
);
560 writel(ctrl_base
, aspeed
->base
+ OPB_CTRL_BASE
);
561 writel(fsi_base
, aspeed
->base
+ OPB_FSI_BASE
);
563 /* Set read data order */
564 writel(0x00030b1b, aspeed
->base
+ OPB0_READ_ORDER1
);
566 /* Set write data order */
567 writel(0x0011101b, aspeed
->base
+ OPB0_WRITE_ORDER1
);
568 writel(0x0c330f3f, aspeed
->base
+ OPB0_WRITE_ORDER2
);
571 * Select OPB0 for all operations.
572 * Will need to be reworked when enabling DMA or anything that uses
575 writel(0x1, aspeed
->base
+ OPB0_SELECT
);
577 rc
= opb_readl(aspeed
, ctrl_base
+ FSI_MVER
, &raw
);
579 dev_err(&pdev
->dev
, "failed to read hub version\n");
583 reg
= be32_to_cpu(raw
);
584 links
= (reg
>> 8) & 0xff;
585 dev_info(&pdev
->dev
, "hub version %08x (%d links)\n", reg
, links
);
587 aspeed
->master
.dev
.parent
= &pdev
->dev
;
588 aspeed
->master
.dev
.release
= aspeed_master_release
;
589 aspeed
->master
.dev
.of_node
= of_node_get(dev_of_node(&pdev
->dev
));
591 aspeed
->master
.n_links
= links
;
592 aspeed
->master
.read
= aspeed_master_read
;
593 aspeed
->master
.write
= aspeed_master_write
;
594 aspeed
->master
.send_break
= aspeed_master_break
;
595 aspeed
->master
.term
= aspeed_master_term
;
596 aspeed
->master
.link_enable
= aspeed_master_link_enable
;
598 dev_set_drvdata(&pdev
->dev
, aspeed
);
600 aspeed_master_init(aspeed
);
602 rc
= fsi_master_register(&aspeed
->master
);
606 /* At this point, fsi_master_register performs the device_initialize(),
607 * and holds the sole reference on master.dev. This means the device
608 * will be freed (via ->release) during any subsequent call to
609 * fsi_master_unregister. We add our own reference to it here, so we
610 * can perform cleanup (in _remove()) without it being freed before
613 get_device(&aspeed
->master
.dev
);
617 clk_disable_unprepare(aspeed
->clk
);
621 static int fsi_master_aspeed_remove(struct platform_device
*pdev
)
623 struct fsi_master_aspeed
*aspeed
= platform_get_drvdata(pdev
);
625 fsi_master_unregister(&aspeed
->master
);
626 clk_disable_unprepare(aspeed
->clk
);
631 static const struct of_device_id fsi_master_aspeed_match
[] = {
632 { .compatible
= "aspeed,ast2600-fsi-master" },
636 static struct platform_driver fsi_master_aspeed_driver
= {
638 .name
= "fsi-master-aspeed",
639 .of_match_table
= fsi_master_aspeed_match
,
641 .probe
= fsi_master_aspeed_probe
,
642 .remove
= fsi_master_aspeed_remove
,
645 module_platform_driver(fsi_master_aspeed_driver
);
646 MODULE_LICENSE("GPL");