xref: /netbsd-src/sys/arch/arm/s3c2xx0/sscom_s3c2440.c (revision 2b85113592462c11cf7bbda9af94c1bdf545f2e7)
1 /*-
2  * Copyright (c) 2012 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Paul Fleischer <paul@xpg.dk>
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  *
17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /* Derived from sscom_s3c2410.c */
31 
32 /*
33  * Copyright (c) 2002, 2003 Fujitsu Component Limited
34  * Copyright (c) 2002, 2003 Genetec Corporation
35  * All rights reserved.
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  * 3. Neither the name of The Fujitsu Component Limited nor the name of
46  *    Genetec corporation may not be used to endorse or promote products
47  *    derived from this software without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
50  * CORPORATION ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
51  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
52  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL FUJITSU COMPONENT LIMITED OR GENETEC
54  * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
57  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
59  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
60  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61  * SUCH DAMAGE.
62  */
63 
64 #include <sys/cdefs.h>
65 __KERNEL_RCSID(0, "$NetBSD: sscom_s3c2440.c,v 1.4 2014/03/14 21:40:48 matt Exp $");
66 
67 #include "opt_sscom.h"
68 #include "opt_ddb.h"
69 #include "opt_kgdb.h"
70 
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/device.h>
74 
75 #include <sys/bus.h>
76 #include <machine/intr.h>
77 
78 #include <arm/s3c2xx0/s3c2440reg.h>
79 #include <arm/s3c2xx0/s3c2440var.h>
80 #include <arm/s3c2xx0/sscom_var.h>
81 
82 #include "locators.h"
83 
84 static int sscom_match(device_t, cfdata_t, void *);
85 static void sscom_attach(device_t, device_t, void *);
86 
87 CFATTACH_DECL_NEW(sscom, sizeof(struct sscom_softc), sscom_match,
88     sscom_attach, NULL, NULL);
89 
90 const static struct sscom_uart_info s3c2440_uart_config[] = {
91 	/* UART 0 */
92 	{
93 		0,
94 		S3C2440_INT_TXD0,
95 		S3C2440_INT_RXD0,
96 		S3C2440_INT_ERR0,
97 		S3C2440_UART_BASE(0),
98 	},
99 	/* UART 1 */
100 	{
101 		1,
102 		S3C2440_INT_TXD1,
103 		S3C2440_INT_RXD1,
104 		S3C2440_INT_ERR1,
105 		S3C2440_UART_BASE(1),
106 	},
107 	/* UART 2 */
108 	{
109 		2,
110 		S3C2440_INT_TXD2,
111 		S3C2440_INT_RXD2,
112 		S3C2440_INT_ERR2,
113 		S3C2440_UART_BASE(2),
114 	},
115 };
116 static int found;
117 
118 static int
sscom_match(device_t parent,struct cfdata * cf,void * aux)119 sscom_match(device_t parent, struct cfdata *cf, void *aux)
120 {
121 	struct s3c2xx0_attach_args *sa = aux;
122 	int unit = sa->sa_index;
123 
124 	if (unit == SSIOCF_INDEX_DEFAULT && found == 0)
125 		return 1;
126 	return (unit == 0 || unit == 1 || unit == 2);
127 }
128 
129 #define	_sscom_intbit(irqno)	(1<<((irqno)-S3C2440_SUBIRQ_MIN))
130 
131 static void
s3c2440_change_txrx_interrupts(struct sscom_softc * sc,bool unmask_p,u_int flags)132 s3c2440_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p,
133     u_int flags)
134 {
135 	int intrbits = 0;
136 	if (flags & SSCOM_HW_RXINT)
137 		intrbits |= _sscom_intbit((sc)->sc_rx_irqno);
138 	if (flags & SSCOM_HW_TXINT)
139 		intrbits |= _sscom_intbit((sc)->sc_tx_irqno);
140 	if (unmask_p) {
141 		s3c2440_unmask_subinterrupts(intrbits);
142 	} else {
143 		s3c2440_mask_subinterrupts(intrbits);
144 	}
145 }
146 
147 static void
sscom_attach(device_t parent,device_t self,void * aux)148 sscom_attach(device_t parent, device_t self, void *aux)
149 {
150 	struct sscom_softc *sc = device_private(self);
151 	struct s3c2xx0_attach_args *sa = aux;
152 	int unit;
153 	bus_addr_t iobase;
154 
155 	found = 1;
156 	unit = (sa->sa_index == SSIOCF_INDEX_DEFAULT) ? 0 : sa->sa_index;
157 	iobase = s3c2440_uart_config[unit].iobase;
158 
159 	sc->sc_dev = self;
160 	sc->sc_iot = s3c2xx0_softc->sc_iot;
161 	sc->sc_unit = unit;
162 	sc->sc_frequency = s3c2xx0_softc->sc_pclk;
163 
164 	sc->sc_change_txrx_interrupts = s3c2440_change_txrx_interrupts;
165 
166 	sc->sc_rx_irqno = s3c2440_uart_config[unit].rx_int;
167 	sc->sc_tx_irqno = s3c2440_uart_config[unit].tx_int;
168 
169 	if (bus_space_map(sc->sc_iot, iobase, SSCOM_SIZE, 0, &sc->sc_ioh)) {
170 		printf( ": failed to map registers\n" );
171 		return;
172 	}
173 
174 	printf("\n");
175 
176 	s3c24x0_intr_establish(s3c2440_uart_config[unit].tx_int,
177 	    IPL_SERIAL, IST_LEVEL, sscomtxintr, sc);
178 	s3c24x0_intr_establish(s3c2440_uart_config[unit].rx_int,
179 	    IPL_SERIAL, IST_LEVEL, sscomrxintr, sc);
180 	s3c24x0_intr_establish(s3c2440_uart_config[unit].err_int,
181 	    IPL_SERIAL, IST_LEVEL, sscomrxintr, sc);
182 	sscom_disable_txrxint(sc);
183 
184 	sscom_attach_subr(sc);
185 }
186 
187 int
s3c2440_sscom_cnattach(bus_space_tag_t iot,int unit,int rate,int frequency,tcflag_t cflag)188 s3c2440_sscom_cnattach(bus_space_tag_t iot, int unit, int rate,
189     int frequency, tcflag_t cflag)
190 {
191 #if defined(SSCOM0CONSOLE) || defined(SSCOM1CONSOLE)
192 	return sscom_cnattach(iot, s3c2440_uart_config + unit,
193 	    rate, frequency, cflag);
194 #else
195 	return 0;
196 #endif
197 }
198 
199 #ifdef KGDB
200 int
s3c2440_sscom_kgdb_attach(bus_space_tag_t iot,int unit,int rate,int frequency,tcflag_t cflag)201 s3c2440_sscom_kgdb_attach(bus_space_tag_t iot, int unit, int rate,
202     int frequency, tcflag_t cflag)
203 {
204 	return sscom_kgdb_attach(iot, s3c2440_uart_config + unit,
205 	    rate, frequency, cflag);
206 }
207 #endif /* KGDB */
208