1238722Skargl/* $NetBSD: timer_isa.c,v 1.13 2011/02/08 20:20:09 rmind Exp $ */ 2251315Skargl/* $OpenBSD: clock_mc.c,v 1.9 1998/03/16 09:38:26 pefo Exp $ */ 3238722Skargl/* NetBSD: clock_mc.c,v 1.2 1995/06/28 04:30:30 cgd Exp */ 4238722Skargl 5238722Skargl/* 6238722Skargl * Copyright (c) 1988 University of Utah. 7238722Skargl * Copyright (c) 1992, 1993 8238722Skargl * The Regents of the University of California. All rights reserved. 9238722Skargl * 10238722Skargl * This code is derived from software contributed to Berkeley by 11238722Skargl * the Systems Programming Group of the University of Utah Computer 12238722Skargl * Science Department and Ralph Campbell. 13238722Skargl * 14238722Skargl * Redistribution and use in source and binary forms, with or without 15238722Skargl * modification, are permitted provided that the following conditions 16238722Skargl * are met: 17238722Skargl * 1. Redistributions of source code must retain the above copyright 18238722Skargl * notice, this list of conditions and the following disclaimer. 19238722Skargl * 2. Redistributions in binary form must reproduce the above copyright 20238722Skargl * notice, this list of conditions and the following disclaimer in the 21238722Skargl * documentation and/or other materials provided with the distribution. 22238722Skargl * 3. Neither the name of the University nor the names of its contributors 23238722Skargl * may be used to endorse or promote products derived from this software 24238722Skargl * without specific prior written permission. 25251337Skargl * 26251337Skargl * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27238722Skargl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28238722Skargl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29238722Skargl * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30238722Skargl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31238722Skargl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32240864Skargl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33240864Skargl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34240864Skargl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35240864Skargl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36238722Skargl * SUCH DAMAGE. 37238722Skargl * 38238783Skargl * from: Utah Hdr: clock.c 1.18 91/01/21 39238722Skargl * 40238722Skargl * @(#)clock.c 8.1 (Berkeley) 6/10/93 41238722Skargl */ 42240864Skargl 43251327Skargl#include <sys/cdefs.h> 44238722Skargl__KERNEL_RCSID(0, "$NetBSD: timer_isa.c,v 1.13 2011/02/08 20:20:09 rmind Exp $"); 45238722Skargl 46251334Skargl#include <sys/param.h> 47251334Skargl#include <sys/kernel.h> 48251345Skargl#include <sys/systm.h> 49251334Skargl#include <sys/device.h> 50240864Skargl 51238722Skargl#include <sys/bus.h> 52238722Skargl 53251334Skargl#include <dev/isa/isareg.h> 54251334Skargl#include <dev/isa/isavar.h> 55238722Skargl 56251334Skargl#include <dev/ic/i8253reg.h> 57240864Skargl 58238722Skargl#include <arc/arc/timervar.h> 59251334Skargl#include <arc/isa/timer_isavar.h> 60251334Skargl 61251334Skargl#define TIMER_IOSIZE 4 62251334Skargl#define TIMER_IRQ 0 63251334Skargl 64251334Skarglstruct timer_isa_softc { 65251334Skargl device_t sc_dev; 66251334Skargl 67238722Skargl bus_space_tag_t sc_iot; 68251334Skargl bus_space_handle_t sc_ioh; 69251334Skargl}; 70238722Skargl 71251334Skargl/* Definition of the driver for autoconfig. */ 72251334Skarglstatic int timer_isa_match(device_t, cfdata_t, void *); 73251341Skarglstatic void timer_isa_attach(device_t, device_t, void *); 74251334Skargl 75251334SkarglCFATTACH_DECL_NEW(timer_isa, sizeof(struct timer_isa_softc), 76251334Skargl timer_isa_match, timer_isa_attach, NULL, NULL); 77251334Skargl 78251334Skargl/* ISA timer access code */ 79251334Skarglstatic void timer_isa_init(device_t); 80251334Skargl 81251334Skarglstruct timerfns timerfns_isa = { 82251334Skargl timer_isa_init 83251334Skargl}; 84251334Skargl 85251334Skarglint timer_isa_conf = 0; 86251334Skargl 87251334Skarglstatic int 88251334Skargltimer_isa_match(device_t parent, cfdata_t cf, void *aux) 89238722Skargl{ 90251341Skargl struct isa_attach_args *ia = aux; 91251341Skargl bus_space_handle_t ioh; 92251341Skargl 93251341Skargl if (ia->ia_nio < 1 || 94251341Skargl (ia->ia_io[0].ir_addr != ISA_UNKNOWN_PORT && 95238722Skargl ia->ia_io[0].ir_addr != IO_TIMER1)) 96238722Skargl return 0; 97251321Skargl 98238722Skargl if (ia->ia_niomem > 0 && 99238722Skargl (ia->ia_iomem[0].ir_addr != ISA_UNKNOWN_IOMEM)) 100238722Skargl return 0; 101238722Skargl 102238722Skargl if (ia->ia_nirq > 0 && 103238722Skargl (ia->ia_irq[0].ir_irq != ISA_UNKNOWN_IRQ && 104238722Skargl ia->ia_irq[0].ir_irq != TIMER_IRQ)) 105238722Skargl return 0; 106238722Skargl 107238722Skargl if (ia->ia_ndrq > 0 && 108238722Skargl (ia->ia_drq[0].ir_drq != ISA_UNKNOWN_DRQ)) 109238722Skargl return 0; 110238722Skargl 111238722Skargl if (!timer_isa_conf) 112238722Skargl return 0; 113238722Skargl 114238722Skargl if (bus_space_map(ia->ia_iot, IO_TIMER1, TIMER_IOSIZE, 0, &ioh)) 115238722Skargl return 0; 116238722Skargl 117238722Skargl bus_space_unmap(ia->ia_iot, ioh, TIMER_IOSIZE); 118238722Skargl 119238722Skargl ia->ia_nio = 1; 120238722Skargl ia->ia_io[0].ir_addr = IO_TIMER1; 121238722Skargl ia->ia_io[0].ir_size = TIMER_IOSIZE; 122238722Skargl 123238722Skargl ia->ia_niomem = 0; 124238722Skargl ia->ia_nirq = 0; 125238722Skargl ia->ia_ndrq = 0; 126238722Skargl 127238722Skargl return 1; 128238722Skargl} 129238722Skargl 130238722Skarglstatic void 131238722Skargltimer_isa_attach(device_t parent, device_t self, void *aux) 132238722Skargl{ 133238722Skargl struct timer_isa_softc *sc = device_private(self); 134238722Skargl struct isa_attach_args *ia = aux; 135238722Skargl void *ih; 136238722Skargl 137238722Skargl sc->sc_dev = self; 138238722Skargl 139238722Skargl aprint_normal("\n"); 140238722Skargl 141238722Skargl sc->sc_iot = ia->ia_iot; 142238722Skargl if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 143238722Skargl ia->ia_io[0].ir_size, 0, &sc->sc_ioh)) 144238722Skargl panic("timer_isa_attach: couldn't map clock I/O space"); 145238722Skargl 146238722Skargl ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, IST_PULSE, 147238722Skargl IPL_CLOCK, (int (*)(void *))hardclock, 148238722Skargl NULL /* clockframe is hardcoded */); 149238722Skargl if (ih == NULL) 150238722Skargl aprint_error_dev(self, "can't establish interrupt\n"); 151238722Skargl 152238722Skargl timerattach(self, &timerfns_isa); 153238722Skargl} 154238722Skargl 155238722Skarglstatic void 156238722Skargltimer_isa_init(device_t self) 157238722Skargl{ 158238722Skargl struct timer_isa_softc *sc = device_private(self); 159238722Skargl 160238722Skargl bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_MODE, 161238722Skargl TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN); 162238722Skargl bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_CNTR0, 163238722Skargl TIMER_DIV(hz) % 256); 164238722Skargl bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_CNTR0, 165238722Skargl TIMER_DIV(hz) / 256); 166238722Skargl} 167238722Skargl