Home | History | Annotate | Line # | Download | only in hd64461
hd64461uart.c revision 1.18.16.1
      1  1.18.16.1  gdamore /*	$NetBSD: hd64461uart.c,v 1.18.16.1 2006/06/16 05:02:32 gdamore Exp $	*/
      2        1.1      uch 
      3        1.1      uch /*-
      4        1.5      uch  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
      5        1.1      uch  * All rights reserved.
      6        1.1      uch  *
      7        1.1      uch  * Redistribution and use in source and binary forms, with or without
      8        1.1      uch  * modification, are permitted provided that the following conditions
      9        1.1      uch  * are met:
     10        1.1      uch  * 1. Redistributions of source code must retain the above copyright
     11        1.1      uch  *    notice, this list of conditions and the following disclaimer.
     12        1.1      uch  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1      uch  *    notice, this list of conditions and the following disclaimer in the
     14        1.1      uch  *    documentation and/or other materials provided with the distribution.
     15        1.1      uch  * 3. All advertising materials mentioning features or use of this software
     16        1.1      uch  *    must display the following acknowledgement:
     17        1.1      uch  *        This product includes software developed by the NetBSD
     18        1.1      uch  *        Foundation, Inc. and its contributors.
     19        1.1      uch  * 4. Neither the name of The NetBSD Foundation nor the names of its
     20        1.1      uch  *    contributors may be used to endorse or promote products derived
     21        1.1      uch  *    from this software without specific prior written permission.
     22        1.1      uch  *
     23        1.1      uch  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     24        1.1      uch  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     25        1.1      uch  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     26        1.1      uch  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     27        1.1      uch  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     28        1.1      uch  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     29        1.1      uch  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30        1.1      uch  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     31        1.1      uch  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     32        1.1      uch  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     33        1.1      uch  * POSSIBILITY OF SUCH DAMAGE.
     34        1.1      uch  */
     35       1.16    lukem 
     36       1.16    lukem #include <sys/cdefs.h>
     37  1.18.16.1  gdamore __KERNEL_RCSID(0, "$NetBSD: hd64461uart.c,v 1.18.16.1 2006/06/16 05:02:32 gdamore Exp $");
     38        1.1      uch 
     39        1.7      uch #include "opt_kgdb.h"
     40        1.7      uch 
     41        1.1      uch #include <sys/param.h>
     42        1.1      uch #include <sys/systm.h>
     43        1.1      uch #include <sys/reboot.h>
     44        1.1      uch #include <sys/malloc.h>
     45        1.1      uch #include <sys/device.h>
     46        1.8      uch #include <sys/kgdb.h>
     47        1.1      uch 
     48        1.1      uch #include <sys/termios.h>
     49        1.1      uch #include <dev/cons.h>
     50        1.1      uch #include <sys/conf.h>
     51        1.1      uch 
     52        1.1      uch #include <machine/bus.h>
     53        1.1      uch #include <machine/intr.h>
     54        1.7      uch #include <machine/console.h>
     55        1.1      uch 
     56        1.1      uch #include <dev/ic/comvar.h>
     57        1.1      uch #include <dev/ic/comreg.h>
     58        1.1      uch 
     59        1.6      uch #include <machine/debug.h>
     60        1.1      uch 
     61        1.1      uch #include <hpcsh/dev/hd64461/hd64461var.h>
     62        1.1      uch #include <hpcsh/dev/hd64461/hd64461reg.h>
     63       1.10      uch #include <hpcsh/dev/hd64461/hd64461intcreg.h>
     64        1.7      uch #include <hpcsh/dev/hd64461/hd64461uartvar.h>
     65        1.7      uch #include <hpcsh/dev/hd64461/hd64461uartreg.h>
     66        1.1      uch 
     67        1.5      uch STATIC struct hd64461uart_chip {
     68        1.1      uch 	struct hpcsh_bus_space __tag_body;
     69        1.1      uch 	bus_space_tag_t io_tag;
     70        1.1      uch 	int console;
     71        1.1      uch } hd64461uart_chip;
     72        1.1      uch 
     73        1.1      uch struct hd64461uart_softc {
     74        1.1      uch 	struct com_softc sc_com;
     75        1.1      uch 
     76        1.1      uch 	struct hd64461uart_chip *sc_chip;
     77        1.1      uch 	enum hd64461_module_id sc_module_id;
     78        1.1      uch };
     79        1.1      uch 
     80        1.1      uch /* boot console */
     81        1.8      uch void hd64461uartcnprobe(struct consdev *);
     82        1.8      uch void hd64461uartcninit(struct consdev *);
     83        1.1      uch 
     84        1.5      uch STATIC int hd64461uart_match(struct device *, struct cfdata *, void *);
     85        1.5      uch STATIC void hd64461uart_attach(struct device *, struct device *, void *);
     86        1.1      uch 
     87       1.13  thorpej CFATTACH_DECL(hd64461uart, sizeof(struct hd64461uart_softc),
     88       1.14  thorpej     hd64461uart_match, hd64461uart_attach, NULL, NULL);
     89        1.1      uch 
     90        1.5      uch STATIC void hd64461uart_init(void);
     91       1.18      uwe STATIC uint8_t hd64461uart_read_1(void *, bus_space_handle_t, bus_size_t);
     92        1.5      uch STATIC void hd64461uart_write_1(void *, bus_space_handle_t, bus_size_t,
     93       1.18      uwe     uint8_t);
     94        1.1      uch 
     95        1.1      uch #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
     96        1.1      uch #ifndef COMCN_SPEED
     97        1.1      uch #define COMCN_SPEED	19200
     98        1.1      uch #endif
     99        1.1      uch 
    100        1.1      uch void
    101        1.8      uch hd64461uartcnprobe(struct consdev *cp)
    102        1.1      uch {
    103       1.11  gehenna 	extern const struct cdevsw com_cdevsw;
    104        1.1      uch 	int maj;
    105        1.1      uch 
    106        1.1      uch 	/* locate the major number */
    107       1.11  gehenna 	maj = cdevsw_lookup_major(&com_cdevsw);
    108        1.1      uch 
    109        1.1      uch 	/* Initialize required fields. */
    110        1.1      uch 	cp->cn_dev = makedev(maj, 0);
    111        1.1      uch 	cp->cn_pri = CN_NORMAL;
    112        1.1      uch }
    113        1.1      uch 
    114        1.1      uch void
    115        1.8      uch hd64461uartcninit(struct consdev *cp)
    116        1.1      uch {
    117        1.3      uch 
    118        1.2      uch 	hd64461uart_init();
    119        1.2      uch 
    120        1.7      uch 	comcnattach(hd64461uart_chip.io_tag, 0x0, COMCN_SPEED, COM_FREQ,
    121       1.18      uwe 	    COM_TYPE_NORMAL, CONMODE);
    122        1.2      uch 
    123        1.1      uch 	hd64461uart_chip.console = 1;
    124        1.1      uch }
    125        1.8      uch 
    126        1.8      uch #ifdef KGDB
    127        1.8      uch int
    128       1.18      uwe hd64461uart_kgdb_init(void)
    129        1.8      uch {
    130        1.8      uch 
    131        1.8      uch 	if (strcmp(kgdb_devname, "hd64461uart") != 0)
    132        1.8      uch 		return (1);
    133        1.8      uch 
    134        1.9      uch 	if (hd64461uart_chip.console)
    135        1.9      uch 		return (1);	/* can't share with console */
    136        1.9      uch 
    137        1.8      uch 	hd64461uart_init();
    138        1.8      uch 
    139        1.8      uch 	if (com_kgdb_attach(hd64461uart_chip.io_tag, 0x0, kgdb_rate,
    140       1.15  thorpej 	    COM_FREQ, COM_TYPE_NORMAL, CONMODE) != 0) {
    141        1.8      uch 		printf("%s: KGDB console open failed.\n", __FUNCTION__);
    142        1.8      uch 		return (1);
    143        1.8      uch 	}
    144        1.8      uch 
    145        1.8      uch 	return (0);
    146        1.8      uch }
    147        1.8      uch #endif /* KGDB */
    148        1.1      uch 
    149       1.18      uwe STATIC int
    150        1.1      uch hd64461uart_match(struct device *parent, struct cfdata *cf, void *aux)
    151        1.1      uch {
    152        1.1      uch 	struct hd64461_attach_args *ha = aux;
    153        1.1      uch 
    154        1.1      uch 	return (ha->ha_module_id == HD64461_MODULE_UART);
    155        1.1      uch }
    156        1.1      uch 
    157       1.18      uwe STATIC void
    158        1.1      uch hd64461uart_attach(struct device *parent, struct device *self, void *aux)
    159        1.1      uch {
    160        1.1      uch 	struct hd64461_attach_args *ha = aux;
    161        1.1      uch 	struct hd64461uart_softc *sc = (struct hd64461uart_softc *)self;
    162        1.1      uch 	struct com_softc *csc = &sc->sc_com;
    163       1.18      uwe 	uint16_t r16;
    164  1.18.16.1  gdamore 	bus_space_handle_t ioh;
    165        1.1      uch 
    166        1.1      uch 	sc->sc_chip = &hd64461uart_chip;
    167        1.1      uch 
    168        1.1      uch 	sc->sc_module_id = ha->ha_module_id;
    169        1.1      uch 
    170        1.9      uch 	if (!sc->sc_chip->console)
    171        1.9      uch 		hd64461uart_init();
    172        1.1      uch 
    173  1.18.16.1  gdamore 	bus_space_map(sc->sc_chip->io_tag, 0, 8, 0, &ioh);
    174        1.1      uch 	csc->sc_frequency = COM_FREQ;
    175  1.18.16.1  gdamore 	COM_INIT_REGS(csc->sc_regs, sc->sc_chip->io_tag, ioh, 0);
    176        1.1      uch 
    177        1.1      uch 	/* switch port to UART */
    178        1.1      uch 
    179        1.1      uch 	/* supply clock */
    180        1.1      uch 	r16 = hd64461_reg_read_2(HD64461_SYSSTBCR_REG16);
    181        1.1      uch 	r16 &= ~HD64461_SYSSTBCR_SURTSD;
    182       1.18      uwe 	hd64461_reg_write_2(HD64461_SYSSTBCR_REG16, r16);
    183        1.1      uch 
    184        1.1      uch 	/* sanity check */
    185  1.18.16.1  gdamore 	if (!com_probe_subr(&csc->sc_regs)) {
    186        1.1      uch 		printf(": device problem. don't attach.\n");
    187        1.1      uch 
    188        1.1      uch 		/* stop clock */
    189        1.1      uch 		r16 |= HD64461_SYSSTBCR_SURTSD;
    190        1.1      uch 		hd64461_reg_write_2(HD64461_SYSSTBCR_REG16, r16);
    191        1.1      uch 		return;
    192        1.1      uch 	}
    193        1.1      uch 
    194        1.1      uch 	com_attach_subr(csc);
    195        1.1      uch 
    196       1.10      uch 	hd6446x_intr_establish(HD64461_INTC_UART, IST_LEVEL, IPL_TTY,
    197        1.3      uch 	    comintr, self);
    198        1.1      uch }
    199        1.1      uch 
    200       1.18      uwe STATIC void
    201       1.18      uwe hd64461uart_init(void)
    202        1.1      uch {
    203        1.3      uch 
    204        1.1      uch 	if (hd64461uart_chip.io_tag)
    205        1.1      uch 		return;
    206        1.1      uch 
    207        1.1      uch 	hd64461uart_chip.io_tag = bus_space_create(
    208        1.1      uch 		&hd64461uart_chip.__tag_body, "HD64461 UART I/O",
    209        1.1      uch 		HD64461_UART_REGBASE, 0); /* no extent */
    210        1.1      uch 
    211        1.1      uch 	/* override bus_space_read_1, bus_space_write_1 */
    212        1.1      uch 	hd64461uart_chip.io_tag->hbs_r_1 = hd64461uart_read_1;
    213        1.1      uch 	hd64461uart_chip.io_tag->hbs_w_1 = hd64461uart_write_1;
    214        1.1      uch }
    215        1.1      uch 
    216       1.18      uwe STATIC uint8_t
    217        1.1      uch hd64461uart_read_1(void *t, bus_space_handle_t h, bus_size_t ofs)
    218        1.1      uch {
    219        1.3      uch 
    220       1.18      uwe 	return *(volatile uint8_t *)(h + (ofs << 1));
    221        1.1      uch }
    222        1.1      uch 
    223       1.18      uwe STATIC void
    224        1.1      uch hd64461uart_write_1(void *t, bus_space_handle_t h, bus_size_t ofs,
    225       1.18      uwe     uint8_t val)
    226        1.1      uch {
    227        1.1      uch 
    228       1.18      uwe 	*(volatile uint8_t *)(h + (ofs << 1)) = val;
    229        1.1      uch }
    230