xref: /openbsd/sys/arch/landisk/stand/boot/scifcons.c (revision e5dd7070)
1 /*	$OpenBSD: scifcons.c,v 1.6 2014/07/17 13:14:06 miod Exp $	*/
2 /*	$NetBSD: scifcons.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */
3 /*	NetBSD: scif.c,v 1.38 2004/12/13 02:14:13 chs Exp */
4 
5 /*-
6  * Copyright (C) 1999 T.Horiuchi and SAITOH Masanobu.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 /*-
31  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
32  * All rights reserved.
33  *
34  * This code is derived from software contributed to The NetBSD Foundation
35  * by Charles M. Hannum.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  *
46  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
47  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
48  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
50  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
51  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
54  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56  * POSSIBILITY OF SUCH DAMAGE.
57  */
58 /*
59  * Copyright (c) 1991 The Regents of the University of California.
60  * All rights reserved.
61  *
62  * Redistribution and use in source and binary forms, with or without
63  * modification, are permitted provided that the following conditions
64  * are met:
65  * 1. Redistributions of source code must retain the above copyright
66  *    notice, this list of conditions and the following disclaimer.
67  * 2. Redistributions in binary form must reproduce the above copyright
68  *    notice, this list of conditions and the following disclaimer in the
69  *    documentation and/or other materials provided with the distribution.
70  * 3. Neither the name of the University nor the names of its contributors
71  *    may be used to endorse or promote products derived from this software
72  *    without specific prior written permission.
73  *
74  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
75  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
76  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
77  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
78  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
79  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
80  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
81  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
82  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
83  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
84  * SUCH DAMAGE.
85  *
86  *	@(#)com.c	7.5 (Berkeley) 5/16/91
87  */
88 /*
89  * SH internal serial driver
90  *
91  * This code is derived from both z8530tty.c and com.c
92  */
93 
94 #include <libsa.h>
95 #include <dev/cons.h>
96 
97 #include <arch/sh/dev/scifreg.h>
98 
99 #define scif_smr_read()		SHREG_SCSMR2
100 #define scif_smr_write(v)	(SHREG_SCSMR2 = (v))
101 
102 #define scif_brr_read()		SHREG_SCBRR2
103 #define scif_brr_write(v)	(SHREG_SCBRR2 = (v))
104 
105 #define scif_scr_read()		SHREG_SCSCR2
106 #define scif_scr_write(v)	(SHREG_SCSCR2 = (v))
107 
108 #define scif_ftdr_write(v)	(SHREG_SCFTDR2 = (v))
109 
110 #define scif_ssr_read()		SHREG_SCSSR2
111 #define scif_ssr_write(v)	(SHREG_SCSSR2 = (v))
112 
113 #define scif_frdr_read()	SHREG_SCFRDR2
114 
115 #define scif_fcr_read()		SHREG_SCFCR2
116 #define scif_fcr_write(v)	(SHREG_SCFCR2 = (v))
117 
118 #define scif_fdr_read()		SHREG_SCFDR2
119 
120 #define scif_sptr_read()	SHREG_SCSPTR2
121 #define scif_sptr_write(v)	(SHREG_SCSPTR2 = (v))
122 
123 #define scif_lsr_read()		SHREG_SCLSR2
124 #define scif_lsr_write(v)	(SHREG_SCLSR2 = (v))
125 
126 #define	divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */
127 
128 #define	SERBUFSIZE	16
129 static u_char serbuf[SERBUFSIZE];
130 static int serbuf_read = 0;
131 static int serbuf_write = 0;
132 
133 void
134 scif_init(unsigned int bps)
135 {
136 
137 	serbuf_read = 0;
138 	serbuf_write = 0;
139 
140 	/* Initialize SCR */
141 	scif_scr_write(0x00);
142 
143 	/* Clear FIFO */
144 	scif_fcr_write(SCFCR2_TFRST | SCFCR2_RFRST);
145 
146 	/* Serial Mode Register */
147 	scif_smr_write(0x00);	/* 8bit,NonParity,Even,1Stop */
148 
149 	/* Bit Rate Register */
150 	scif_brr_write(divrnd(PCLOCK, 32 * bps) - 1);
151 
152 	delay(100);
153 
154 	scif_sptr_write(SCSPTR2_RTSIO);
155 
156 	scif_fcr_write(FIFO_RCV_TRIGGER_1 | FIFO_XMT_TRIGGER_8);
157 
158 	/* Send permission, Receive permission ON */
159 	scif_scr_write(SCSCR2_TE | SCSCR2_RE);
160 
161 	/* Serial Status Register */
162 	scif_ssr_write(scif_ssr_read() & SCSSR2_TDFE); /* Clear Status */
163 }
164 
165 void
166 scif_cnprobe(struct consdev *cn)
167 {
168 	cn->cn_pri = CN_HIGHPRI;
169 }
170 
171 void
172 scif_cninit(struct consdev *cn)
173 {
174 	scif_init(9600);
175 }
176 
177 int
178 scif_cngetc(dev_t dev)
179 {
180 	unsigned char c, err_c;
181 	unsigned short err_c2;
182 
183 	if (serbuf_read != serbuf_write) {
184 		if (dev & 0x80)
185 			return 1;
186 		c = serbuf[serbuf_read];
187 		serbuf_read = (serbuf_read + 1) % SERBUFSIZE;
188 		return (c);
189 	}
190 
191 	for (;;) {
192 		/* wait for ready */
193 		if ((scif_fdr_read() & SCFDR2_RECVCNT) != 0) {
194 			c = scif_frdr_read();
195 			err_c = scif_ssr_read();
196 			scif_ssr_write(scif_ssr_read() &
197 			    ~(SCSSR2_ER | SCSSR2_BRK | SCSSR2_RDF | SCSSR2_DR));
198 
199 			err_c2 = scif_lsr_read();
200 			scif_lsr_write(scif_lsr_read() & ~SCLSR2_ORER);
201 
202 			if ((err_c & (SCSSR2_ER | SCSSR2_BRK | SCSSR2_FER |
203 			    SCSSR2_PER)) == 0) {
204 				if ((err_c2 & SCLSR2_ORER) == 0) {
205 					if ((dev & 0x80) == 0)
206 						return (c);
207 					/* stuff char into preread buffer */
208 					serbuf[serbuf_write] = (u_char)c;
209 					serbuf_write = (serbuf_write + 1) %
210 					    SERBUFSIZE;
211 					return (1);
212 				}
213 			}
214 		}
215 		if (dev & 0x80)
216 			return 0;
217 	}
218 }
219 
220 void
221 scif_cnputc(dev_t dev, int c)
222 {
223 
224 	/* wait for ready */
225 	while ((scif_fdr_read() & SCFDR2_TXCNT) == SCFDR2_TXF_FULL)
226 		continue;
227 
228 	/* write send data to send register */
229 	scif_ftdr_write(c);
230 
231 	/* clear ready flag */
232 	scif_ssr_write(scif_ssr_read() & ~(SCSSR2_TDFE | SCSSR2_TEND));
233 }
234