xref: /netbsd-src/sys/arch/hppa/dev/com_dino.c (revision ee2e3cd827a52b58023121b3e1bb2522d9099855)
16d3ceb1dSskrll /*	$OpenBSD: com_dino.c,v 1.4 2007/07/15 19:25:49 kettenis Exp $	*/
26d3ceb1dSskrll 
36d3ceb1dSskrll /*
46d3ceb1dSskrll  * Copyright (c) 2004 Michael Shalayeff
56d3ceb1dSskrll  * All rights reserved.
66d3ceb1dSskrll  *
76d3ceb1dSskrll  * Redistribution and use in source and binary forms, with or without
86d3ceb1dSskrll  * modification, are permitted provided that the following conditions
96d3ceb1dSskrll  * are met:
106d3ceb1dSskrll  * 1. Redistributions of source code must retain the above copyright
116d3ceb1dSskrll  *    notice, this list of conditions and the following disclaimer.
126d3ceb1dSskrll  * 2. Redistributions in binary form must reproduce the above copyright
136d3ceb1dSskrll  *    notice, this list of conditions and the following disclaimer in the
146d3ceb1dSskrll  *    documentation and/or other materials provided with the distribution.
156d3ceb1dSskrll  *
166d3ceb1dSskrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
176d3ceb1dSskrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
186d3ceb1dSskrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
196d3ceb1dSskrll  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
206d3ceb1dSskrll  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
216d3ceb1dSskrll  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
226d3ceb1dSskrll  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
236d3ceb1dSskrll  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
246d3ceb1dSskrll  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
256d3ceb1dSskrll  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
266d3ceb1dSskrll  * THE POSSIBILITY OF SUCH DAMAGE.
276d3ceb1dSskrll  */
286d3ceb1dSskrll 
296d3ceb1dSskrll #include <sys/param.h>
306d3ceb1dSskrll #include <sys/systm.h>
316d3ceb1dSskrll #include <sys/device.h>
326d3ceb1dSskrll #include <sys/tty.h>
336d3ceb1dSskrll 
346d3ceb1dSskrll #include <sys/bus.h>
356d3ceb1dSskrll #include <machine/intr.h>
366d3ceb1dSskrll #include <machine/iomod.h>
376d3ceb1dSskrll #include <machine/autoconf.h>
386d3ceb1dSskrll 
396d3ceb1dSskrll #include <dev/ic/comreg.h>
406d3ceb1dSskrll #include <dev/ic/comvar.h>
416d3ceb1dSskrll 
426d3ceb1dSskrll #include <hppa/dev/cpudevs.h>
436d3ceb1dSskrll #include <hppa/hppa/machdep.h>
446d3ceb1dSskrll 
456d3ceb1dSskrll void *dino_intr_establish(void *sc, int irq, int pri,
466d3ceb1dSskrll     int (*handler)(void *v), void *arg);
476d3ceb1dSskrll 
486d3ceb1dSskrll #define	COM_DINO_FREQ	7272700
496d3ceb1dSskrll 
506d3ceb1dSskrll struct com_dino_softc {
516d3ceb1dSskrll 	struct  com_softc sc_com;	/* real "com" softc */
526d3ceb1dSskrll 	void	*sc_ih;			/* interrupt handler */
536d3ceb1dSskrll };
546d3ceb1dSskrll 
556d3ceb1dSskrll struct com_dino_regs {
566d3ceb1dSskrll 	uint8_t		reset;
576d3ceb1dSskrll 	uint8_t		pad0[3];
586d3ceb1dSskrll 	uint8_t		test;
596d3ceb1dSskrll #define	COM_DINO_PAR_LOOP	0x01
606d3ceb1dSskrll #define	COM_DINO_CLK_SEL	0x02
616d3ceb1dSskrll 	uint8_t		pad1[3];
626d3ceb1dSskrll 	uint32_t	iodc;
636d3ceb1dSskrll 	uint8_t		pad2[0x54];
646d3ceb1dSskrll 	uint8_t		dither;
656d3ceb1dSskrll };
666d3ceb1dSskrll 
676d3ceb1dSskrll int	com_dino_match(device_t, cfdata_t, void *);
686d3ceb1dSskrll void	com_dino_attach(device_t, device_t, void *);
696d3ceb1dSskrll 
706d3ceb1dSskrll CFATTACH_DECL_NEW(com_dino, sizeof(struct com_dino_softc), com_dino_match,
716d3ceb1dSskrll     com_dino_attach, NULL, NULL);
726d3ceb1dSskrll 
736d3ceb1dSskrll int
com_dino_match(device_t parent,cfdata_t match,void * aux)746d3ceb1dSskrll com_dino_match(device_t parent, cfdata_t match, void *aux)
756d3ceb1dSskrll {
766d3ceb1dSskrll 	struct confargs *ca = aux;
776d3ceb1dSskrll 
786d3ceb1dSskrll 	if (ca->ca_type.iodc_type != HPPA_TYPE_FIO ||
796d3ceb1dSskrll 	    ca->ca_type.iodc_sv_model != HPPA_FIO_GRS232)
80*ee2e3cd8Sskrll 		return 0;
816d3ceb1dSskrll 
82*ee2e3cd8Sskrll 	return 1;
836d3ceb1dSskrll 	/* HOZER comprobe1(ca->ca_iot, ca->ca_hpa + IOMOD_DEVOFFSET); */
846d3ceb1dSskrll }
856d3ceb1dSskrll 
866d3ceb1dSskrll void
com_dino_attach(device_t parent,device_t self,void * aux)876d3ceb1dSskrll com_dino_attach(device_t parent, device_t self, void *aux)
886d3ceb1dSskrll {
896d3ceb1dSskrll 	void *sc_dino = device_private(parent);
906d3ceb1dSskrll 	struct com_dino_softc *sc_comdino = device_private(self);
916d3ceb1dSskrll 	struct com_softc *sc = &sc_comdino->sc_com;
926d3ceb1dSskrll 	struct confargs *ca = aux;
936d3ceb1dSskrll 	struct com_dino_regs *regs = (struct com_dino_regs *)ca->ca_hpa;
946d3ceb1dSskrll 	int pagezero_cookie;
956d3ceb1dSskrll 
966d3ceb1dSskrll 	bus_addr_t iobase;
976d3ceb1dSskrll 	bus_space_handle_t ioh;
986d3ceb1dSskrll 
996d3ceb1dSskrll 	sc->sc_dev = self;
1006d3ceb1dSskrll 	iobase = (bus_addr_t)ca->ca_hpa + IOMOD_DEVOFFSET;
1016d3ceb1dSskrll 	sc->sc_frequency = COM_DINO_FREQ;
1026d3ceb1dSskrll 
1036d3ceb1dSskrll 	/* Test if this is the console.  Compare either HPA or device path. */
1046d3ceb1dSskrll 	pagezero_cookie = hppa_pagezero_map();
1056d3ceb1dSskrll 	if (PAGE0->mem_cons.pz_class == PCL_DUPLEX &&
1066d3ceb1dSskrll 	    PAGE0->mem_cons.pz_hpa == (struct iomod *)ca->ca_hpa) {
1076d3ceb1dSskrll 
1086d3ceb1dSskrll 		/*
1096d3ceb1dSskrll 		 * This port is the console.  In this case we must call
1106d3ceb1dSskrll 		 * comcnattach() and later com_is_console() to initialize
1116d3ceb1dSskrll 		 * everything properly.
1126d3ceb1dSskrll 		 */
1136d3ceb1dSskrll 
1146d3ceb1dSskrll 		if (comcnattach(ca->ca_iot, iobase, B9600,
1156d3ceb1dSskrll 		    sc->sc_frequency, COM_TYPE_NORMAL,
1166d3ceb1dSskrll 		    (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) {
1176d3ceb1dSskrll 			aprint_error(": can't comcnattach\n");
1186d3ceb1dSskrll 			hppa_pagezero_unmap(pagezero_cookie);
1196d3ceb1dSskrll 			return;
1206d3ceb1dSskrll 		}
1216d3ceb1dSskrll 	}
1226d3ceb1dSskrll 	hppa_pagezero_unmap(pagezero_cookie);
1236d3ceb1dSskrll 
1246d3ceb1dSskrll 	/*
1256d3ceb1dSskrll 	 * Get the already initialized console ioh via com_is_console() if
1266d3ceb1dSskrll 	 * this is the console or map the I/O space if this isn't the console.
1276d3ceb1dSskrll 	 */
1286d3ceb1dSskrll 
1296d3ceb1dSskrll 	if (!com_is_console(ca->ca_iot, iobase, &ioh) &&
1306d3ceb1dSskrll 	    bus_space_map(ca->ca_iot, iobase, COM_NPORTS, 0, &ioh) != 0) {
1316d3ceb1dSskrll 		aprint_error(": can't map I/O space\n");
1326d3ceb1dSskrll 		return;
1336d3ceb1dSskrll 	}
1346d487047Sthorpej 	com_init_regs(&sc->sc_regs, ca->ca_iot, ioh, iobase);
1356d3ceb1dSskrll 
1366d3ceb1dSskrll 	/* select clock freq */
1376d3ceb1dSskrll 	regs->test = COM_DINO_CLK_SEL;
1386d3ceb1dSskrll 
1396d3ceb1dSskrll 	com_attach_subr(sc);
1406d3ceb1dSskrll 
1416d3ceb1dSskrll 	ca->ca_irq = 10;
1426d3ceb1dSskrll 
1436d3ceb1dSskrll 	sc_comdino->sc_ih = dino_intr_establish(sc_dino, ca->ca_irq, IPL_TTY,
1446d3ceb1dSskrll 	    comintr, sc);
1456d3ceb1dSskrll }
146