mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03:36 +01:00
cpg: add overclock save/restore functions
This commit is contained in:
parent
b3416dcc25
commit
7e859169fe
2 changed files with 45 additions and 41 deletions
|
@ -135,6 +135,26 @@ int clock_get_speed(void);
|
||||||
leaving the add-in. */
|
leaving the add-in. */
|
||||||
void clock_set_speed(int speed);
|
void clock_set_speed(int speed);
|
||||||
|
|
||||||
|
/* If you want to faithfully save and restore the clock state while properly
|
||||||
|
handling clock speeds that are not Ftune/PTune's defaults, you can get a
|
||||||
|
full copy of the settings.
|
||||||
|
|
||||||
|
WARNING: Applying random settings with cpg_set_overclock_setting() might
|
||||||
|
damage your calculator! */
|
||||||
|
|
||||||
|
struct cpg_overclock_setting
|
||||||
|
{
|
||||||
|
uint32_t FLLFRQ, FRQCR;
|
||||||
|
uint32_t CS0BCR, CS2BCR, CS3BCR, CS5aBCR;
|
||||||
|
uint32_t CS0WCR, CS2WCR, CS3WCR, CS5aWCR;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Queries the clock setting from the hardware. */
|
||||||
|
void cpg_get_overclock_setting(struct cpg_overclock_setting *s);
|
||||||
|
|
||||||
|
/* Applies the specified overclock setting. */
|
||||||
|
void cpg_set_overclock_setting(struct cpg_overclock_setting const *s);
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Sleep functions
|
// Sleep functions
|
||||||
//---
|
//---
|
||||||
|
@ -153,27 +173,6 @@ void sleep_us_spin(uint64_t delay_us);
|
||||||
/* sleep_ms(): Sleep for a fixed duration in milliseconds */
|
/* sleep_ms(): Sleep for a fixed duration in milliseconds */
|
||||||
#define sleep_ms(delay_ms) sleep_us((delay_ms) * 1000ull)
|
#define sleep_ms(delay_ms) sleep_us((delay_ms) * 1000ull)
|
||||||
|
|
||||||
//---
|
|
||||||
// Low-level overclock functions
|
|
||||||
//
|
|
||||||
// These low-level functions directly read or write registers involved in
|
|
||||||
// setting the overclock level. Don't use them directly unless you understand
|
|
||||||
// how their interactions with the environment; instead, use clock_set_speed().
|
|
||||||
//---
|
|
||||||
|
|
||||||
struct cpg_overclock_setting
|
|
||||||
{
|
|
||||||
uint32_t FLLFRQ, FRQCR;
|
|
||||||
uint32_t CS0BCR, CS2BCR, CS3BCR, CS5aBCR;
|
|
||||||
uint32_t CS0WCR, CS2WCR, CS3WCR, CS5aWCR;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Queries the clock setting from the hardware. */
|
|
||||||
void cpg_get_overclock_setting(struct cpg_overclock_setting *s);
|
|
||||||
|
|
||||||
/* Applies the specified overclock setting. */
|
|
||||||
void cpg_set_overclock_setting(struct cpg_overclock_setting const *s);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -77,7 +77,7 @@ void cpg_get_overclock_setting(struct cpg_overclock_setting *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpg_set_overclock_setting(struct cpg_overclock_setting const *s)
|
static void cpg_low_level_set_setting(struct cpg_overclock_setting const *s)
|
||||||
{
|
{
|
||||||
if(isSH3()) {
|
if(isSH3()) {
|
||||||
SH7705_WDT.WTCNT.WRITE = 0;
|
SH7705_WDT.WTCNT.WRITE = 0;
|
||||||
|
@ -117,6 +117,30 @@ void cpg_set_overclock_setting(struct cpg_overclock_setting const *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cpg_set_overclock_setting(struct cpg_overclock_setting const *s)
|
||||||
|
{
|
||||||
|
uint32_t old_Pphi = clock_freq()->Pphi_f;
|
||||||
|
|
||||||
|
/* Wait for asynchronous tasks to complete */
|
||||||
|
gint_world_sync();
|
||||||
|
|
||||||
|
/* Disable interrupts during the change */
|
||||||
|
cpu_atomic_start();
|
||||||
|
|
||||||
|
/* Load the clock settings */
|
||||||
|
cpg_low_level_set_setting(s);
|
||||||
|
|
||||||
|
/* Determine the change in frequency for Pϕ and recompute CPG data */
|
||||||
|
cpg_compute_freq();
|
||||||
|
uint32_t new_Pphi = clock_freq()->Pphi_f;
|
||||||
|
|
||||||
|
/* Update timers' TCNT and TCOR to match the new clock speed */
|
||||||
|
void timer_rescale(uint32_t old_Pphi, uint32_t new_Pphi);
|
||||||
|
timer_rescale(old_Pphi, new_Pphi);
|
||||||
|
|
||||||
|
cpu_atomic_end();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef FX9860G
|
#ifdef FX9860G
|
||||||
|
|
||||||
static struct cpg_overclock_setting const settings_fx9860g_sh3[5] = {
|
static struct cpg_overclock_setting const settings_fx9860g_sh3[5] = {
|
||||||
|
@ -486,24 +510,5 @@ void clock_set_speed(int level)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct cpg_overclock_setting const *s = &settings[level - CLOCK_SPEED_F1];
|
struct cpg_overclock_setting const *s = &settings[level - CLOCK_SPEED_F1];
|
||||||
uint32_t old_Pphi = clock_freq()->Pphi_f;
|
|
||||||
|
|
||||||
/* Wait for asynchronous tasks to complete */
|
|
||||||
gint_world_sync();
|
|
||||||
|
|
||||||
/* Disable interrupts during the change */
|
|
||||||
cpu_atomic_start();
|
|
||||||
|
|
||||||
/* Set the clock settings */
|
|
||||||
cpg_set_overclock_setting(s);
|
cpg_set_overclock_setting(s);
|
||||||
|
|
||||||
/* Determine the change in frequency for Pϕ and recompute CPG data */
|
|
||||||
cpg_compute_freq();
|
|
||||||
uint32_t new_Pphi = clock_freq()->Pphi_f;
|
|
||||||
|
|
||||||
/* Update timers' TCNT and TCOR to match the new clock speed */
|
|
||||||
void timer_rescale(uint32_t old_Pphi, uint32_t new_Pphi);
|
|
||||||
timer_rescale(old_Pphi, new_Pphi);
|
|
||||||
|
|
||||||
cpu_atomic_end();
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue