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