1/* $NetBSD: timer_isa.c,v 1.13 2011/02/08 20:20:09 rmind Exp $ */ 2/* $OpenBSD: clock_mc.c,v 1.9 1998/03/16 09:38:26 pefo Exp $ */ 3/* NetBSD: clock_mc.c,v 1.2 1995/06/28 04:30:30 cgd Exp */ 4 5/* 6 * Copyright (c) 1988 University of Utah. 7 * Copyright (c) 1992, 1993 8 * The Regents of the University of California. All rights reserved. 9 * 10 * This code is derived from software contributed to Berkeley by 11 * the Systems Programming Group of the University of Utah Computer 12 * Science Department and Ralph Campbell. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * from: Utah Hdr: clock.c 1.18 91/01/21 39 * 40 * @(#)clock.c 8.1 (Berkeley) 6/10/93 41 */ 42 43#include <sys/cdefs.h> 44__KERNEL_RCSID(0, "$NetBSD: timer_isa.c,v 1.13 2011/02/08 20:20:09 rmind Exp $"); 45 46#include <sys/param.h> 47#include <sys/kernel.h> 48#include <sys/systm.h> 49#include <sys/device.h> 50 51#include <sys/bus.h> 52 53#include <dev/isa/isareg.h> 54#include <dev/isa/isavar.h> 55 56#include <dev/ic/i8253reg.h> 57 58#include <arc/arc/timervar.h> 59#include <arc/isa/timer_isavar.h> 60 61#define TIMER_IOSIZE 4 62#define TIMER_IRQ 0 63 64struct timer_isa_softc { 65 device_t sc_dev; 66 67 bus_space_tag_t sc_iot; 68 bus_space_handle_t sc_ioh; 69}; 70 71/* Definition of the driver for autoconfig. */ 72static int timer_isa_match(device_t, cfdata_t, void *); 73static void timer_isa_attach(device_t, device_t, void *); 74 75CFATTACH_DECL_NEW(timer_isa, sizeof(struct timer_isa_softc), 76 timer_isa_match, timer_isa_attach, NULL, NULL); 77 78/* ISA timer access code */ 79static void timer_isa_init(device_t); 80 81struct timerfns timerfns_isa = { 82 timer_isa_init 83}; 84 85int timer_isa_conf = 0; 86 87static int 88timer_isa_match(device_t parent, cfdata_t cf, void *aux) 89{ 90 struct isa_attach_args *ia = aux; 91 bus_space_handle_t ioh; 92 93 if (ia->ia_nio < 1 || 94 (ia->ia_io[0].ir_addr != ISA_UNKNOWN_PORT && 95 ia->ia_io[0].ir_addr != IO_TIMER1)) 96 return 0; 97 98 if (ia->ia_niomem > 0 && 99 (ia->ia_iomem[0].ir_addr != ISA_UNKNOWN_IOMEM)) 100 return 0; 101 102 if (ia->ia_nirq > 0 && 103 (ia->ia_irq[0].ir_irq != ISA_UNKNOWN_IRQ && 104 ia->ia_irq[0].ir_irq != TIMER_IRQ)) 105 return 0; 106 107 if (ia->ia_ndrq > 0 && 108 (ia->ia_drq[0].ir_drq != ISA_UNKNOWN_DRQ)) 109 return 0; 110 111 if (!timer_isa_conf) 112 return 0; 113 114 if (bus_space_map(ia->ia_iot, IO_TIMER1, TIMER_IOSIZE, 0, &ioh)) 115 return 0; 116 117 bus_space_unmap(ia->ia_iot, ioh, TIMER_IOSIZE); 118 119 ia->ia_nio = 1; 120 ia->ia_io[0].ir_addr = IO_TIMER1; 121 ia->ia_io[0].ir_size = TIMER_IOSIZE; 122 123 ia->ia_niomem = 0; 124 ia->ia_nirq = 0; 125 ia->ia_ndrq = 0; 126 127 return 1; 128} 129 130static void 131timer_isa_attach(device_t parent, device_t self, void *aux) 132{ 133 struct timer_isa_softc *sc = device_private(self); 134 struct isa_attach_args *ia = aux; 135 void *ih; 136 137 sc->sc_dev = self; 138 139 aprint_normal("\n"); 140 141 sc->sc_iot = ia->ia_iot; 142 if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 143 ia->ia_io[0].ir_size, 0, &sc->sc_ioh)) 144 panic("timer_isa_attach: couldn't map clock I/O space"); 145 146 ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, IST_PULSE, 147 IPL_CLOCK, (int (*)(void *))hardclock, 148 NULL /* clockframe is hardcoded */); 149 if (ih == NULL) 150 aprint_error_dev(self, "can't establish interrupt\n"); 151 152 timerattach(self, &timerfns_isa); 153} 154 155static void 156timer_isa_init(device_t self) 157{ 158 struct timer_isa_softc *sc = device_private(self); 159 160 bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_MODE, 161 TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN); 162 bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_CNTR0, 163 TIMER_DIV(hz) % 256); 164 bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_CNTR0, 165 TIMER_DIV(hz) / 256); 166} 167