WIP - added SH3 OC functions and parameters

This commit is contained in:
Sylvain PILLOT 2022-12-06 09:02:49 +01:00
parent 12c40b2980
commit 2fe00a712d
2 changed files with 189 additions and 78 deletions

View File

@ -1,4 +1,4 @@
/---
//---
// gint:mpu:wdt - Watchdog Timer
//---

View File

@ -14,10 +14,15 @@
#include <gint/hardware.h>
#include <gint/mpu/cpg.h>
#include <gint/mpu/bsc.h>
#include <gint/mpu/wdt.h>
#define CPG SH7305_CPG
#define BSC SH7305_BSC
#define CPGSH3 SH7705_CPG
#define BSCSH3 SH7705_BSC
#define WDTSH3 SH7705_WDT
//---
// Low-level clock speed access
//---
@ -25,67 +30,111 @@
#define SDMR3_CL2 ((volatile uint8_t *)0xFEC15040)
#define SDMR3_CL3 ((volatile uint8_t *)0xFEC15060)
void cpg_get_overclock_setting(struct cpg_overclock_setting *s)
{
if(!isSH4())
return;
s->FLLFRQ = CPG.FLLFRQ.lword;
s->FRQCR = CPG.FRQCR.lword;
s->CS0BCR = BSC.CS0BCR.lword;
s->CS0WCR = BSC.CS0WCR.lword;
s->CS2BCR = BSC.CS2BCR.lword;
s->CS2WCR = BSC.CS2WCR.lword;
s->CS3BCR = BSC.CS3BCR.lword;
s->CS3WCR = BSC.CS3WCR.lword;
s->CS5aBCR = BSC.CS5ABCR.lword;
s->CS5aWCR = BSC.CS5AWCR.lword;
}
void cpg_set_overclock_setting(struct cpg_overclock_setting const *s)
{
if(!isSH4())
return;
BSC.CS0WCR.WR = 11; /* 18 cycles */
CPG.FLLFRQ.lword = s->FLLFRQ;
CPG.FRQCR.lword = s->FRQCR;
CPG.FRQCR.KICK = 1;
while(CPG.LSTATS != 0) {}
BSC.CS0BCR.lword = s->CS0BCR;
BSC.CS0WCR.lword = s->CS0WCR;
BSC.CS2BCR.lword = s->CS2BCR;
BSC.CS2WCR.lword = s->CS2WCR;
BSC.CS3BCR.lword = s->CS3BCR;
BSC.CS3WCR.lword = s->CS3WCR;
if(BSC.CS3WCR.A3CL == 1)
*SDMR3_CL2 = 0;
else
*SDMR3_CL3 = 0;
BSC.CS5ABCR.lword = s->CS5aBCR;
BSC.CS5AWCR.lword = s->CS5aWCR;
}
//---
// Predefined clock speeds
//---
#define PLL_32x 0b011111
#define PLL_26x 0b011001
#define PLL_16x 0b001111
#define DIV_2 0
#define DIV_4 1
#define DIV_8 2
#define DIV_16 3
#define DIV_32 4
// for SH4 based calculators
#define SH4_PLL_32x 0b011111
#define SH4_PLL_26x 0b011001
#define SH4_PLL_16x 0b001111
#define SH4_DIV_2 0
#define SH4_DIV_4 1
#define SH4_DIV_8 2
#define SH4_DIV_16 3
#define SH4_DIV_32 4
// for SH3 based calculators
#define SH3_PLL_1x 0 //0b0000 // x1
#define SH3_PLL_2x 1 //0b0001 // x2
#define SH3_PLL_3x 2 //0b0010 // x3
#define SH3_PLL_4x 3 //0b0011 // x4
#define SH3_DIV_1 0 //0b0000 // 1/1
#define SH3_DIV_2 1 //0b0001 // 1/2
#define SH3_DIV_3 2 //0b0010 // 1/3
#define SH3_DIV_4 3 //0b0011 // 1/4
void cpg_get_overclock_setting(struct cpg_overclock_setting *s)
{
if(isSH3())
{
s->FLLFRQ = 0xFFFFFFF; // not used for SH3 MPUs
s->FRQCR = CPGSH3.FRQCR.word;
s->CS0BCR = BSCSH3.CS0BCR.lword;
s->CS0WCR = BSCSH3.CS0WCR.lword;
s->CS2BCR = BSCSH3.CS2BCR.lword;
s->CS2WCR = BSCSH3.CS2WCR.lword;
s->CS3BCR = BSCSH3.CS3BCR.lword;
s->CS3WCR = BSCSH3.CS3WCR.lword;
s->CS5aBCR = BSCSH3.CS5ABCR.lword;
s->CS5aWCR = BSCSH3.CS5AWCR.lword;
}
else if(isSH4())
{
s->FLLFRQ = CPG.FLLFRQ.lword;
s->FRQCR = CPG.FRQCR.lword;
s->CS0BCR = BSC.CS0BCR.lword;
s->CS0WCR = BSC.CS0WCR.lword;
s->CS2BCR = BSC.CS2BCR.lword;
s->CS2WCR = BSC.CS2WCR.lword;
s->CS3BCR = BSC.CS3BCR.lword;
s->CS3WCR = BSC.CS3WCR.lword;
s->CS5aBCR = BSC.CS5ABCR.lword;
s->CS5aWCR = BSC.CS5AWCR.lword;
}
else return;
}
void cpg_set_overclock_setting(struct cpg_overclock_setting const *s)
{
if(isSH3())
{
WDTSH3.WTCNT.WRITE = 0;
WDTSH3.WTCNT.WRITE = 0x65;
CPGSH3.FRQCR.word = 0x1000 | s->FRQCR;
BSCSH3.CS0BCR.lword = s->CS0BCR;
BSCSH3.CS0WCR.lword = s->CS0WCR;
BSCSH3.CS2BCR.lword = s->CS2BCR;
BSCSH3.CS2WCR.lword = s->CS2WCR;
BSCSH3.CS3BCR.lword = s->CS3BCR;
BSCSH3.CS3WCR.lword = s->CS3WCR;
BSCSH3.CS5ABCR.lword = s->CS5aBCR;
BSCSH3.CS5AWCR.lword = s->CS5aWCR;
}
else if(isSH4())
{
BSC.CS0WCR.WR = 11; /* 18 cycles */
CPG.FLLFRQ.lword = s->FLLFRQ;
CPG.FRQCR.lword = s->FRQCR;
CPG.FRQCR.KICK = 1;
while(CPG.LSTATS != 0) {}
BSC.CS0BCR.lword = s->CS0BCR;
BSC.CS0WCR.lword = s->CS0WCR;
BSC.CS2BCR.lword = s->CS2BCR;
BSC.CS2WCR.lword = s->CS2WCR;
BSC.CS3BCR.lword = s->CS3BCR;
BSC.CS3WCR.lword = s->CS3WCR;
if(BSC.CS3WCR.A3CL == 1)
*SDMR3_CL2 = 0;
else
*SDMR3_CL3 = 0;
BSC.CS5ABCR.lword = s->CS5aBCR;
BSC.CS5AWCR.lword = s->CS5aWCR;
}
else return;
}
/*settings for the fxcg50 / G90+E*/
static struct cpg_overclock_setting settings_cg50[5] = {
static struct cpg_overclock_setting settings_fxcg50[5] = {
/* CLOCK_SPEED_F1 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = 0x0F011112,
@ -99,7 +148,7 @@ static struct cpg_overclock_setting settings_cg50[5] = {
.CS5aWCR = 0x000203C1 },
/* CLOCK_SPEED_F2 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = (PLL_16x<<24)+(DIV_4<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV_8,
.FRQCR = (SH4_PLL_16x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_8,
.CS0BCR = 0x24920400,
.CS2BCR = 0x24923400,
.CS3BCR = 0x24924400,
@ -110,7 +159,7 @@ static struct cpg_overclock_setting settings_cg50[5] = {
.CS5aWCR = 0x000203C1 },
/* CLOCK_SPEED_F3 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = (PLL_26x<<24)+(DIV_4<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV_8,
.FRQCR = (SH4_PLL_26x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_8,
.CS0BCR = 0x24920400,
.CS2BCR = 0x24923400,
.CS3BCR = 0x24924400,
@ -121,7 +170,7 @@ static struct cpg_overclock_setting settings_cg50[5] = {
.CS5aWCR = 0x000203C1 },
/* CLOCK_SPEED_F4 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = (PLL_32x<<24)+(DIV_2<<20)+(DIV_4<<12)+(DIV_8<<8)+DIV_16,
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_2<<20)+(SH4_DIV_4<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
.CS0BCR = 0x24920400,
.CS2BCR = 0x24923400,
.CS3BCR = 0x24924400,
@ -132,7 +181,7 @@ static struct cpg_overclock_setting settings_cg50[5] = {
.CS5aWCR = 0x000203C1 },
/* CLOCK_SPEED_F5 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = (PLL_26x<<24)+(DIV_2<<20)+(DIV_4<<12)+(DIV_4<<8)+DIV_8,
.FRQCR = (SH4_PLL_26x<<24)+(SH4_DIV_2<<20)+(SH4_DIV_4<<12)+(SH4_DIV_4<<8)+SH4_DIV_8,
.CS0BCR = 0x24920400,
.CS2BCR = 0x24923400,
.CS3BCR = 0x24924400,
@ -144,7 +193,7 @@ static struct cpg_overclock_setting settings_cg50[5] = {
};
/*settings for the prizm fxcg10/20*/
static struct cpg_overclock_setting settings_cg20[5] = {
static struct cpg_overclock_setting settings_prizm[5] = {
/* CLOCK_SPEED_F1 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = 0x0F102203,
@ -158,7 +207,7 @@ static struct cpg_overclock_setting settings_cg20[5] = {
.CS5aWCR = 0x00010240 },
/* CLOCK_SPEED_F2 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = (PLL_32x<<24)+(DIV_8<<20)+(DIV_16<<12)+(DIV_16<<8)+DIV_32,
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_8<<20)+(SH4_DIV_16<<12)+(SH4_DIV_16<<8)+SH4_DIV_32,
.CS0BCR = 0x04900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -169,7 +218,7 @@ static struct cpg_overclock_setting settings_cg20[5] = {
.CS5aWCR = 0x00010240 },
/* CLOCK_SPEED_F3 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = (PLL_32x<<24)+(DIV_4<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV_32,
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_32,
.CS0BCR = 0x24900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -180,7 +229,7 @@ static struct cpg_overclock_setting settings_cg20[5] = {
.CS5aWCR = 0x00010240 },
/* CLOCK_SPEED_F4 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = (PLL_32x<<24)+(DIV_4<<20)+(DIV_4<<12)+(DIV_4<<8)+DIV_32,
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_4<<12)+(SH4_DIV_4<<8)+SH4_DIV_32,
.CS0BCR = 0x44900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -191,7 +240,7 @@ static struct cpg_overclock_setting settings_cg20[5] = {
.CS5aWCR = 0x00010240 },
/* CLOCK_SPEED_F5 */
{ .FLLFRQ = 0x00004000 + 900,
.FRQCR = (PLL_26x<<24)+(DIV_2<<20)+(DIV_4<<12)+(DIV_4<<8)+DIV_16,
.FRQCR = (SH4_PLL_26x<<24)+(SH4_DIV_2<<20)+(SH4_DIV_4<<12)+(SH4_DIV_4<<8)+SH4_DIV_16,
.CS0BCR = 0x34900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -202,8 +251,68 @@ static struct cpg_overclock_setting settings_cg20[5] = {
.CS5aWCR = 0x00010240 },
};
/*settings for the fx9860G SH3 based*/
static struct cpg_overclock_setting settings_fx9860g_sh3[5] = {
/* CLOCK_SPEED_F1 */
{ .FLLFRQ = 0xFFFFFFFF, // not used for SH3 MPUs
.FRQCR = 0x1001,
.CS0BCR = 0x02480400,
.CS2BCR = 0x02483400,
.CS3BCR = 0x36DB0600,
.CS5aBCR = 0x224A0200,
.CS0WCR = 0x00000140,
.CS2WCR = 0x00000140,
.CS3WCR = 0x00000500,
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F2 */
{ .FLLFRQ = 0xFFFFFFFF, // not used for SH3 MPUs
.FRQCR = (SH3_PLL_2x<<8)+(SH3_DIV_1<<4)+SH3_DIV_2,
.CS0BCR = 0x02480400,
.CS2BCR = 0x02483400,
.CS3BCR = 0x36DB0600,
.CS5aBCR = 0x224A0200,
.CS0WCR = 0x00000140,
.CS2WCR = 0x00000140,
.CS3WCR = 0x00000500,
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F3 */
{ .FLLFRQ = 0xFFFFFFFF, // not used for SH3 MPUs
.FRQCR = (SH3_PLL_3x<<8)+(SH3_DIV_1<<4)+SH3_DIV_3,
.CS0BCR = 0x02480400,
.CS2BCR = 0x02483400,
.CS3BCR = 0x36DB0600,
.CS5aBCR = 0x224A0200,
.CS0WCR = 0x00000140,
.CS2WCR = 0x00000140,
.CS3WCR = 0x00000500,
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F4 */
{ .FLLFRQ = 0xFFFFFFFF, // not used for SH3 MPUs
.FRQCR = (SH3_PLL_4x<<8)+(SH3_DIV_1<<4)+SH3_DIV_4,
.CS0BCR = 0x02480400,
.CS2BCR = 0x02483400,
.CS3BCR = 0x36DB0600,
.CS5aBCR = 0x224A0200,
.CS0WCR = 0x00000140,
.CS2WCR = 0x00000140,
.CS3WCR = 0x00000500,
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F5 */
{ .FLLFRQ = 0xFFFFFFFF, // not used for SH3 MPUs
.FRQCR = (SH3_PLL_4x<<8)+(SH3_DIV_1<<4)+SH3_DIV_4,
.CS0BCR = 0x02480400,
.CS2BCR = 0x02483400,
.CS3BCR = 0x36DB0600,
.CS5aBCR = 0x224A0200,
.CS0WCR = 0x000000C0,
.CS2WCR = 0x000100C0,
.CS3WCR = 0x00000500,
.CS5aWCR = 0x00000D41 },
};
/*settings for the fx9860GII*/
static struct cpg_overclock_setting settings_fx9860gII[5] = {
static struct cpg_overclock_setting settings_fx9860g_sh4[5] = {
/* CLOCK_SPEED_F1 */
{ .FLLFRQ = 0x00004384,
.FRQCR = 0x0F202203,
@ -217,7 +326,7 @@ static struct cpg_overclock_setting settings_fx9860gII[5] = {
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F2 */
{ .FLLFRQ = 0x00004384,
.FRQCR = PLL_16x<<24)+(DIV_4<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV16,
.FRQCR = (SH4_PLL_16x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
.CS0BCR = 0x24920400,
.CS2BCR = 0x24923400,
.CS3BCR = 0x24924400,
@ -228,7 +337,7 @@ static struct cpg_overclock_setting settings_fx9860gII[5] = {
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F3 */
{ .FLLFRQ = 0x00004384,
.FRQCR = PLL_16x<<24)+(DIV_8<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV16,
.FRQCR = (SH4_PLL_16x<<24)+(SH4_DIV_8<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
.CS0BCR = 0x04900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -239,7 +348,7 @@ static struct cpg_overclock_setting settings_fx9860gII[5] = {
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F4 */
{ .FLLFRQ = 0x00004384,
.FRQCR = (PLL_32x<<24)+(DIV_4<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV16,
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
.CS0BCR = 0x04900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -250,7 +359,7 @@ static struct cpg_overclock_setting settings_fx9860gII[5] = {
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F5 */
{ .FLLFRQ = 0x00004384,
.FRQCR = (PLL_32x<<24)+(DIV_2<<20)+(DIV_4<<12)+(DIV_4<<8)+DIV16,
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_2<<20)+(SH4_DIV_4<<12)+(SH4_DIV_4<<8)+SH4_DIV_16,
.CS0BCR = 0x14900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -262,7 +371,7 @@ static struct cpg_overclock_setting settings_fx9860gII[5] = {
};
/*settings for the fx9860GII-2 / G35+EII*/
static struct cpg_overclock_setting settings_fx9860gII2[5] = {
static struct cpg_overclock_setting settings_g35pe2[5] = {
/* CLOCK_SPEED_F1 */
{ .FLLFRQ = 0x00004384,
.FRQCR = 0x0F202203,
@ -276,7 +385,7 @@ static struct cpg_overclock_setting settings_fx9860gII2[5] = {
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F2 */
{ .FLLFRQ = 0x00004384,
.FRQCR = (PLL_16x<<24)+(DIV_4<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV16,
.FRQCR = (SH4_PLL_16x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
.CS0BCR = 0x24920400,
.CS2BCR = 0x24923400,
.CS3BCR = 0x24924400,
@ -287,7 +396,7 @@ static struct cpg_overclock_setting settings_fx9860gII2[5] = {
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F3 */
{ .FLLFRQ = 0x00004384,
.FRQCR = (PLL_16x<<24)+(DIV_8<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV16,
.FRQCR = (SH4_PLL_16x<<24)+(SH4_DIV_8<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
.CS0BCR = 0x04900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -298,7 +407,7 @@ static struct cpg_overclock_setting settings_fx9860gII2[5] = {
.CS5aWCR = 0x00000D41 },
/* CLOCK_SPEED_F4 */
{ .FLLFRQ = 0x00004384,
.FRQCR = (PLL_32x<<24)+(DIV_4<<20)+(DIV_8<<12)+(DIV_8<<8)+DIV16,
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
.CS0BCR = 0x04900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -309,7 +418,7 @@ static struct cpg_overclock_setting settings_fx9860gII2[5] = {
.CS5aWCR = 0x00031340 },
/* CLOCK_SPEED_F5 */
{ .FLLFRQ = 0x00004384,
.FRQCR = (PLL_32x<<24)+(DIV_2<<20)+(DIV_4<<12)+(DIV_8<<8)+DIV16,
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_2<<20)+(SH4_DIV_4<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
.CS0BCR = 0x14900400,
.CS2BCR = 0x04903400,
.CS3BCR = 0x24924400,
@ -323,13 +432,15 @@ static struct cpg_overclock_setting settings_fx9860gII2[5] = {
static struct cpg_overclock_setting *get_settings(void)
{
if(gint[HWCALC] == HWCALC_FXCG50)
return settings_cg50;
return settings_fxcg50;
if(gint[HWCALC] == HWCALC_PRIZM)
return settings_cg20;
return settings_prizm;
if(gint[HWCALC] == HWCALC_G35PE2)
return settings_fx9860gII2;
return settings_g35pe2;
if(gint[HWCALC] == HWCALC_FX9860G_SH4)
return settings_fx9860gII;
return settings_fx9860g_sh4;
if(gint[HWCALC] == HWCALC_FX9860G_SH3)
return settings_fx9860g_sh3;
return NULL;
}