/* clock startup for Jellybean with Lemondrop attached Configure PLL1 to max speed (204MHz). Note: PLL1 clock is used by M4/M0 core, Peripheral, APB1. */ void cpu_clock_init(void) { /* use IRC as clock source for APB1 (including I2C0) */ CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_IRC); /* use IRC as clock source for APB3 */ CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_IRC); //FIXME a lot of the details here should be in a CGU driver /* set xtal oscillator to low frequency mode */ CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_HF_MASK; /* power on the oscillator and wait until stable */ CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_ENABLE_MASK; /* Wait about 100us after Crystal Power ON */ delay(WAIT_CPU_CLOCK_INIT_DELAY); /* use XTAL_OSC as clock source for BASE_M4_CLK (CPU) */ CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_XTAL) | CGU_BASE_M4_CLK_AUTOBLOCK(1)); /* use XTAL_OSC as clock source for APB1 */ CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK(1) | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_XTAL); /* use XTAL_OSC as clock source for APB3 */ CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_AUTOBLOCK(1) | CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_XTAL); cpu_clock_pll1_low_speed(); /* use PLL1 as clock source for BASE_M4_CLK (CPU) */ CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1) | CGU_BASE_M4_CLK_AUTOBLOCK(1)); /* use XTAL_OSC as clock source for PLL0USB */ CGU_PLL0USB_CTRL = CGU_PLL0USB_CTRL_PD(1) | CGU_PLL0USB_CTRL_AUTOBLOCK(1) | CGU_PLL0USB_CTRL_CLK_SEL(CGU_SRC_XTAL); while (CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK_MASK); /* configure PLL0USB to produce 480 MHz clock from 12 MHz XTAL_OSC */ /* Values from User Manual v1.4 Table 94, for 12MHz oscillator. */ CGU_PLL0USB_MDIV = 0x06167FFA; CGU_PLL0USB_NP_DIV = 0x00302062; CGU_PLL0USB_CTRL |= (CGU_PLL0USB_CTRL_PD(1) | CGU_PLL0USB_CTRL_DIRECTI(1) | CGU_PLL0USB_CTRL_DIRECTO(1) | CGU_PLL0USB_CTRL_CLKEN(1)); /* power on PLL0USB and wait until stable */ CGU_PLL0USB_CTRL &= ~CGU_PLL0USB_CTRL_PD_MASK; while (!(CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK_MASK)); /* use PLL0USB as clock source for USB0 */ CGU_BASE_USB0_CLK = CGU_BASE_USB0_CLK_AUTOBLOCK(1) | CGU_BASE_USB0_CLK_CLK_SEL(CGU_SRC_PLL0USB); /* use PLL0USB as clock source for IDIVA */ /* divide by 4 */ CGU_IDIVA_CTRL = CGU_IDIVA_CTRL_IDIV(3) | CGU_IDIVA_CTRL_AUTOBLOCK(1) | CGU_IDIVA_CTRL_CLK_SEL(CGU_SRC_PLL0USB); /* use IDIVA as clock source for IDIVB */ /* divide by 2 */ CGU_IDIVB_CTRL = CGU_IDIVB_CTRL_IDIV(1) | CGU_IDIVB_CTRL_AUTOBLOCK(1) | CGU_IDIVA_CTRL_CLK_SEL(CGU_SRC_IDIVA); /* Use IDIVB for CLKOUT */ CGU_BASE_OUT_CLK = CGU_BASE_OUT_CLK_AUTOBLOCK(1) | CGU_BASE_OUT_CLK_CLK_SEL(CGU_SRC_IDIVB); /* use IDIVB as clock source for USB1 */ CGU_BASE_USB1_CLK = CGU_BASE_USB1_CLK_AUTOBLOCK(1) | CGU_BASE_USB1_CLK_CLK_SEL(CGU_SRC_IDIVB); /* Switch peripheral clock over to use PLL1 (204MHz) */ CGU_BASE_PERIPH_CLK = CGU_BASE_PERIPH_CLK_AUTOBLOCK(1) | CGU_BASE_PERIPH_CLK_CLK_SEL(CGU_SRC_PLL1); /* Switch APB1 clock over to use PLL1 (204MHz) */ CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK(1) | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1); /* Switch APB3 clock over to use PLL1 (204MHz) */ CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_AUTOBLOCK(1) | CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_PLL1); CGU_BASE_SSP0_CLK = CGU_BASE_SSP0_CLK_AUTOBLOCK(1) | CGU_BASE_SSP0_CLK_CLK_SEL(CGU_SRC_PLL1); CGU_BASE_SSP1_CLK = CGU_BASE_SSP1_CLK_AUTOBLOCK(1) | CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1); }
void sys_clock_samplerate(const airspy_sys_samplerate_t* const pt_airspy_sys_samplerate) { uint32_t pll0audio_mdiv; uint32_t pll0audio_npdiv; uint32_t pll0audio_ctrl_flags; pll0audio_mdiv = pt_airspy_sys_samplerate->pll0audio_mdiv; pll0audio_npdiv = pt_airspy_sys_samplerate->pll0audio_npdiv; pll0audio_ctrl_flags = pt_airspy_sys_samplerate->pll0audio_ctrl_flags; /* Power Down ADCHS Clock */ CGU_BASE_ADCHS_CLK = CGU_BASE_ADCHS_CLK_PD; /* Power Down PLL0AUDIO */ CGU_PLL0AUDIO_CTRL = CGU_PLL0AUDIO_CTRL_PD; /* Power Down IDIVB */ CGU_IDIVB_CTRL = CGU_IDIVB_CTRL_PD; if( (pll0audio_mdiv == 0) && (pll0audio_npdiv == 0) ) { if( pt_airspy_sys_samplerate->idivb == 0) { /* Do not use IDIVB direct connection CGU_SRC_GP_CLKIN to ACHS_CLK */ /* ADCHS Clock CGU_BASE_ADCHS_CLK => Clock Source CLK_IN */ CGU_BASE_ADCHS_CLK = CGU_BASE_ADCHS_CLK_AUTOBLOCK | CGU_BASE_ADCHS_CLK_CLK_SEL(CGU_SRC_GP_CLKIN); }else { /* ADCHS Clock CGU_BASE_ADCHS_CLK => Clock Source IDIVB */ /* Use CGU_SRC_GP_CLKIN as clock source for IDIVB */ CGU_IDIVB_CTRL = CGU_IDIVB_CTRL_IDIV(pt_airspy_sys_samplerate->idivb) | CGU_IDIVB_CTRL_AUTOBLOCK | CGU_IDIVB_CTRL_CLK_SEL(CGU_SRC_GP_CLKIN); /* ADCHS Clock CGU_BASE_ADCHS_CLK => Clock Source CLK_IDIVB */ CGU_BASE_ADCHS_CLK = CGU_BASE_ADCHS_CLK_AUTOBLOCK | CGU_BASE_ADCHS_CLK_CLK_SEL(CGU_SRC_IDIVB); } }else { /* ADCHS Clock CGU_BASE_ADCHS_CLK => Clock Source PLL0AUDIO */ /* Use CGU_SRC_GP_CLKIN as clock source for PLL0AUDIO */ CGU_PLL0AUDIO_CTRL = CGU_PLL0AUDIO_CTRL_PD | CGU_PLL0AUDIO_CTRL_AUTOBLOCK | CGU_PLL0AUDIO_CTRL_CLK_SEL(CGU_SRC_GP_CLKIN); while (CGU_PLL0AUDIO_STAT & CGU_PLL0AUDIO_STAT_LOCK); /* configure PLL0AUDIO to produce xxMHz */ /* PLL Register settings (SEL_EXT=1): Mdec=31=PLL0_MDIV[16:0] => CGU_PLL0AUDIO_MDIV Ndec=0=PLL0_NPDIV[21:12], Pdec=21=PLL0_NPDIV[6:0] => CGU_PLL0AUDIO_NP_DIV */ CGU_PLL0AUDIO_MDIV = pll0audio_mdiv; CGU_PLL0AUDIO_NP_DIV = pll0audio_npdiv; CGU_PLL0AUDIO_CTRL |= (CGU_PLL0AUDIO_CTRL_PD | pll0audio_ctrl_flags | CGU_PLL0AUDIO_CTRL_SEL_EXT | CGU_PLL0AUDIO_CTRL_CLKEN); /* power on PLL0AUDIO and wait until stable */ CGU_PLL0AUDIO_CTRL &= ~CGU_PLL0AUDIO_CTRL_PD; while (!(CGU_PLL0AUDIO_STAT & CGU_PLL0AUDIO_STAT_LOCK)); /* use PLL0AUDIO as clock source for ADCHS */ CGU_BASE_ADCHS_CLK = CGU_BASE_ADCHS_CLK_AUTOBLOCK | CGU_BASE_ADCHS_CLK_CLK_SEL(CGU_SRC_PLL0AUDIO); } }