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