|
- #include <stdint.h>
- #include "imxrt.h"
- #include "wiring.h"
- #include "debug/printf.h"
-
-
-
- volatile uint32_t F_CPU_ACTUAL = 396000000;
- volatile uint32_t F_BUS_ACTUAL = 132000000;
-
-
-
-
-
- #define OVERCLOCK_STEPSIZE 28000000
- #define OVERCLOCK_MAX_VOLT 1300
-
-
-
- uint32_t set_arm_clock(uint32_t frequency);
-
-
-
-
-
-
-
-
-
- uint32_t set_arm_clock(uint32_t frequency)
- {
- uint32_t cbcdr = CCM_CBCDR;
- uint32_t cbcmr = CCM_CBCMR;
- uint32_t dcdc = DCDC_REG3;
-
-
- uint32_t voltage = 1150;
- if (frequency > 528000000) {
- voltage = 1250;
- #if defined(OVERCLOCK_STEPSIZE) && defined(OVERCLOCK_MAX_VOLT)
- if (frequency > 600000000) {
- voltage += ((frequency - 600000000) / OVERCLOCK_STEPSIZE) * 25;
- if (voltage > OVERCLOCK_MAX_VOLT) voltage = OVERCLOCK_MAX_VOLT;
- }
- #endif
- } else if (frequency <= 24000000) {
- voltage = 950;
- }
-
-
- CCM_CCGR6 |= CCM_CCGR6_DCDC(CCM_CCGR_ON);
- if ((dcdc & DCDC_REG3_TRG_MASK) < DCDC_REG3_TRG((voltage - 800) / 25)) {
- printf("Increasing voltage to %u mV\n", voltage);
- dcdc &= ~DCDC_REG3_TRG_MASK;
- dcdc |= DCDC_REG3_TRG((voltage - 800) / 25);
- DCDC_REG3 = dcdc;
- while (!(DCDC_REG0 & DCDC_REG0_STS_DC_OK)) ;
- }
-
- if (!(cbcdr & CCM_CBCDR_PERIPH_CLK_SEL)) {
- printf("need to switch to alternate clock during reconfigure of ARM PLL\n");
- const uint32_t need1s = CCM_ANALOG_PLL_USB1_ENABLE | CCM_ANALOG_PLL_USB1_POWER |
- CCM_ANALOG_PLL_USB1_LOCK | CCM_ANALOG_PLL_USB1_EN_USB_CLKS;
- uint32_t sel, div;
- if ((CCM_ANALOG_PLL_USB1 & need1s) == need1s) {
- printf("USB PLL is running, so we can use 120 MHz\n");
- sel = 0;
- div = 3;
- } else {
- printf("USB PLL is off, use 24 MHz crystal\n");
- sel = 1;
- div = 0;
- }
- if ((cbcdr & CCM_CBCDR_PERIPH_CLK2_PODF_MASK) != CCM_CBCDR_PERIPH_CLK2_PODF(div)) {
-
- cbcdr &= ~CCM_CBCDR_PERIPH_CLK2_PODF_MASK;
- cbcdr |= CCM_CBCDR_PERIPH_CLK2_PODF(div);
- CCM_CBCDR = cbcdr;
- }
- if ((cbcmr & CCM_CBCMR_PERIPH_CLK2_SEL_MASK) != CCM_CBCMR_PERIPH_CLK2_SEL(sel)) {
-
- cbcmr &= ~CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
- cbcmr |= CCM_CBCMR_PERIPH_CLK2_SEL(sel);
- CCM_CBCMR = cbcmr;
- while (CCM_CDHIPR & CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY) ;
- }
-
- cbcdr |= CCM_CBCDR_PERIPH_CLK_SEL;
- CCM_CBCDR = cbcdr;
- while (CCM_CDHIPR & CCM_CDHIPR_PERIPH_CLK_SEL_BUSY) ;
- } else {
- printf("already running from PERIPH_CLK2, safe to mess with ARM PLL\n");
- }
-
-
-
-
- uint32_t div_arm = 1;
- uint32_t div_ahb = 1;
- while (frequency * div_arm * div_ahb < 648000000) {
- if (div_arm < 8) {
- div_arm = div_arm + 1;
- } else {
- if (div_ahb < 5) {
- div_ahb = div_ahb + 1;
- div_arm = 1;
- } else {
- break;
- }
- }
- }
- uint32_t mult = (frequency * div_arm * div_ahb + 6000000) / 12000000;
- if (mult > 108) mult = 108;
- if (mult < 54) mult = 54;
- printf("Freq: 12 MHz * %u / %u / %u\n", mult, div_arm, div_ahb);
- frequency = mult * 12000000 / div_arm / div_ahb;
-
- printf("ARM PLL=%x\n", CCM_ANALOG_PLL_ARM);
- const uint32_t arm_pll_mask = CCM_ANALOG_PLL_ARM_LOCK | CCM_ANALOG_PLL_ARM_BYPASS |
- CCM_ANALOG_PLL_ARM_ENABLE | CCM_ANALOG_PLL_ARM_POWERDOWN |
- CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK;
- if ((CCM_ANALOG_PLL_ARM & arm_pll_mask) != (CCM_ANALOG_PLL_ARM_LOCK
- | CCM_ANALOG_PLL_ARM_ENABLE | CCM_ANALOG_PLL_ARM_DIV_SELECT(mult))) {
- printf("ARM PLL needs reconfigure\n");
- CCM_ANALOG_PLL_ARM = CCM_ANALOG_PLL_ARM_POWERDOWN;
-
- CCM_ANALOG_PLL_ARM = CCM_ANALOG_PLL_ARM_ENABLE
- | CCM_ANALOG_PLL_ARM_DIV_SELECT(mult);
- while (!(CCM_ANALOG_PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK)) ;
- printf("ARM PLL=%x\n", CCM_ANALOG_PLL_ARM);
- } else {
- printf("ARM PLL already running at required frequency\n");
- }
-
- if ((CCM_CACRR & CCM_CACRR_ARM_PODF_MASK) != (div_arm - 1)) {
- CCM_CACRR = CCM_CACRR_ARM_PODF(div_arm - 1);
- while (CCM_CDHIPR & CCM_CDHIPR_ARM_PODF_BUSY) ;
- }
-
- if ((cbcdr & CCM_CBCDR_AHB_PODF_MASK) != CCM_CBCDR_AHB_PODF(div_ahb - 1)) {
- cbcdr &= ~CCM_CBCDR_AHB_PODF_MASK;
- cbcdr |= CCM_CBCDR_AHB_PODF(div_ahb - 1);
- CCM_CBCDR = cbcdr;
- while (CCM_CDHIPR & CCM_CDHIPR_AHB_PODF_BUSY);
- }
-
- uint32_t div_ipg = (frequency + 149999999) / 150000000;
- if (div_ipg > 4) div_ipg = 4;
- if ((cbcdr & CCM_CBCDR_IPG_PODF_MASK) != (CCM_CBCDR_IPG_PODF(div_ipg - 1))) {
- cbcdr &= ~CCM_CBCDR_IPG_PODF_MASK;
- cbcdr |= CCM_CBCDR_IPG_PODF(div_ipg - 1);
-
- CCM_CBCDR = cbcdr;
- }
-
- cbcdr &= ~CCM_CBCDR_PERIPH_CLK_SEL;
- CCM_CBCDR = cbcdr;
- while (CCM_CDHIPR & CCM_CDHIPR_PERIPH_CLK_SEL_BUSY) ;
-
- F_CPU_ACTUAL = frequency;
- F_BUS_ACTUAL = frequency / div_ipg;
-
- printf("New Frequency: ARM=%u, IPG=%u\n", frequency, frequency / div_ipg);
-
-
- if ((dcdc & DCDC_REG3_TRG_MASK) > DCDC_REG3_TRG((voltage - 800) / 25)) {
- printf("Decreasing voltage to %u mV\n", voltage);
- dcdc &= ~DCDC_REG3_TRG_MASK;
- dcdc |= DCDC_REG3_TRG((voltage - 800) / 25);
- DCDC_REG3 = dcdc;
- while (!(DCDC_REG0 & DCDC_REG0_STS_DC_OK)) ;
- }
-
- return frequency;
- }
|