2 * $Id: timer.c,v 1.2 2005-12-25 05:57:00 nkeynes Exp $
4 * SH4 Timer/Clock peripheral modules (CPG, TMU, RTC), combined together to
5 * keep things simple (they intertwine a bit).
7 * Copyright (c) 2005 Nathan Keynes.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
26 /********************************* CPG *************************************/
28 int32_t mmio_region_CPG_read( uint32_t reg )
30 return MMIO_READ( CPG, reg );
33 void mmio_region_CPG_write( uint32_t reg, uint32_t val )
35 MMIO_WRITE( CPG, reg, val );
38 /********************************** RTC *************************************/
40 int32_t mmio_region_RTC_read( uint32_t reg )
42 return MMIO_READ( RTC, reg );
45 void mmio_region_RTC_write( uint32_t reg, uint32_t val )
47 MMIO_WRITE( RTC, reg, val );
50 /********************************** TMU *************************************/
52 int timer_divider[3] = {16,16,16};
54 int32_t mmio_region_TMU_read( uint32_t reg )
56 return MMIO_READ( TMU, reg );
60 int get_timer_div( int val )
62 switch( val & 0x07 ) {
63 case 0: return 16; /* assume peripheral clock is IC/4 */
72 void mmio_region_TMU_write( uint32_t reg, uint32_t val )
76 timer_divider[0] = get_timer_div(val);
79 timer_divider[1] = get_timer_div(val);
82 timer_divider[2] = get_timer_div(val);
85 MMIO_WRITE( TMU, reg, val );
88 void TMU_run_slice( uint32_t nanosecs )
90 int tcr = MMIO_READ( TMU, TSTR );
91 int cycles = nanosecs / sh4_peripheral_period;
93 int count = cycles / timer_divider[0];
94 int *val = MMIO_REG( TMU, TCNT0 );
96 MMIO_READ( TMU, TCR0 ) |= 0x100;
97 /* interrupt goes here */
99 *val = MMIO_READ( TMU, TCOR0 ) - count;
105 int count = cycles / timer_divider[1];
106 int *val = MMIO_REG( TMU, TCNT1 );
108 MMIO_READ( TMU, TCR1 ) |= 0x100;
109 /* interrupt goes here */
111 *val = MMIO_READ( TMU, TCOR1 ) - count;
117 int count = cycles / timer_divider[2];
118 int *val = MMIO_REG( TMU, TCNT2 );
120 MMIO_READ( TMU, TCR2 ) |= 0x100;
121 /* interrupt goes here */
123 *val = MMIO_READ( TMU, TCOR2 ) - count;
.