1/* $NetBSD: obio_mputmr.c,v 1.4 2008/11/21 17:13:07 matt Exp $ */ 2 3/* 4 * Based on omap_mputmr.c 5 * Based on i80321_timer.c and arch/arm/sa11x0/sa11x0_ost.c 6 * 7 * Copyright (c) 1997 Mark Brinicombe. 8 * Copyright (c) 1997 Causality Limited. 9 * All rights reserved. 10 * 11 * This code is derived from software contributed to The NetBSD Foundation 12 * by IWAMOTO Toshihiro and Ichiro FUKUHARA. 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. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by the NetBSD 25 * Foundation, Inc. and its contributors. 26 * 4. Neither the name of The NetBSD Foundation nor the names of its 27 * contributors may be used to endorse or promote products derived 28 * from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 31 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 32 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 33 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 34 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40 * POSSIBILITY OF SUCH DAMAGE. 41 * 42 * Copyright (c) 2001, 2002 Wasabi Systems, Inc. 43 * All rights reserved. 44 * 45 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. All advertising materials mentioning features or use of this software 56 * must display the following acknowledgement: 57 * This product includes software developed for the NetBSD Project by 58 * Wasabi Systems, Inc. 59 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 60 * or promote products derived from this software without specific prior 61 * written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 65 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 66 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 67 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 68 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 69 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 70 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 71 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 72 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 73 * POSSIBILITY OF SUCH DAMAGE. 74 * 75 * Copyright (c) 2007 Microsoft 76 * All rights reserved. 77 * 78 * Redistribution and use in source and binary forms, with or without 79 * modification, are permitted provided that the following conditions 80 * are met: 81 * 1. Redistributions of source code must retain the above copyright 82 * notice, this list of conditions and the following disclaimer. 83 * 2. Redistributions in binary form must reproduce the above copyright 84 * notice, this list of conditions and the following disclaimer in the 85 * documentation and/or other materials provided with the distribution. 86 * 3. All advertising materials mentioning features or use of this software 87 * must display the following acknowledgement: 88 * This product includes software developed by Microsoft 89 * 90 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 91 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 92 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 93 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, 94 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 95 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 96 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 97 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 98 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 99 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 100 * SUCH DAMAGE. 101 */ 102 103#include <sys/cdefs.h> 104__KERNEL_RCSID(0, "$NetBSD: obio_mputmr.c,v 1.4 2008/11/21 17:13:07 matt Exp $"); 105 106#include "opt_omap.h" 107#include "opt_cpuoptions.h" 108 109#include <sys/types.h> 110#include <sys/param.h> 111#include <sys/systm.h> 112#include <sys/kernel.h> 113#include <sys/time.h> 114#include <sys/device.h> 115 116#include <dev/clock_subr.h> 117 118#include <sys/bus.h> 119#include <machine/intr.h> 120 121#include <arm/omap/omap2_obiovar.h> 122 123#include <arm/omap/omap2_mputmrvar.h> 124#include <arm/omap/omap2_mputmrreg.h> 125 126 127#include <arm/omap/omap2_reg.h> 128 129#ifndef OMAP_MPU_TIMER_CLOCK_FREQ 130#error Specify the timer frequency in Hz with the OMAP_MPU_TIMER_CLOCK_FREQ option. 131#endif 132 133typedef struct { 134 uint gptn; 135 bus_addr_t addr; 136 uint intr; 137 uint32_t clksel2; 138 uint32_t fclken1; 139 uint32_t iclken1; 140} gptimer_instance_t; 141 142/* XXX 143 * this table can be used to initialize the GP Timers 144 * until we use config(8) locators for CLKSEL2 values, you may want to edit here. 145 */ 146#define GPT_ENTRY(n) { \ 147 .gptn = (n), \ 148 .addr = GPT ## n ## _BASE, \ 149 .intr = IRQ_ ## GPT ## n, \ 150 .clksel2 = OMAP2_CM_CLKSEL2_CORE_GPTn(n, \ 151 CLKSEL2_CORE_GPT_SYS_CLK), \ 152 .fclken1 = OMAP2_CM_FCLKEN1_CORE_EN_GPT ## n, \ 153 .iclken1 = OMAP2_CM_ICLKEN1_CORE_EN_GPT ## n, \ 154 } 155static const gptimer_instance_t gptimer_instance_tab[] = { 156 GPT_ENTRY( 2), GPT_ENTRY( 3), GPT_ENTRY( 4), GPT_ENTRY( 5), 157 GPT_ENTRY( 6), GPT_ENTRY( 7), GPT_ENTRY( 8), GPT_ENTRY( 9), 158 GPT_ENTRY(10), GPT_ENTRY(11), GPT_ENTRY(12), 159}; 160#undef GPT_ENTRY 161#define GPTIMER_INSTANCE_CNT __arraycount(gptimer_instance_tab) 162 163static const gptimer_instance_t * 164 gpt_lookup(struct obio_attach_args *); 165static void gpt_enable(struct mputmr_softc *, 166 struct obio_attach_args *, const gptimer_instance_t *); 167 168static int obiomputmr_match(device_t, struct cfdata *, void *); 169static void obiomputmr_attach(device_t, device_t, void *); 170 171 172CFATTACH_DECL_NEW(obiomputmr, sizeof(struct mputmr_softc), 173 obiomputmr_match, obiomputmr_attach, NULL, NULL); 174 175static int 176obiomputmr_match(device_t parent, cfdata_t match, void *aux) 177{ 178 struct obio_attach_args *obio = aux; 179 180 if (obio->obio_addr == -1 || obio->obio_intr == -1) 181 panic("omapmputmr must have addr and intr specified in config."); 182 183 if (obio->obio_size == 0) 184 obio->obio_size = 256; /* Per the OMAP TRM. */ 185 186 if (gpt_lookup(obio) == NULL) 187 return 0; 188 189 /* We implicitly trust the config file. */ 190 return 1; 191} 192 193void 194obiomputmr_attach(device_t parent, device_t self, void *aux) 195{ 196 struct mputmr_softc *sc = device_private(self); 197 struct obio_attach_args *obio = aux; 198 int ints_per_sec; 199 200 sc->sc_dev = self; 201 sc->sc_iot = obio->obio_iot; 202 sc->sc_intr = obio->obio_intr; 203 204 if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0, 205 &sc->sc_ioh)) 206 panic("%s: Cannot map registers", device_xname(self)); 207 208 switch (device_unit(self)) { /* XXX broken */ 209 case 0: 210 clock_sc = sc; 211 ints_per_sec = hz; 212 break; 213 case 1: 214 stat_sc = sc; 215 ints_per_sec = profhz = stathz = STATHZ; 216 break; 217 case 2: 218 ref_sc = sc; 219 ints_per_sec = hz; /* Same rate as clock */ 220 break; 221 default: 222 ints_per_sec = hz; /* Better value? */ 223 break; 224 } 225 226 aprint_normal(": OMAP MPU Timer"); 227 gpt_enable(sc, obio, gpt_lookup(obio)); 228 aprint_normal("\n"); 229 aprint_naive("\n"); 230 231 /* Stop the timer from counting, but keep the timer module working. */ 232 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_CNTL_TIMER, 233 MPU_CLOCK_ENABLE); 234 235 timer_factors tf; 236 calc_timer_factors(ints_per_sec, &tf); 237 238 switch (device_unit(self)) { /* XXX broken */ 239 case 0: 240#ifndef ARM11_PMC 241 counts_per_hz = tf.reload + 1; 242 counts_per_usec = tf.counts_per_usec; 243#endif 244 break; 245 case 2: 246 247 /* 248 * The microtime reference clock for all practical purposes 249 * just wraps around as an unsigned int. 250 */ 251 252 tf.reload = 0xffffffff; 253 break; 254 255 default: 256 break; 257 } 258 259 /* Set the reload value. */ 260 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_LOAD_TIMER, tf.reload); 261 /* Set the PTV and the other required bits and pieces. */ 262 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_CNTL_TIMER, 263 ( MPU_CLOCK_ENABLE 264 | (tf.ptv << MPU_PTV_SHIFT) 265 | MPU_AR 266 | MPU_ST)); 267 /* The clock is now running, but is not generating interrupts. */ 268} 269 270static const gptimer_instance_t * 271gpt_lookup(struct obio_attach_args *obio) 272{ 273 const gptimer_instance_t *ip; 274 uint i; 275 276 for (i = 0, ip = gptimer_instance_tab; 277 i < GPTIMER_INSTANCE_CNT; i++, ip++) { 278 if (ip->addr == obio->obio_addr && ip->intr == obio->obio_intr) 279 return ip; 280 } 281 282 return NULL; 283} 284 285void 286gpt_enable( 287 struct mputmr_softc *sc, 288 struct obio_attach_args *obio, 289 const gptimer_instance_t *ip) 290{ 291 bus_space_handle_t ioh; 292 uint32_t r; 293 int err; 294 295 KASSERT(ip != NULL); 296 297 aprint_normal(" #%d", ip->gptn); 298 299 err = bus_space_map(obio->obio_iot, OMAP2_CM_BASE, 300 OMAP2_CM_SIZE, 0, &ioh); 301 KASSERT(err == 0); 302 303 r = bus_space_read_4(obio->obio_iot, ioh, OMAP2_CM_CLKSEL2_CORE); 304 r |= ip->clksel2; 305 bus_space_write_4(obio->obio_iot, ioh, OMAP2_CM_CLKSEL2_CORE, r); 306 307 r = bus_space_read_4(obio->obio_iot, ioh, OMAP2_CM_FCLKEN1_CORE); 308 r |= ip->fclken1; 309 bus_space_write_4(obio->obio_iot, ioh, OMAP2_CM_FCLKEN1_CORE, r); 310 311 r = bus_space_read_4(obio->obio_iot, ioh, OMAP2_CM_ICLKEN1_CORE); 312 r |= ip->iclken1; 313 bus_space_write_4(obio->obio_iot, ioh, OMAP2_CM_ICLKEN1_CORE, r); 314 315 bus_space_unmap(obio->obio_iot, ioh, OMAP2_CM_SIZE); 316} 317