vxKernel/src/driver/mpu/sh/sh7305/cpg/cpg.c

79 lines
1.9 KiB
C

#include <vhex/driver/mpu/sh/sh7305/cpg.h>
#include <vhex/driver.h>
#define CPG SH7305_CPG
void cpg_clock_freq(struct cpg_clock_frequency *freq)
{
/* The meaning of the PLL setting on SH7305 differs from the
documentation of SH7224; the value must not be doubled. */
int pll = CPG.FRQCR.STC + 1;
freq->PLL = pll;
/* The FLL ratio is the value of the setting, halved if SELXM=1 */
int fll = CPG.FLLFRQ.FLF;
if(CPG.FLLFRQ.SELXM == 1) fll >>= 1;
freq->FLL = fll;
/* On SH7724, the divider ratio is given by 1 / (setting + 1), but on
the SH7305 it is 1 / (2^setting + 1). */
int divb = CPG.FRQCR.BFC;
int divi = CPG.FRQCR.IFC;
int divs = CPG.FRQCR.SFC;
int divp = CPG.FRQCR.P1FC;
freq->Bphi_div = 1 << (divb + 1);
freq->Iphi_div = 1 << (divi + 1);
freq->Sphi_div = 1 << (divs + 1);
freq->Pphi_div = 1 << (divp + 1);
/* Deduce the input frequency of divider 1 */
freq->base = 32768;
if(CPG.PLLCR.FLLE) freq->base *= fll;
if(CPG.PLLCR.PLLE) freq->base *= pll;
/* And the frequency of all other input clocks */
freq->RTCCLK_f = 32768;
freq->Bphi_f = freq->base >> (divb + 1);
freq->Iphi_f = freq->base >> (divi + 1);
freq->Sphi_f = freq->base >> (divs + 1);
freq->Pphi_f = freq->base >> (divp + 1);
}
//---
// Define driver information
//---
struct cpg_ctx {
uint32_t SSCGCR;
};
/* __cpg_configure() : configure the CPG */
static void __cpg_configure(struct cpg_ctx *state)
{
(void)state;
}
/* __cpg_hsave() : save hardware information */
static void __cpg_hsave(struct cpg_ctx *state)
{
(void)state;
}
/* __cpg_hrestore() : restore hardware information */
static void __cpg_hrestore(struct cpg_ctx *state)
{
(void)state;
}
struct vhex_driver drv_cpg = {
.name = "CPG",
.hsave = (void*)&__cpg_hsave,
.hrestore = (void*)&__cpg_hrestore,
.configure = (void*)&__cpg_configure,
.state_size = sizeof(struct cpg_ctx)
};
VHEX_DECLARE_DRIVER(03, drv_cpu);