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