xref: /linux/drivers/fsi/fsi-master.h (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
11802d0beSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
209aecfabSJeremy Kerr /*
309aecfabSJeremy Kerr  * FSI master definitions. These comprise the core <--> master interface,
409aecfabSJeremy Kerr  * to allow the core to interact with the (hardware-specific) masters.
509aecfabSJeremy Kerr  *
609aecfabSJeremy Kerr  * Copyright (C) IBM Corporation 2016
709aecfabSJeremy Kerr  */
809aecfabSJeremy Kerr 
909aecfabSJeremy Kerr #ifndef DRIVERS_FSI_MASTER_H
1009aecfabSJeremy Kerr #define DRIVERS_FSI_MASTER_H
1109aecfabSJeremy Kerr 
1209aecfabSJeremy Kerr #include <linux/device.h>
139840fcd8SBenjamin Herrenschmidt #include <linux/mutex.h>
1409aecfabSJeremy Kerr 
158bcd06d0SJoel Stanley /*
168bcd06d0SJoel Stanley  * Master registers
178bcd06d0SJoel Stanley  *
188bcd06d0SJoel Stanley  * These are used by hardware masters, such as the one in the FSP2, AST2600 and
198bcd06d0SJoel Stanley  * the hub master in POWER processors.
208bcd06d0SJoel Stanley  */
218bcd06d0SJoel Stanley 
228bcd06d0SJoel Stanley /* Control Registers */
238bcd06d0SJoel Stanley #define FSI_MMODE		0x0		/* R/W: mode */
248bcd06d0SJoel Stanley #define FSI_MDLYR		0x4		/* R/W: delay */
258bcd06d0SJoel Stanley #define FSI_MCRSP		0x8		/* R/W: clock rate */
268bcd06d0SJoel Stanley #define FSI_MENP0		0x10		/* R/W: enable */
278bcd06d0SJoel Stanley #define FSI_MLEVP0		0x18		/* R: plug detect */
288bcd06d0SJoel Stanley #define FSI_MSENP0		0x18		/* S: Set enable */
298bcd06d0SJoel Stanley #define FSI_MCENP0		0x20		/* C: Clear enable */
308bcd06d0SJoel Stanley #define FSI_MAEB		0x70		/* R: Error address */
318bcd06d0SJoel Stanley #define FSI_MVER		0x74		/* R: master version/type */
328bcd06d0SJoel Stanley #define FSI_MSTAP0		0xd0		/* R: Port status */
338bcd06d0SJoel Stanley #define FSI_MRESP0		0xd0		/* W: Port reset */
348bcd06d0SJoel Stanley #define FSI_MESRB0		0x1d0		/* R: Master error status */
358bcd06d0SJoel Stanley #define FSI_MRESB0		0x1d0		/* W: Reset bridge */
368bcd06d0SJoel Stanley #define FSI_MSCSB0		0x1d4		/* R: Master sub command stack */
378bcd06d0SJoel Stanley #define FSI_MATRB0		0x1d8		/* R: Master address trace */
388bcd06d0SJoel Stanley #define FSI_MDTRB0		0x1dc		/* R: Master data trace */
398bcd06d0SJoel Stanley #define FSI_MECTRL		0x2e0		/* W: Error control */
408bcd06d0SJoel Stanley 
418bcd06d0SJoel Stanley /* MMODE: Mode control */
428bcd06d0SJoel Stanley #define FSI_MMODE_EIP		0x80000000	/* Enable interrupt polling */
438bcd06d0SJoel Stanley #define FSI_MMODE_ECRC		0x40000000	/* Enable error recovery */
448bcd06d0SJoel Stanley #define FSI_MMODE_RELA		0x20000000	/* Enable relative address commands */
458bcd06d0SJoel Stanley #define FSI_MMODE_EPC		0x10000000	/* Enable parity checking */
468bcd06d0SJoel Stanley #define FSI_MMODE_P8_TO_LSB	0x00000010	/* Timeout value LSB */
478bcd06d0SJoel Stanley 						/*   MSB=1, LSB=0 is 0.8 ms */
488bcd06d0SJoel Stanley 						/*   MSB=0, LSB=1 is 0.9 ms */
498bcd06d0SJoel Stanley #define FSI_MMODE_CRS0SHFT	18		/* Clk rate selection 0 shift */
508bcd06d0SJoel Stanley #define FSI_MMODE_CRS0MASK	0x3ff		/* Clk rate selection 0 mask */
518bcd06d0SJoel Stanley #define FSI_MMODE_CRS1SHFT	8		/* Clk rate selection 1 shift */
528bcd06d0SJoel Stanley #define FSI_MMODE_CRS1MASK	0x3ff		/* Clk rate selection 1 mask */
538bcd06d0SJoel Stanley 
54f157555eSLuo Xueqin /* MRESB: Reset bridge */
558bcd06d0SJoel Stanley #define FSI_MRESB_RST_GEN	0x80000000	/* General reset */
568bcd06d0SJoel Stanley #define FSI_MRESB_RST_ERR	0x40000000	/* Error Reset */
578bcd06d0SJoel Stanley 
588bcd06d0SJoel Stanley /* MRESP: Reset port */
598bcd06d0SJoel Stanley #define FSI_MRESP_RST_ALL_MASTER 0x20000000	/* Reset all FSI masters */
608bcd06d0SJoel Stanley #define FSI_MRESP_RST_ALL_LINK	0x10000000	/* Reset all FSI port contr. */
618bcd06d0SJoel Stanley #define FSI_MRESP_RST_MCR	0x08000000	/* Reset FSI master reg. */
628bcd06d0SJoel Stanley #define FSI_MRESP_RST_PYE	0x04000000	/* Reset FSI parity error */
638bcd06d0SJoel Stanley #define FSI_MRESP_RST_ALL	0xfc000000	/* Reset any error */
648bcd06d0SJoel Stanley 
658bcd06d0SJoel Stanley /* MECTRL: Error control */
668bcd06d0SJoel Stanley #define FSI_MECTRL_EOAE		0x8000		/* Enable machine check when */
678bcd06d0SJoel Stanley 						/* master 0 in error */
688bcd06d0SJoel Stanley #define FSI_MECTRL_P8_AUTO_TERM	0x4000		/* Auto terminate */
698bcd06d0SJoel Stanley 
708bcd06d0SJoel Stanley #define FSI_HUB_LINK_OFFSET		0x80000
718bcd06d0SJoel Stanley #define FSI_HUB_LINK_SIZE		0x80000
728bcd06d0SJoel Stanley #define FSI_HUB_MASTER_MAX_LINKS	8
738bcd06d0SJoel Stanley 
748bcd06d0SJoel Stanley /*
758bcd06d0SJoel Stanley  * Protocol definitions
768bcd06d0SJoel Stanley  *
778bcd06d0SJoel Stanley  * These are used by low level masters that bit-bang out the protocol
788bcd06d0SJoel Stanley  */
798bcd06d0SJoel Stanley 
80fea9cf32SBenjamin Herrenschmidt /* Various protocol delays */
81fea9cf32SBenjamin Herrenschmidt #define	FSI_ECHO_DELAY_CLOCKS	16	/* Number clocks for echo delay */
82fea9cf32SBenjamin Herrenschmidt #define	FSI_SEND_DELAY_CLOCKS	16	/* Number clocks for send delay */
83fea9cf32SBenjamin Herrenschmidt #define	FSI_PRE_BREAK_CLOCKS	50	/* Number clocks to prep for break */
84fea9cf32SBenjamin Herrenschmidt #define	FSI_BREAK_CLOCKS	256	/* Number of clocks to issue break */
85fea9cf32SBenjamin Herrenschmidt #define	FSI_POST_BREAK_CLOCKS	16000	/* Number clocks to set up cfam */
86fea9cf32SBenjamin Herrenschmidt #define	FSI_INIT_CLOCKS		5000	/* Clock out any old data */
87fea9cf32SBenjamin Herrenschmidt #define	FSI_MASTER_DPOLL_CLOCKS	50      /* < 21 will cause slave to hang */
88fea9cf32SBenjamin Herrenschmidt #define	FSI_MASTER_EPOLL_CLOCKS	50      /* Number of clocks for E_POLL retry */
89fea9cf32SBenjamin Herrenschmidt 
90fea9cf32SBenjamin Herrenschmidt /* Various retry maximums */
91fea9cf32SBenjamin Herrenschmidt #define FSI_CRC_ERR_RETRIES	10
92fea9cf32SBenjamin Herrenschmidt #define	FSI_MASTER_MAX_BUSY	200
93fea9cf32SBenjamin Herrenschmidt #define	FSI_MASTER_MTOE_COUNT	1000
94fea9cf32SBenjamin Herrenschmidt 
95fea9cf32SBenjamin Herrenschmidt /* Command encodings */
96fea9cf32SBenjamin Herrenschmidt #define	FSI_CMD_DPOLL		0x2
97fea9cf32SBenjamin Herrenschmidt #define	FSI_CMD_EPOLL		0x3
98fea9cf32SBenjamin Herrenschmidt #define	FSI_CMD_TERM		0x3f
99fea9cf32SBenjamin Herrenschmidt #define FSI_CMD_ABS_AR		0x4
100fea9cf32SBenjamin Herrenschmidt #define FSI_CMD_REL_AR		0x5
101fea9cf32SBenjamin Herrenschmidt #define FSI_CMD_SAME_AR		0x3	/* but only a 2-bit opcode... */
102fea9cf32SBenjamin Herrenschmidt 
103fea9cf32SBenjamin Herrenschmidt /* Slave responses */
104fea9cf32SBenjamin Herrenschmidt #define	FSI_RESP_ACK		0	/* Success */
105fea9cf32SBenjamin Herrenschmidt #define	FSI_RESP_BUSY		1	/* Slave busy */
106fea9cf32SBenjamin Herrenschmidt #define	FSI_RESP_ERRA		2	/* Any (misc) Error */
107fea9cf32SBenjamin Herrenschmidt #define	FSI_RESP_ERRC		3	/* Slave reports master CRC error */
108fea9cf32SBenjamin Herrenschmidt 
109fea9cf32SBenjamin Herrenschmidt /* Misc */
110fea9cf32SBenjamin Herrenschmidt #define	FSI_CRC_SIZE		4
111fea9cf32SBenjamin Herrenschmidt 
112fea9cf32SBenjamin Herrenschmidt /* fsi-master definition and flags */
1134af889b0SJeremy Kerr #define FSI_MASTER_FLAG_SWCLOCK		0x1
1144af889b0SJeremy Kerr 
1158bcd06d0SJoel Stanley /*
1168bcd06d0SJoel Stanley  * Structures and function prototypes
1178bcd06d0SJoel Stanley  *
1188bcd06d0SJoel Stanley  * These are common to all masters
1198bcd06d0SJoel Stanley  */
1208bcd06d0SJoel Stanley 
12109aecfabSJeremy Kerr struct fsi_master {
12209aecfabSJeremy Kerr 	struct device	dev;
12309aecfabSJeremy Kerr 	int		idx;
12409aecfabSJeremy Kerr 	int		n_links;
12509aecfabSJeremy Kerr 	int		flags;
1269840fcd8SBenjamin Herrenschmidt 	struct mutex	scan_lock;
12709aecfabSJeremy Kerr 	int		(*read)(struct fsi_master *, int link, uint8_t id,
12809aecfabSJeremy Kerr 				uint32_t addr, void *val, size_t size);
12909aecfabSJeremy Kerr 	int		(*write)(struct fsi_master *, int link, uint8_t id,
13009aecfabSJeremy Kerr 				uint32_t addr, const void *val, size_t size);
13109aecfabSJeremy Kerr 	int		(*term)(struct fsi_master *, int link, uint8_t id);
13209aecfabSJeremy Kerr 	int		(*send_break)(struct fsi_master *, int link);
13304635a30SEddie James 	int		(*link_enable)(struct fsi_master *, int link,
13404635a30SEddie James 				       bool enable);
135a2e7da86SBenjamin Herrenschmidt 	int		(*link_config)(struct fsi_master *, int link,
136a2e7da86SBenjamin Herrenschmidt 				       u8 t_send_delay, u8 t_echo_delay);
13709aecfabSJeremy Kerr };
13809aecfabSJeremy Kerr 
139*d5d8dfb0SEddie James #define to_fsi_master(d) container_of(d, struct fsi_master, dev)
14009aecfabSJeremy Kerr 
141e0c24bddSJeremy Kerr /**
142e0c24bddSJeremy Kerr  * fsi_master registration & lifetime: the fsi_master_register() and
143e0c24bddSJeremy Kerr  * fsi_master_unregister() functions will take ownership of the master, and
144e0c24bddSJeremy Kerr  * ->dev in particular. The registration path performs a get_device(), which
145e0c24bddSJeremy Kerr  * takes the first reference on the device. Similarly, the unregistration path
146e0c24bddSJeremy Kerr  * performs a put_device(), which may well drop the last reference.
147e0c24bddSJeremy Kerr  *
148e0c24bddSJeremy Kerr  * This means that master implementations *may* need to hold their own
149e0c24bddSJeremy Kerr  * reference (via get_device()) on master->dev. In particular, if the device's
150e0c24bddSJeremy Kerr  * ->release callback frees the fsi_master, then fsi_master_unregister will
151e0c24bddSJeremy Kerr  * invoke this free if no other reference is held.
152e0c24bddSJeremy Kerr  *
153e0c24bddSJeremy Kerr  * The same applies for the error path of fsi_master_register; if the call
154e0c24bddSJeremy Kerr  * fails, dev->release will have been invoked.
155e0c24bddSJeremy Kerr  */
15609aecfabSJeremy Kerr extern int fsi_master_register(struct fsi_master *master);
15709aecfabSJeremy Kerr extern void fsi_master_unregister(struct fsi_master *master);
15809aecfabSJeremy Kerr 
15915362d69SJeremy Kerr extern int fsi_master_rescan(struct fsi_master *master);
16015362d69SJeremy Kerr 
16109aecfabSJeremy Kerr #endif /* DRIVERS_FSI_MASTER_H */
162