1169695Skan/* $NetBSD: au_timer.c,v 1.10 2011/02/20 07:48:36 matt Exp $ */ 2169695Skan 3169695Skan/* 4169695Skan * Copyright 2002 Wasabi Systems, Inc. 5169695Skan * All rights reserved. 6169695Skan * 7169695Skan * Written by Simon Burge for Wasabi Systems, Inc. 8169695Skan * 9169695Skan * Redistribution and use in source and binary forms, with or without 10169695Skan * modification, are permitted provided that the following conditions 11169695Skan * are met: 12169695Skan * 1. Redistributions of source code must retain the above copyright 13169695Skan * notice, this list of conditions and the following disclaimer. 14169695Skan * 2. Redistributions in binary form must reproduce the above copyright 15169695Skan * notice, this list of conditions and the following disclaimer in the 16169695Skan * documentation and/or other materials provided with the distribution. 17169695Skan * 3. All advertising materials mentioning features or use of this software 18169695Skan * must display the following acknowledgement: 19169695Skan * This product includes software developed for the NetBSD Project by 20169695Skan * Wasabi Systems, Inc. 21169695Skan * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22169695Skan * or promote products derived from this software without specific prior 23169695Skan * written permission. 24169695Skan * 25169695Skan * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26169695Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27169695Skan * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28169695Skan * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29169695Skan * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30169695Skan * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31169695Skan * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32169695Skan * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33169695Skan * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34169695Skan * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35169695Skan * POSSIBILITY OF SUCH DAMAGE. 36169695Skan */ 37169695Skan 38169695Skan#include <sys/cdefs.h> 39169695Skan__KERNEL_RCSID(0, "$NetBSD: au_timer.c,v 1.10 2011/02/20 07:48:36 matt Exp $"); 40169695Skan 41169695Skan#include <sys/param.h> 42169695Skan#include <sys/kernel.h> 43169695Skan#include <sys/lwp.h> 44169695Skan#include <sys/systm.h> 45169695Skan 46169695Skan#include <sys/bus.h> 47169695Skan#include <mips/locore.h> 48169695Skan 49169695Skan#include <mips/alchemy/include/aureg.h> 50169695Skan#include <mips/alchemy/include/auvar.h> 51169695Skan 52169695Skan/* 53169695Skan * Set a programmable clock register. 54169695Skan * If "wait" is non-zero, wait for that bit to become 0 in the 55169695Skan * counter control register before and after writing to the 56169695Skan * specified clock register. 57169695Skan */ 58169695Skan#define SET_PC_REG(reg, wait, val) \ 59169695Skando { \ 60169695Skan if (wait) \ 61169695Skan while (bus_space_read_4(st, sh, PC_COUNTER_CONTROL) \ 62169695Skan & (wait)) \ 63169695Skan /* nothing */; \ 64169695Skan bus_space_write_4(st, sh, (reg), (val)); \ 65169695Skan if (wait) \ 66169695Skan while (bus_space_read_4(st, sh, (reg)) & (wait)) \ 67169695Skan /* nothing */; \ 68169695Skan} while (0) 69169695Skan 70169695Skanvoid 71169695Skanau_cal_timers(bus_space_tag_t st, bus_space_handle_t sh) 72169695Skan{ 73169695Skan struct cpu_info * const ci = curcpu(); 74169695Skan uint32_t ctrdiff[4], startctr, endctr; 75169695Skan uint32_t ctl, ctr, octr; 76169695Skan int i; 77169695Skan 78169695Skan /* Enable the programmable counter 1. */ 79169695Skan ctl = bus_space_read_4(st, sh, PC_COUNTER_CONTROL); 80169695Skan if ((ctl & (CC_EO | CC_EN1)) != (CC_EO | CC_EN1)) 81169695Skan SET_PC_REG(PC_COUNTER_CONTROL, 0, ctl | CC_EO | CC_EN1); 82169695Skan 83169695Skan /* Initialize for 16Hz. */ 84169695Skan SET_PC_REG(PC_TRIM1, CC_T1S, PC_RATE / 16 - 1); 85169695Skan 86169695Skan /* Run the loop an extra time to prime the cache. */ 87169695Skan for (i = 0; i < 4; i++) { 88169695Skan /* Reset the counter. */ 89169695Skan SET_PC_REG(PC_COUNTER_WRITE1, CC_C1S, 0); 90169695Skan 91169695Skan /* Wait for 1/16th of a second. */ 92169695Skan //startctr = mips3_cp0_count_read(); 93169695Skan 94169695Skan /* Wait for the PC to tick over. */ 95169695Skan ctr = bus_space_read_4(st, sh, PC_COUNTER_READ_1); 96169695Skan do { 97169695Skan octr = bus_space_read_4(st, sh, PC_COUNTER_READ_1); 98169695Skan } while (ctr == octr); 99169695Skan 100169695Skan startctr = mips3_cp0_count_read(); 101169695Skan do { 102169695Skan ctr = bus_space_read_4(st, sh, PC_COUNTER_READ_1); 103169695Skan } while (ctr == octr); // while (ctr <= octr + 1); 104169695Skan endctr = mips3_cp0_count_read(); 105169695Skan ctrdiff[i] = endctr - startctr; 106169695Skan } 107169695Skan 108169695Skan /* Disable the counter (if it wasn't enabled already). */ 109169695Skan if ((ctl & (CC_EO | CC_EN1)) != (CC_EO | CC_EN1)) 110169695Skan SET_PC_REG(PC_COUNTER_CONTROL, 0, ctl); 111169695Skan 112169695Skan /* Compute the number of cycles per second. */ 113169695Skan ci->ci_cpu_freq = ((ctrdiff[2] + ctrdiff[3]) / 2) * 16; 114169695Skan ci->ci_cctr_freq = ci->ci_cpu_freq; 115169695Skan 116169695Skan /* Compute the number of ticks for hz. */ 117169695Skan ci->ci_cycles_per_hz = (ci->ci_cpu_freq + hz / 2) / hz; 118169695Skan 119169695Skan /* Compute the delay divisor. */ 120169695Skan ci->ci_divisor_delay = (ci->ci_cpu_freq + 500000) / 1000000; 121169695Skan 122169695Skan /* 123169695Skan * Get correct cpu frequency if the CPU runs at twice the 124169695Skan * external/cp0-count frequency. 125169695Skan */ 126169695Skan if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) 127169695Skan ci->ci_cpu_freq *= 2; 128169695Skan 129169695Skan#ifdef DEBUG 130169695Skan printf("Timer calibration: %lu cycles/sec [(%u, %u) * 16]\n", 131169695Skan ci->ci_cpu_freq, ctrdiff[2], ctrdiff[3]); 132169695Skan#endif 133169695Skan} 134169695Skan