1/*
2 *  Copyright IBM Corp. 2006
3 *  Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
4 */
5#ifndef __S390_ETR_H
6#define __S390_ETR_H
7
8/* ETR attachment control register */
9struct etr_eacr {
10	unsigned int e0		: 1;	/* port 0 stepping control */
11	unsigned int e1		: 1;	/* port 1 stepping control */
12	unsigned int _pad0	: 5;	/* must be 00100 */
13	unsigned int dp		: 1;	/* data port control */
14	unsigned int p0		: 1;	/* port 0 change recognition control */
15	unsigned int p1		: 1;	/* port 1 change recognition control */
16	unsigned int _pad1	: 3;	/* must be 000 */
17	unsigned int ea		: 1;	/* ETR alert control */
18	unsigned int es		: 1;	/* ETR sync check control */
19	unsigned int sl		: 1;	/* switch to local control */
20} __attribute__ ((packed));
21
22/* Port state returned by steai */
23enum etr_psc {
24	etr_psc_operational = 0,
25	etr_psc_semi_operational = 1,
26	etr_psc_protocol_error =  4,
27	etr_psc_no_symbols = 8,
28	etr_psc_no_signal = 12,
29	etr_psc_pps_mode = 13
30};
31
32/* Logical port state returned by stetr */
33enum etr_lpsc {
34	etr_lpsc_operational_step = 0,
35	etr_lpsc_operational_alt = 1,
36	etr_lpsc_semi_operational = 2,
37	etr_lpsc_protocol_error =  4,
38	etr_lpsc_no_symbol_sync = 8,
39	etr_lpsc_no_signal = 12,
40	etr_lpsc_pps_mode = 13
41};
42
43/* ETR status words */
44struct etr_esw {
45	struct etr_eacr eacr;		/* attachment control register */
46	unsigned int y		: 1;	/* stepping mode */
47	unsigned int _pad0	: 5;	/* must be 00000 */
48	unsigned int p		: 1;	/* stepping port number */
49	unsigned int q		: 1;	/* data port number */
50	unsigned int psc0	: 4;	/* port 0 state code */
51	unsigned int psc1	: 4;	/* port 1 state code */
52} __attribute__ ((packed));
53
54/* Second level data register status word */
55struct etr_slsw {
56	unsigned int vv1	: 1;	/* copy of validity bit data frame 1 */
57	unsigned int vv2	: 1;	/* copy of validity bit data frame 2 */
58	unsigned int vv3	: 1;	/* copy of validity bit data frame 3 */
59	unsigned int vv4	: 1;	/* copy of validity bit data frame 4 */
60	unsigned int _pad0	: 19;	/* must by all zeroes */
61	unsigned int n		: 1;	/* EAF port number */
62	unsigned int v1		: 1;	/* validity bit ETR data frame 1 */
63	unsigned int v2		: 1;	/* validity bit ETR data frame 2 */
64	unsigned int v3		: 1;	/* validity bit ETR data frame 3 */
65	unsigned int v4		: 1;	/* validity bit ETR data frame 4 */
66	unsigned int _pad1	: 4;	/* must be 0000 */
67} __attribute__ ((packed));
68
69/* ETR data frames */
70struct etr_edf1 {
71	unsigned int u		: 1;	/* untuned bit */
72	unsigned int _pad0	: 1;	/* must be 0 */
73	unsigned int r		: 1;	/* service request bit */
74	unsigned int _pad1	: 4;	/* must be 0000 */
75	unsigned int a		: 1;	/* time adjustment bit */
76	unsigned int net_id	: 8;	/* ETR network id */
77	unsigned int etr_id	: 8;	/* id of ETR which sends data frames */
78	unsigned int etr_pn	: 8;	/* port number of ETR output port */
79} __attribute__ ((packed));
80
81struct etr_edf2 {
82	unsigned int etv	: 32;	/* Upper 32 bits of TOD. */
83} __attribute__ ((packed));
84
85struct etr_edf3 {
86	unsigned int rc		: 8;	/* failure reason code */
87	unsigned int _pad0	: 3;	/* must be 000 */
88	unsigned int c		: 1;	/* ETR coupled bit */
89	unsigned int tc		: 4;	/* ETR type code */
90	unsigned int blto	: 8;	/* biased local time offset */
91					/* (blto - 128) * 15 = minutes */
92	unsigned int buo	: 8;	/* biased utc offset */
93					/* (buo - 128) = leap seconds */
94} __attribute__ ((packed));
95
96struct etr_edf4 {
97	unsigned int ed		: 8;	/* ETS device dependent data */
98	unsigned int _pad0	: 1;	/* must be 0 */
99	unsigned int buc	: 5;	/* biased ut1 correction */
100					/* (buc - 16) * 0.1 seconds */
101	unsigned int em		: 6;	/* ETS error magnitude */
102	unsigned int dc		: 6;	/* ETS drift code */
103	unsigned int sc		: 6;	/* ETS steering code */
104} __attribute__ ((packed));
105
106/*
107 * ETR attachment information block, two formats
108 * format 1 has 4 reserved words with a size of 64 bytes
109 * format 2 has 16 reserved words with a size of 96 bytes
110 */
111struct etr_aib {
112	struct etr_esw esw;
113	struct etr_slsw slsw;
114	unsigned long long tsp;
115	struct etr_edf1 edf1;
116	struct etr_edf2 edf2;
117	struct etr_edf3 edf3;
118	struct etr_edf4 edf4;
119	unsigned int reserved[16];
120} __attribute__ ((packed,aligned(8)));
121
122/* ETR interruption parameter */
123struct etr_irq_parm {
124	unsigned int _pad0	: 8;
125	unsigned int pc0	: 1;	/* port 0 state change */
126	unsigned int pc1	: 1;	/* port 1 state change */
127	unsigned int _pad1	: 3;
128	unsigned int eai	: 1;	/* ETR alert indication */
129	unsigned int _pad2	: 18;
130} __attribute__ ((packed));
131
132/* Query TOD offset result */
133struct etr_ptff_qto {
134	unsigned long long physical_clock;
135	unsigned long long tod_offset;
136	unsigned long long logical_tod_offset;
137	unsigned long long tod_epoch_difference;
138} __attribute__ ((packed));
139
140/* Inline assembly helper functions */
141static inline int etr_setr(struct etr_eacr *ctrl)
142{
143	int rc = -EOPNOTSUPP;
144
145	asm volatile(
146		"	.insn	s,0xb2160000,%1\n"
147		"0:	la	%0,0\n"
148		"1:\n"
149		EX_TABLE(0b,1b)
150		: "+d" (rc) : "Q" (*ctrl));
151	return rc;
152}
153
154/* Stores a format 1 aib with 64 bytes */
155static inline int etr_stetr(struct etr_aib *aib)
156{
157	int rc = -EOPNOTSUPP;
158
159	asm volatile(
160		"	.insn	s,0xb2170000,%1\n"
161		"0:	la	%0,0\n"
162		"1:\n"
163		EX_TABLE(0b,1b)
164		: "+d" (rc) : "Q" (*aib));
165	return rc;
166}
167
168/* Stores a format 2 aib with 96 bytes for specified port */
169static inline int etr_steai(struct etr_aib *aib, unsigned int func)
170{
171	register unsigned int reg0 asm("0") = func;
172	int rc = -EOPNOTSUPP;
173
174	asm volatile(
175		"	.insn	s,0xb2b30000,%1\n"
176		"0:	la	%0,0\n"
177		"1:\n"
178		EX_TABLE(0b,1b)
179		: "+d" (rc) : "Q" (*aib), "d" (reg0));
180	return rc;
181}
182
183/* Function codes for the steai instruction. */
184#define ETR_STEAI_STEPPING_PORT		0x10
185#define ETR_STEAI_ALTERNATE_PORT	0x11
186#define ETR_STEAI_PORT_0		0x12
187#define ETR_STEAI_PORT_1		0x13
188
189static inline int etr_ptff(void *ptff_block, unsigned int func)
190{
191	register unsigned int reg0 asm("0") = func;
192	register unsigned long reg1 asm("1") = (unsigned long) ptff_block;
193	int rc = -EOPNOTSUPP;
194
195	asm volatile(
196		"	.word	0x0104\n"
197		"	ipm	%0\n"
198		"	srl	%0,28\n"
199		: "=d" (rc), "=m" (ptff_block)
200		: "d" (reg0), "d" (reg1), "m" (ptff_block) : "cc");
201	return rc;
202}
203
204/* Function codes for the ptff instruction. */
205#define ETR_PTFF_QAF	0x00	/* query available functions */
206#define ETR_PTFF_QTO	0x01	/* query tod offset */
207#define ETR_PTFF_QSI	0x02	/* query steering information */
208#define ETR_PTFF_ATO	0x40	/* adjust tod offset */
209#define ETR_PTFF_STO	0x41	/* set tod offset */
210#define ETR_PTFF_SFS	0x42	/* set fine steering rate */
211#define ETR_PTFF_SGS	0x43	/* set gross steering rate */
212
213/* Functions needed by the machine check handler */
214void etr_switch_to_local(void);
215void etr_sync_check(void);
216
217/* STP interruption parameter */
218struct stp_irq_parm {
219	unsigned int _pad0	: 14;
220	unsigned int tsc	: 1;	/* Timing status change */
221	unsigned int lac	: 1;	/* Link availability change */
222	unsigned int tcpc	: 1;	/* Time control parameter change */
223	unsigned int _pad2	: 15;
224} __attribute__ ((packed));
225
226#define STP_OP_SYNC	1
227#define STP_OP_CTRL	3
228
229struct stp_sstpi {
230	unsigned int rsvd0;
231	unsigned int rsvd1 : 8;
232	unsigned int stratum : 8;
233	unsigned int vbits : 16;
234	unsigned int leaps : 16;
235	unsigned int tmd : 4;
236	unsigned int ctn : 4;
237	unsigned int rsvd2 : 3;
238	unsigned int c : 1;
239	unsigned int tst : 4;
240	unsigned int tzo : 16;
241	unsigned int dsto : 16;
242	unsigned int ctrl : 16;
243	unsigned int rsvd3 : 16;
244	unsigned int tto;
245	unsigned int rsvd4;
246	unsigned int ctnid[3];
247	unsigned int rsvd5;
248	unsigned int todoff[4];
249	unsigned int rsvd6[48];
250} __attribute__ ((packed));
251
252/* Functions needed by the machine check handler */
253void stp_sync_check(void);
254void stp_island_check(void);
255
256#endif /* __S390_ETR_H */
257