Search
lxdream.org :: lxdream/src/sh4/timer.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/timer.c
changeset 859:b941c703ccd6
prev736:a02d1475ccfd
next929:fd8cb0c82f5f
author nkeynes
date Fri Sep 26 10:29:10 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Improve FRQCR register handling slightly (recognize the PLLEN1 flag)
file annotate diff log raw
1.1 --- a/src/sh4/timer.c Mon Jul 14 07:44:42 2008 +0000
1.2 +++ b/src/sh4/timer.c Fri Sep 26 10:29:10 2008 +0000
1.3 @@ -27,18 +27,22 @@
1.4 #include "sh4/intc.h"
1.5
1.6 /********************************* CPG *************************************/
1.7 -/* This is the base clock from which all other clocks are derived */
1.8 +/* This is the base clock from which all other clocks are derived.
1.9 + * Note: The real clock runs at 33Mhz, which is multiplied by the PLL to
1.10 + * run the instruction clock at 200Mhz. For sake of simplicity/precision,
1.11 + * we instead use 200Mhz as the base rate and divide everything down instead.
1.12 + **/
1.13 uint32_t sh4_input_freq = SH4_BASE_RATE;
1.14
1.15 uint32_t sh4_cpu_multiplier = 2000; /* = 0.5 * frequency */
1.16
1.17 uint32_t sh4_cpu_freq = SH4_BASE_RATE;
1.18 -uint32_t sh4_bus_freq = SH4_BASE_RATE;
1.19 -uint32_t sh4_peripheral_freq = SH4_BASE_RATE / 2;
1.20 +uint32_t sh4_bus_freq = SH4_BASE_RATE / 2;
1.21 +uint32_t sh4_peripheral_freq = SH4_BASE_RATE / 4;
1.22
1.23 uint32_t sh4_cpu_period = 1000 / SH4_BASE_RATE; /* in nanoseconds */
1.24 -uint32_t sh4_bus_period = 1000 / SH4_BASE_RATE;
1.25 -uint32_t sh4_peripheral_period = 2000 / SH4_BASE_RATE;
1.26 +uint32_t sh4_bus_period = 2* 1000 / SH4_BASE_RATE;
1.27 +uint32_t sh4_peripheral_period = 4 * 2000 / SH4_BASE_RATE;
1.28
1.29 int32_t mmio_region_CPG_read( uint32_t reg )
1.30 {
1.31 @@ -53,16 +57,20 @@
1.32 void mmio_region_CPG_write( uint32_t reg, uint32_t val )
1.33 {
1.34 uint32_t div;
1.35 + uint32_t primary_clock = sh4_input_freq;
1.36 +
1.37 switch( reg ) {
1.38 case FRQCR: /* Frequency control */
1.39 + if( (val & FRQCR_PLL1EN) == 0 )
1.40 + primary_clock /= 6;
1.41 div = ifc_divider[(val >> 6) & 0x07];
1.42 - sh4_cpu_freq = sh4_input_freq / div;
1.43 + sh4_cpu_freq = primary_clock / div;
1.44 sh4_cpu_period = sh4_cpu_multiplier * div / sh4_input_freq;
1.45 div = ifc_divider[(val >> 3) & 0x07];
1.46 - sh4_bus_freq = sh4_input_freq / div;
1.47 + sh4_bus_freq = primary_clock / div;
1.48 sh4_bus_period = 1000 * div / sh4_input_freq;
1.49 div = pfc_divider[val & 0x07];
1.50 - sh4_peripheral_freq = sh4_input_freq / div;
1.51 + sh4_peripheral_freq = primary_clock / div;
1.52 sh4_peripheral_period = 1000 * div / sh4_input_freq;
1.53
1.54 /* Update everything that depends on the peripheral frequency */
.