xref: /openbmc/u-boot/drivers/misc/aspeed-fsi.c (revision 18b134e0)
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, &reg);
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