tick.c revision 210403
1/*-
2 * Copyright (c) 2006-2009 RMI Corporation
3 * Copyright (c) 2006 Bruce M. Simpson
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28/*
29 * Simple driver for the 32-bit interval counter built in to all
30 * MIPS32 CPUs.
31 * XXX: For calibration this either needs an external clock, or
32 * to be explicitly told what the frequency is.
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/mips/rmi/tick.c 210403 2010-07-23 07:46:55Z mav $");
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/sysctl.h>
41#include <sys/time.h>
42#include <sys/timetc.h>
43#include <sys/kernel.h>
44#include <sys/power.h>
45#include <sys/smp.h>
46#include <machine/clock.h>
47#include <machine/locore.h>
48#include <machine/md_var.h>
49#include <machine/hwfunc.h>
50
51
52struct timecounter counter_timecounter = {
53	platform_get_timecount,	/* get_timecount */
54	0,			/* no poll_pps */
55	~0u,			/* counter_mask */
56	0,			/* frequency */
57	"MIPS32",		/* name */
58	800,			/* quality (adjusted in code) */
59};
60
61void tick_init(void);
62
63
64void
65tick_init(void)
66{
67	counter_freq = platform_get_frequency();
68	if (bootverbose)
69		printf("MIPS32 clock: %u MHz", cpu_clock);
70
71	counter_timecounter.tc_frequency = counter_freq;
72	tc_init(&counter_timecounter);
73}
74
75static int
76sysctl_machdep_counter_freq(SYSCTL_HANDLER_ARGS)
77{
78	int error;
79	uint64_t freq;
80
81	/*
82	 * RRS wonders if this will really work. You don't change the req of
83	 * the system here, it would require changes to the RMI PIC in order
84	 * to get the TC to run at a differrent frequency.
85	 */
86
87	if (counter_timecounter.tc_frequency == 0)
88		return (EOPNOTSUPP);
89	freq = counter_freq;
90	error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
91	if (error == 0 && req->newptr != NULL) {
92		counter_freq = freq;
93		counter_timecounter.tc_frequency = counter_freq;
94	}
95	return (error);
96}
97
98SYSCTL_PROC(_machdep, OID_AUTO, counter_freq, CTLTYPE_QUAD | CTLFLAG_RW,
99    0, sizeof(u_int), sysctl_machdep_counter_freq, "IU", "");
100