1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_SYS_ZSDEV_H
28#define	_SYS_ZSDEV_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32/*
33 * Onboard serial ports.
34 * Device dependent software definitions.
35 * All interfaces described in this file are private to the Sun 'zs' driver
36 * implementation and may change at any time without notice.
37 */
38
39
40/*
41 * Chip, buffer, and register definitions for Z8530 SCC
42 */
43
44#include <sys/spl.h>
45#include <sys/ksynch.h>
46#include <sys/dditypes.h>
47#include <sys/ser_zscc.h>
48
49#ifdef _MACHDEP
50#include <sys/zsmach.h>
51#endif
52
53#ifdef	__cplusplus
54extern "C" {
55#endif
56
57#ifndef _MACHDEP
58#define	ZSDELAY()
59#define	ZSFLUSH()
60#define	ZSNEXTPOLL(zscurr)
61#endif
62
63/*
64 * OUTLINE defines the high-order flag bit in the minor device number that
65 * controls use of a tty line for dialin and dialout simultaneously.
66 */
67#define	OUTLINE		((minor_t)1 << (NBITSMINOR32 - 1))
68#define	UNIT(x)		(getminor(x) & ~OUTLINE)
69
70#define	ZSWR1_INIT	(ZSWR1_SIE|ZSWR1_TIE|ZSWR1_RIE)
71
72extern int zs_usec_delay;
73
74
75#define	ZS_REG_SIZE	(2 * sizeof (struct zscc_device))
76
77#define	PCLK		(19660800/4)	/* basic clock rate for UARTs */
78
79#define	SDLCFLAG	0x7E
80
81#define	ZS_ON		(ZSWR5_DTR|ZSWR5_RTS)
82#define	ZS_OFF		0
83
84/*
85 * Modem control commands.
86 */
87#define	DMSET   0
88#define	DMBIS   1
89#define	DMBIC   2
90#define	DMGET   3
91
92/*
93 * Macros to access a port
94 */
95#define	SCC_WRITEA(reg, val) { \
96	((struct zscc_device *) \
97	((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = reg; \
98	ZSDELAY(); \
99	((struct zscc_device *) \
100	((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = val; \
101	ZSDELAY(); \
102	zs->zs_wreg[reg] = val; \
103}
104#define	SCC_WRITEB(reg, val) { \
105	((struct zscc_device *) \
106	((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = reg; \
107	ZSDELAY(); \
108	((struct zscc_device *) \
109	((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = val; \
110	ZSDELAY(); \
111	zs->zs_wreg[reg] = val; \
112}
113#define	SCC_WRITE(reg, val)  { \
114	zs->zs_addr->zscc_control = reg; \
115	ZSDELAY(); \
116	zs->zs_addr->zscc_control = val; \
117	ZSDELAY(); \
118	zs->zs_wreg[reg] = val; \
119}
120
121#define	SCC_READA(reg, var) { \
122	((struct zscc_device *) \
123	((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = reg; \
124	ZSDELAY(); \
125	var = ((struct zscc_device *) \
126	((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control; \
127	ZSDELAY(); \
128}
129#define	SCC_READB(reg, var) { \
130	((struct zscc_device *) \
131	((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = reg; \
132	ZSDELAY(); \
133	var = ((struct zscc_device *) \
134	((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control; \
135	ZSDELAY(); \
136}
137#define	SCC_READ(reg, var) { \
138	register struct zscc_device *tmp; \
139	tmp = zs->zs_addr; \
140	tmp->zscc_control = reg; \
141	ZSDELAY(); \
142	var = tmp->zscc_control; \
143	ZSDELAY(); \
144}
145
146#define	SCC_BIS(reg, val) { \
147	zs->zs_addr->zscc_control = reg; \
148	ZSDELAY(); \
149	zs->zs_addr->zscc_control =  zs->zs_wreg[reg] |= val; \
150	ZSDELAY(); \
151}
152
153#define	SCC_BIC(reg, val) { \
154	zs->zs_addr->zscc_control = reg; \
155	ZSDELAY(); \
156	zs->zs_addr->zscc_control =  zs->zs_wreg[reg] &= ~val; \
157	ZSDELAY(); \
158}
159
160
161#define	SCC_WRITE0(val) { \
162	zs->zs_addr->zscc_control = val; \
163	ZSDELAY(); \
164	ZSFLUSH(); \
165}
166
167#define	SCC_WRITEDATA(val) { \
168	zs->zs_addr->zscc_data = val; \
169	ZSDELAY(); \
170	ZSFLUSH(); \
171}
172#define	SCC_READ0()	zs->zs_addr->zscc_control
173#define	SCC_READDATA()	zs->zs_addr->zscc_data
174
175
176/*
177 * Protocol specific entry points for driver routines.
178 */
179struct zsops {
180	void	(*zsop_txint)();	/* xmit buffer empty */
181	void	(*zsop_xsint)();	/* external/status */
182	void	(*zsop_rxint)();	/* receive char available */
183	void	(*zsop_srint)();	/* special receive condition */
184	int	(*zsop_softint)();	/* second stage interrupt handler */
185	int	(*zsop_suspend)();	/* suspend driver */
186	int	(*zsop_resume)();	/* resume driver */
187};
188
189/*
190 * Hardware channel common data.  One structure per port.
191 * Each of the fields in this structure is required to be protected by a
192 * mutex lock at the highest priority at which it can be altered.
193 * The zs_flags, zs_wreg and zs_next fields can be altered by interrupt
194 * handling code that runs at ZS_PL_HI (IPL 12), so they must be protected
195 * by the mutex whose handle is stored in zs_excl_hi.  All others can be
196 * protected by the zs_excl mutex, which is lower priority and adaptive.
197 */
198#define	ZS_MAX_PRIV_STR 800 /* int */
199struct zscom {
200	void		(*zs_txint)();	/* SCC interrupt vector routines */
201	unsigned char	*zs_wr_cur;
202	unsigned char 	*zs_wr_lim;
203	void		(*zs_rxint)();	/* SCC interrupt vector routines */
204	unsigned char 	*zs_rd_cur;
205	unsigned char 	*zs_rd_lim;
206	struct zscc_device *zs_addr;	/* address of second half of chip */
207	void		(*zs_xsint)();	/* SCC interrupt vector routines */
208	void		(*zs_srint)();	/* SCC interrupt vector routines */
209	int		(*zs_suspend)(); /* routine to suspend driver */
210	int		(*zs_resume)();	/* routine to resume driver */
211	uchar_t		zs_wreg[16];	/* shadow of write registers */
212	caddr_t		zs_priv;	/* protocol private data */
213	struct zsops	*zs_ops;	/* basic operations vectors */
214	dev_info_t	*zs_dip;	/* dev_info */
215	dev_info_t	*zs_hdlc_dip;	/* zsh dev_info */
216	time_t		zs_dtrlow;	/* time dtr went low */
217	short		zs_unit;	/* which channel (0:NZSLINE) */
218	/*
219	 * The zs_wreg, zs_next and zs_flags fields
220	 * are protected by zs_excl_hi.
221	 */
222	uchar_t		zs_suspended;	/* True, if suspended */
223	struct zs_prog	*zs_prog_save;	/* H/W state, saved for CPR */
224	struct zscom	*zs_next; /* next in the circularly linked list */
225	struct zscom	*zs_back; /* back in the circularly linked list */
226
227	kmutex_t	*zs_excl_hi;	/* zs spinlock mutex */
228	kmutex_t	*zs_excl;	/* zs adaptive mutex */
229	kmutex_t	*zs_ocexcl;	/* zs adaptive mutex for open/close */
230	kcondvar_t	zs_flags_cv;	/* condition variable for flags */
231	ulong_t		zs_priv_str[ZS_MAX_PRIV_STR];
232	uint_t		zs_flags;	/* ZS_* flags below */
233	kstat_t		*intrstats;	/* interrupt statistics */
234	timeout_id_t	zs_timer;	/* close timer */
235};
236
237/*
238 * Definition for zs_flags field
239 *
240 * ZS_CLOSED is for synchronizing with za_soft_active an za_kick_active.
241 */
242#define	ZS_NEEDSOFT	0x00000001
243#define	ZS_PROGRESS	0x00000002
244#define	ZS_CLOSING	0x00000004	/* close has started */
245#define	ZS_CLOSED	0x00000008	/* close is done; stop other activity */
246
247#ifdef	_KERNEL
248#define	ZS_H_LOG_MAX	0x8000
249/*
250 * ZSSETSOFT macro to pend a level 3 interrupt if one isn't already pending.
251 */
252
253extern kmutex_t	zs_soft_lock;		/* ptr to lock for zssoftpend */
254extern int zssoftpend;			/* secondary interrupt pending */
255
256extern ddi_softintr_t zs_softintr_id;
257#define	ZSSETSOFT(zs)	{		\
258	zs->zs_flags |= ZS_NEEDSOFT;	\
259	if (!zssoftpend)  { 		\
260		zssoftpend = 1;		\
261	ddi_trigger_softintr(zs_softintr_id); \
262	}				\
263}
264
265#endif	/* _KERNEL */
266
267/*
268 * Lock priority definitions.
269 * XXX: These should be obtained from configuration data, eventually.
270 */
271#define	ZS_PL   ipltospl(SPL3)		/* translates to SPARC IPL 6  */
272#define	ZS_PL_HI ipltospl(SPLTTY)	/* translates to SPARC IPL 12 */
273
274/*
275 * Definitions for generic SCC programming routine
276 */
277struct zs_prog {
278	struct zscom	*zs;	/* common data for this channel */
279	uchar_t		flags;	/* see definitions below */
280	uchar_t		wr4;	/* misc parameters and modes */
281	uchar_t		wr11;	/* clock mode control */
282	uchar_t		wr12;	/* BRG time constant Lo byte */
283	uchar_t		wr13;	/* BRG time constant Hi byte */
284	uchar_t		wr3;	/* receiver parameters and control */
285	uchar_t		wr5;	/* transmitter parameters and control */
286	uchar_t		wr15;	/* external status interrupt control */
287};
288
289/*
290 * Definitions for zs_prog flags field
291 */
292#define	ZSP_SYNC		01	/* 0 = async line; 1 = synchronous */
293#define	ZSP_NRZI		02	/* 0 = NRZ encoding; 1 = NRZI */
294#define	ZSP_PLL			04	/* request use of PLL clock source */
295#define	ZSP_LOOP		010	/* request interal loopback mode */
296#define	ZSP_PARITY_SPECIAL	020	/* parity error causes ext status int */
297#define	ZSP_ECHO		040	/* request auto echo mode */
298
299extern void	zsa_init(struct zscom *zs);
300extern int	zsmctl(struct zscom *zs, int bits, int how);
301extern void	zs_program(struct zs_prog *zspp);
302extern void	zsopinit(struct zscom *zs, struct zsops *zso);
303extern void	setzssoft(void);
304extern dev_info_t *zs_get_dev_info(dev_t dev, int otyp);
305
306extern	char *zssoftCAR;
307extern	int nzs;
308extern	struct zscom *zscom;
309extern	struct zs_prog *zs_prog;
310extern	kmutex_t zs_curr_lock;	/* lock protecting zscurr use for clone */
311extern	struct zsops zsops_null;
312extern	int zs_drain_check;
313
314#ifdef	__cplusplus
315}
316#endif
317
318#endif	/* !_SYS_ZSDEV_H */
319