1/* $NetBSD: obio_timer.c,v 1.4 2008/12/04 00:38:07 cliff Exp $ */ 2 3/* adapted from: 4 * NetBSD: obio_mputmr.c,v 1.3 2008/08/27 11:03:10 matt Exp 5 */ 6 7/* 8 * Based on omap_mputmr.c 9 * Based on i80321_timer.c and arch/arm/sa11x0/sa11x0_ost.c 10 * 11 * Copyright (c) 1997 Mark Brinicombe. 12 * Copyright (c) 1997 Causality Limited. 13 * All rights reserved. 14 * 15 * This code is derived from software contributed to The NetBSD Foundation 16 * by IWAMOTO Toshihiro and Ichiro FUKUHARA. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 1. Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in the 25 * documentation and/or other materials provided with the distribution. 26 * 3. All advertising materials mentioning features or use of this software 27 * must display the following acknowledgement: 28 * This product includes software developed by the NetBSD 29 * Foundation, Inc. and its contributors. 30 * 4. Neither the name of The NetBSD Foundation nor the names of its 31 * contributors may be used to endorse or promote products derived 32 * from this software without specific prior written permission. 33 * 34 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 35 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 36 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 37 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 38 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 39 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 40 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 44 * POSSIBILITY OF SUCH DAMAGE. 45 * 46 * Copyright (c) 2001, 2002 Wasabi Systems, Inc. 47 * All rights reserved. 48 * 49 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 50 * 51 * Redistribution and use in source and binary forms, with or without 52 * modification, are permitted provided that the following conditions 53 * are met: 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. All advertising materials mentioning features or use of this software 60 * must display the following acknowledgement: 61 * This product includes software developed for the NetBSD Project by 62 * Wasabi Systems, Inc. 63 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 64 * or promote products derived from this software without specific prior 65 * written permission. 66 * 67 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 68 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 69 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 70 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 71 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 72 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 73 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 74 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 75 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 76 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 77 * POSSIBILITY OF SUCH DAMAGE. 78 * 79 * Copyright (c) 2007 Microsoft 80 * All rights reserved. 81 * 82 * Redistribution and use in source and binary forms, with or without 83 * modification, are permitted provided that the following conditions 84 * are met: 85 * 1. Redistributions of source code must retain the above copyright 86 * notice, this list of conditions and the following disclaimer. 87 * 2. Redistributions in binary form must reproduce the above copyright 88 * notice, this list of conditions and the following disclaimer in the 89 * documentation and/or other materials provided with the distribution. 90 * 3. All advertising materials mentioning features or use of this software 91 * must display the following acknowledgement: 92 * This product includes software developed by Microsoft 93 * 94 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 95 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 96 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 97 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, 98 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 99 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 100 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 101 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 102 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 103 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 104 * SUCH DAMAGE. 105 */ 106 107#include <sys/cdefs.h> 108__KERNEL_RCSID(0, "$NetBSD: obio_timer.c,v 1.4 2008/12/04 00:38:07 cliff Exp $"); 109 110#include "opt_cpuoptions.h" 111#include "opt_gemini.h" 112#include "locators.h" 113 114#include <sys/types.h> 115#include <sys/param.h> 116#include <sys/systm.h> 117#include <sys/kernel.h> 118#include <sys/time.h> 119#include <sys/device.h> 120 121#include <dev/clock_subr.h> 122 123#include <sys/bus.h> 124#include <machine/intr.h> 125 126#include <arm/gemini/gemini_reg.h> 127#include <arm/gemini/gemini_obiovar.h> 128#include <arm/gemini/gemini_timervar.h> 129 130#if STATHZ != HZ 131# error system clock HZ and stat clock STATHZ must be same 132#endif 133 134 135#ifndef GEMINI_TIMER_CLOCK_FREQ 136# error Specify the timer frequency in Hz with option GEMINI_TIMER_CLOCK_FREQ 137#endif 138 139static int obiotimer_match(device_t, struct cfdata *, void *); 140static void obiotimer_attach(device_t, device_t, void *); 141 142struct geminitmr_softc xsc; 143 144 145 146typedef struct { 147 uint timerno; 148 bus_addr_t addr; 149 uint intr; 150} obiotimer_instance_t; 151 152/* XXX 153 * this table can be used to match the GP Timers 154 * until we use config(8) locators to distinguish between 155 * gemini "sub-timers". 156 */ 157#define GPT_ENTRY(n, i) { \ 158 .timerno = (n), \ 159 .addr = GEMINI_TIMER_BASE, \ 160 .intr = i, \ 161 } 162static const obiotimer_instance_t obiotimer_instance_tab[] = { 163 GPT_ENTRY(1, 14), 164 GPT_ENTRY(2, 15), 165 GPT_ENTRY(3, 16), 166}; 167#undef GPT_ENTRY 168#define GPTIMER_INSTANCE_CNT __arraycount(obiotimer_instance_tab) 169 170static const obiotimer_instance_t * 171 obiotimer_lookup(struct obio_attach_args *); 172static void obiotimer_enable(struct geminitmr_softc *, 173 struct obio_attach_args *, 174 const obiotimer_instance_t *); 175 176static int obiotimer_match(device_t, struct cfdata *, void *); 177static void obiotimer_attach(device_t, device_t, void *); 178 179 180CFATTACH_DECL_NEW(obiotimer, sizeof(struct geminitmr_softc), 181 obiotimer_match, obiotimer_attach, NULL, NULL); 182 183 184static int 185obiotimer_match(device_t parent, struct cfdata *match, void *aux) 186{ 187 struct obio_attach_args *obio = aux; 188 189 if ((obio->obio_addr == OBIOCF_ADDR_DEFAULT) 190 || (obio->obio_intr == OBIOCF_INTR_DEFAULT)) 191 panic("geminitmr must have addr and intr specified in config."); 192 193 if (obiotimer_lookup(obio) == NULL) 194 return 0; 195 196 return 1; 197} 198 199void 200obiotimer_attach(device_t parent, device_t self, void *aux) 201{ 202 struct geminitmr_softc *sc = device_private(self); 203 struct obio_attach_args *obio = aux; 204 const obiotimer_instance_t *ip; 205#ifndef GEMINI_SLAVE 206 static int once=1; 207#endif 208 209 ip = obiotimer_lookup(obio); 210 if (ip == NULL) 211 panic("%s: bad lookup", device_xname(self)); 212 /* should not fail since we already matched */ 213 214 sc->sc_timerno = ip->timerno; 215 sc->sc_iot = obio->obio_iot; 216 sc->sc_intr = obio->obio_intr; 217 sc->sc_addr = obio->obio_addr; 218 sc->sc_size = (obio->obio_size == OBIOCF_SIZE_DEFAULT) 219 ? (GEMINI_TIMER_INTRMASK + 4) 220 : obio->obio_size; 221 222 if (bus_space_map(sc->sc_iot, sc->sc_addr, sc->sc_size, 0, &sc->sc_ioh)) 223 panic("%s: Cannot map registers", device_xname(self)); 224 225 obiotimer_enable(sc, obio, obiotimer_lookup(obio)); 226 aprint_normal("\n"); 227 aprint_naive("\n"); 228 229#ifndef GEMINI_SLAVE 230 if (once) { 231 once = 0; 232 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 233 GEMINI_TIMER_TMCR, 0); 234 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 235 GEMINI_TIMER_INTRMASK, (uint32_t)~TIMER_INTRMASK_Resv); 236 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 237 GEMINI_TIMER_INTRSTATE, 0); 238 } 239#endif 240 241 switch (sc->sc_timerno) { 242 case 1: 243#ifndef GEMINI_SLAVE 244 /* 245 * timer #1 is the combined system clock and stat clock 246 * for the Master or Single Gemini CPU 247 * it gets started later 248 */ 249 profhz = stathz = hz; 250 stat_sc = clock_sc = sc; 251#endif 252 break; 253 case 2: 254#ifdef GEMINI_SLAVE 255 /* 256 * timer #2 is the combined system clock and stat clock 257 * for the Slave Gemini CPU 258 * it gets started later 259 */ 260 profhz = stathz = hz; 261 stat_sc = clock_sc = sc; 262#endif 263 break; 264 case 3: 265 /* 266 * Timer #3 is used for microtime reference clock and delay() 267 * autoloading, non-interrupting, just wraps around 268 * we start it now to make delay() available 269 */ 270 ref_sc = sc; 271#ifndef GEMINI_SLAVE 272 gemini_microtime_init(); 273#endif 274 break; 275 default: 276 panic("bad gemini timer number %d\n", sc->sc_timerno); 277 break; 278 } 279} 280 281static const obiotimer_instance_t * 282obiotimer_lookup(struct obio_attach_args *obio) 283{ 284 const obiotimer_instance_t *ip; 285 uint i; 286 287 for (i = 0, ip = obiotimer_instance_tab; 288 i < GPTIMER_INSTANCE_CNT; i++, ip++) { 289 if (ip->addr == obio->obio_addr && ip->intr == obio->obio_intr) 290 return ip; 291 } 292 293 return NULL; 294} 295 296void 297obiotimer_enable( 298 struct geminitmr_softc *sc, 299 struct obio_attach_args *obio, 300 const obiotimer_instance_t *ip) 301{ 302 /* nothing to do */ 303} 304