Search
lxdream.org :: lxdream :: r859:b941c703ccd6
lxdream 0.9.1
released Jun 29
Download Now
changeset859:b941c703ccd6
parent858:368fc0dcd57c
child860:b429964761c8
authornkeynes
dateFri Sep 26 10:29:10 2008 +0000 (14 years ago)
Improve FRQCR register handling slightly (recognize the PLLEN1 flag)
src/sh4/sh4mmio.h
src/sh4/timer.c
1.1 --- a/src/sh4/sh4mmio.h Fri Sep 12 11:59:49 2008 +0000
1.2 +++ b/src/sh4/sh4mmio.h Fri Sep 26 10:29:10 2008 +0000
1.3 @@ -117,9 +117,16 @@
1.4 LONG_PORT( 0x040, DMAOR, PORT_MRW, 0, "DMA operation register" )
1.5 MMIO_REGION_END
1.6
1.7 +#define FRQCR_CKOEN 0x0800
1.8 +#define FRQCR_PLL1EN 0x0400
1.9 +#define FRQCR_PLL2EN 0x0200
1.10 +#define FRQCR_IFC_MASK 0x01C0
1.11 +#define FRQCR_BFC_MASK 0x0038
1.12 +#define FRQCR_PFC_MASK 0x0007
1.13 +
1.14 /* Clock Pulse Generator (page 233 [273] of sh7750h manual) */
1.15 MMIO_REGION_BEGIN( 0xFFC00000, CPG, "Clock Pulse Generator" )
1.16 - WORD_PORT( 0x000, FRQCR, PORT_MRW, UNDEFINED, "Frequency control" )
1.17 + WORD_PORT( 0x000, FRQCR, PORT_MRW, 0x0E0A, "Frequency control" )
1.18 BYTE_PORT( 0x004, STBCR, PORT_MRW, 0, "Standby control" )
1.19 BYTE_PORT( 0x008, WTCNT, PORT_MRW, 0, "Watchdog timer counter" )
1.20 BYTE_PORT( 0x00C, WTCSR, PORT_MRW, 0, "Watchdog timer control/status" )
2.1 --- a/src/sh4/timer.c Fri Sep 12 11:59:49 2008 +0000
2.2 +++ b/src/sh4/timer.c Fri Sep 26 10:29:10 2008 +0000
2.3 @@ -27,18 +27,22 @@
2.4 #include "sh4/intc.h"
2.5
2.6 /********************************* CPG *************************************/
2.7 -/* This is the base clock from which all other clocks are derived */
2.8 +/* This is the base clock from which all other clocks are derived.
2.9 + * Note: The real clock runs at 33Mhz, which is multiplied by the PLL to
2.10 + * run the instruction clock at 200Mhz. For sake of simplicity/precision,
2.11 + * we instead use 200Mhz as the base rate and divide everything down instead.
2.12 + **/
2.13 uint32_t sh4_input_freq = SH4_BASE_RATE;
2.14
2.15 uint32_t sh4_cpu_multiplier = 2000; /* = 0.5 * frequency */
2.16
2.17 uint32_t sh4_cpu_freq = SH4_BASE_RATE;
2.18 -uint32_t sh4_bus_freq = SH4_BASE_RATE;
2.19 -uint32_t sh4_peripheral_freq = SH4_BASE_RATE / 2;
2.20 +uint32_t sh4_bus_freq = SH4_BASE_RATE / 2;
2.21 +uint32_t sh4_peripheral_freq = SH4_BASE_RATE / 4;
2.22
2.23 uint32_t sh4_cpu_period = 1000 / SH4_BASE_RATE; /* in nanoseconds */
2.24 -uint32_t sh4_bus_period = 1000 / SH4_BASE_RATE;
2.25 -uint32_t sh4_peripheral_period = 2000 / SH4_BASE_RATE;
2.26 +uint32_t sh4_bus_period = 2* 1000 / SH4_BASE_RATE;
2.27 +uint32_t sh4_peripheral_period = 4 * 2000 / SH4_BASE_RATE;
2.28
2.29 int32_t mmio_region_CPG_read( uint32_t reg )
2.30 {
2.31 @@ -53,16 +57,20 @@
2.32 void mmio_region_CPG_write( uint32_t reg, uint32_t val )
2.33 {
2.34 uint32_t div;
2.35 + uint32_t primary_clock = sh4_input_freq;
2.36 +
2.37 switch( reg ) {
2.38 case FRQCR: /* Frequency control */
2.39 + if( (val & FRQCR_PLL1EN) == 0 )
2.40 + primary_clock /= 6;
2.41 div = ifc_divider[(val >> 6) & 0x07];
2.42 - sh4_cpu_freq = sh4_input_freq / div;
2.43 + sh4_cpu_freq = primary_clock / div;
2.44 sh4_cpu_period = sh4_cpu_multiplier * div / sh4_input_freq;
2.45 div = ifc_divider[(val >> 3) & 0x07];
2.46 - sh4_bus_freq = sh4_input_freq / div;
2.47 + sh4_bus_freq = primary_clock / div;
2.48 sh4_bus_period = 1000 * div / sh4_input_freq;
2.49 div = pfc_divider[val & 0x07];
2.50 - sh4_peripheral_freq = sh4_input_freq / div;
2.51 + sh4_peripheral_freq = primary_clock / div;
2.52 sh4_peripheral_period = 1000 * div / sh4_input_freq;
2.53
2.54 /* Update everything that depends on the peripheral frequency */
.