1/*	$OpenBSD: delay.c,v 1.1 2006/10/06 21:48:50 mickey Exp $	*/
2/*	$NetBSD: delay.c,v 1.1 2006/09/01 21:26:18 uwe Exp $	*/
3
4/*-
5 * Copyright (c) 2005 NONAKA Kimihiro
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/param.h>
31#include <libsa.h>
32
33#include <sh/tmureg.h>
34
35#ifndef	TICK_CH
36#define	TICK_CH	0
37#endif
38#if TICK_CH == 0
39#define	TSTR	SH4_TSTR
40#define	TCOR	SH4_TCOR0
41#define	TCNT	SH4_TCNT0
42#define	TCR	SH4_TCR0
43#define	TSTR_CH	TSTR_STR0
44#elif TICK_CH == 1
45#define	TSTR	SH4_TSTR
46#define	TCOR	SH4_TCOR1
47#define	TCNT	SH4_TCNT1
48#define	TCR	SH4_TCR1
49#define	TSTR_CH	TSTR_STR1
50#elif TICK_CH == 2
51#define	TSTR	SH4_TSTR
52#define	TCOR	SH4_TCOR2
53#define	TCNT	SH4_TCNT2
54#define	TCR	SH4_TCR2
55#define	TSTR_CH	TSTR_STR2
56#elif TICK_CH == 3
57#define	TSTR	SH4_TSTR2
58#define	TCOR	SH4_TCOR3
59#define	TCNT	SH4_TCNT3
60#define	TCR	SH4_TCR3
61#define	TSTR_CH	SH4_TSTR2_STR3
62#elif TICK_CH == 4
63#define	TSTR	SH4_TSTR2
64#define	TCOR	SH4_TCOR4
65#define	TCNT	SH4_TCNT4
66#define	TCR	SH4_TCR4
67#define	TSTR_CH	SH4_TSTR2_STR4
68#else
69#error	TICK_CH != [01234]
70#endif
71
72#ifndef	TICK_PRESC
73#define	TICK_PRESC	1024
74#endif
75#if TICK_PRESC == 4
76#define	TCR_TPSC	TCR_TPSC_P4
77#elif TICK_PRESC == 16
78#define	TCR_TPSC	TCR_TPSC_P16
79#elif TICK_PRESC == 64
80#define	TCR_TPSC	TCR_TPSC_P64
81#elif TICK_PRESC == 256
82#define	TCR_TPSC	TCR_TPSC_P256
83#elif TICK_PRESC == 1024
84#define	TCR_TPSC	SH4_TCR_TPSC_P1024
85#else
86#error	TICK_PRESC != 4, 16, 64, 256, 1024
87#endif
88
89#define	TICKS_PER_SEC	(PCLOCK / TICK_PRESC)
90#define	MS_PER_TICK	(1000000 / TICKS_PER_SEC)
91
92int
93tick_init(void)
94{
95
96	_reg_bclr_1(TSTR, TSTR_CH);
97	_reg_write_2(TCR, TCR_TPSC);
98	_reg_write_4(TCOR, 0xffffffff);
99	_reg_write_4(TCNT, 0xffffffff);
100	_reg_bset_1(TSTR, TSTR_CH);
101
102	return 0;
103}
104
105void
106tick_stop(void)
107{
108
109	_reg_bclr_1(TSTR, TSTR_CH);
110}
111
112uint32_t
113gettick(void)
114{
115
116	return ~(_reg_read_4(TCNT));
117}
118
119void
120delay(int ms)
121{
122	uint32_t base, now;
123
124	base = gettick();
125	for (;;) {
126		now = gettick();
127		if (((now - base) / MS_PER_TICK) > ms) {
128			break;
129		}
130	}
131}
132