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