source: trunk/libs/newlib/src/libgloss/or1k/timer.c @ 487

Last change on this file since 487 was 444, checked in by satin@…, 7 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.8 KB
Line 
1/* timer.c -- tick timer functions for OpenRISC 1000.
2 *
3 * Copyright (c) 2011, 2014 Authors
4 *
5 * Contributor Julius Baxter <juliusbaxter@gmail.com>
6 * Contributor Stefan Wallentowitz <stefan.wallentowitz@tum.de>
7 *
8 * The authors hereby grant permission to use, copy, modify, distribute,
9 * and license this software and its documentation for any purpose, provided
10 * that existing copyright notices are retained in all copies and that this
11 * notice is included verbatim in any distributions. No written agreement,
12 * license, or royalty fee is required for any of the authorized uses.
13 * Modifications to this software may be copyrighted by their authors
14 * and need not follow the licensing terms described here, provided that
15 * the new terms are clearly indicated on the first page of each file where
16 * they apply.
17 */
18
19#include "include/or1k-support.h"
20#include "include/or1k-sprs.h"
21
22#include "or1k-internals.h"
23#include "board.h"
24
25/* --------------------------------------------------------------------------*/
26/*!Tick timer interrupt handler
27
28   Increment timer ticks counter, reload TTMR
29                                                                             */
30/* --------------------------------------------------------------------------*/
31void
32_or1k_timer_interrupt_handler(void)
33{
34        OR1K_REENT.or1k_timer_ticks++;
35        uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR);
36        ttmr = OR1K_SPR_TICK_TTMR_IE_SET(ttmr, 1);
37        ttmr = OR1K_SPR_TICK_TTMR_MODE_SET(ttmr, OR1K_SPR_TICK_TTMR_MODE_RESTART);
38        ttmr = OR1K_SPR_TICK_TTMR_IP_SET(ttmr, 0);
39        or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr);
40}
41
42/* --------------------------------------------------------------------------*/
43/*!Enable tick timer
44
45   Install handler, calculate TTMR period, reset tick counter
46
47   @param[in] hz     Rate at which to trigger timer ticks                    */
48/* --------------------------------------------------------------------------*/
49int
50or1k_timer_init(unsigned int hz)
51{
52        uint32_t upr = or1k_mfspr(OR1K_SPR_SYS_UPR_ADDR);
53        if (OR1K_SPR_SYS_UPR_TTP_GET(upr) == 0) {
54                return -1;
55        }
56
57        /* Set this, for easy access when reloading */
58        uint32_t period = (_or1k_board_clk_freq/hz) & OR1K_SPR_TICK_TTMR_TP_MASK;
59        OR1K_REENT.or1k_timer_period = period;
60        or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, period);
61
62        /* Reset timer tick counter */
63        OR1K_REENT.or1k_timer_ticks = 0;
64
65        /* Install handler */
66        or1k_exception_handler_add(0x5, _or1k_timer_interrupt_handler);
67        OR1K_REENT.or1k_timer_mode = OR1K_SPR_TICK_TTMR_MODE_RESTART;
68
69        /* Reset counter register */
70        or1k_mtspr(OR1K_SPR_TICK_TTCR_ADDR, 0);
71
72        return 0;
73}
74
75void
76or1k_timer_set_period(uint32_t hz)
77{
78        uint32_t period = (_or1k_board_clk_freq/hz) & OR1K_SPR_TICK_TTMR_TP_MASK;
79        uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR);
80        ttmr = OR1K_SPR_TICK_TTMR_TP_SET(ttmr, period);
81        or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr);
82        OR1K_REENT.or1k_timer_period = period;
83}
84
85void
86or1k_timer_set_handler(void (*handler)(void))
87{
88        or1k_exception_handler_add(0x5, handler);
89}
90
91void
92or1k_timer_set_mode(uint32_t mode)
93{
94        // Store mode in variable
95        OR1K_REENT.or1k_timer_mode = mode;
96
97        uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR);
98        // If the timer is currently running, we also change the mode
99        if (OR1K_SPR_TICK_TTMR_MODE_GET(ttmr) != 0) {
100                ttmr = OR1K_SPR_TICK_TTMR_MODE_SET(ttmr, mode);
101                or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr);
102        }
103}
104
105/* --------------------------------------------------------------------------*/
106/*!Enable tick timer
107
108   Enable timer interrupt, install handler, load TTMR
109                                                                             */
110/* --------------------------------------------------------------------------*/
111void
112or1k_timer_enable(void)
113{
114        uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR);
115        ttmr = OR1K_SPR_TICK_TTMR_IE_SET(ttmr, 1);
116        ttmr = OR1K_SPR_TICK_TTMR_MODE_SET(ttmr, OR1K_REENT.or1k_timer_mode);
117        or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr);
118
119        uint32_t sr = or1k_mfspr(OR1K_SPR_SYS_SR_ADDR);
120        sr = OR1K_SPR_SYS_SR_TEE_SET(sr, 1);
121        or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, sr);
122}
123
124/* --------------------------------------------------------------------------*/
125/*!Disable tick timer
126
127   Disable timer interrupt in SR
128                                                                             */
129/* --------------------------------------------------------------------------*/
130uint32_t
131or1k_timer_disable(void)
132{
133        uint32_t oldsr = or1k_mfspr(OR1K_SPR_SYS_SR_ADDR);
134        uint32_t sr = OR1K_SPR_SYS_SR_TEE_SET(oldsr, 0);
135        or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, sr);
136        return OR1K_SPR_SYS_SR_TEE_GET(oldsr);
137}
138
139void
140or1k_timer_restore(uint32_t sr_tee)
141{
142        uint32_t sr = or1k_mfspr(OR1K_SPR_SYS_SR_ADDR);
143        sr = OR1K_SPR_SYS_SR_TEE_SET(sr, sr_tee);
144        or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, sr);
145}
146
147void
148or1k_timer_pause(void)
149{
150        uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR);
151        ttmr = OR1K_SPR_TICK_TTMR_MODE_SET(ttmr, OR1K_SPR_TICK_TTMR_MODE_DISABLE);
152        or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr);
153}
154
155void
156or1k_timer_reset(void)
157{
158        uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR);
159        ttmr = OR1K_SPR_TICK_TTMR_IP_SET(ttmr, 0);
160        or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr);
161        or1k_mtspr(OR1K_SPR_TICK_TTCR_ADDR, 0);
162}
163
164/* --------------------------------------------------------------------------*/
165/*!Get tick timer
166
167   Return value of tick timer
168                                                                             */
169/* --------------------------------------------------------------------------*/
170unsigned long
171or1k_timer_get_ticks(void)
172{
173        return OR1K_REENT.or1k_timer_ticks;
174}
175
176/* --------------------------------------------------------------------------*/
177/*!Reset tick timer
178
179   Clear value of tick timer
180                                                                             */
181/* --------------------------------------------------------------------------*/
182void
183or1k_timer_reset_ticks(void)
184{
185        OR1K_REENT.or1k_timer_ticks = 0;
186}
Note: See TracBrowser for help on using the repository browser.