I am trying to disable unused PLLs on an iMX6SL CPU. The following code should:
- Set the CPU Clock to 396MHz (From BareMetal SDK)
- Configure clock defaults (From BareMetal SDK)
- Disable 4 of the PLLs that (I think that) I am not using.
This causes some weired behavior. The code sometimes locks up after turning the PLLs off. Am I missing something here? I think that I have gated the proper clocks first. Could the JTAG clock be affected by me disabling the PLLs? Do I need some delay after disabling the PLLs?
Here is a snippit of code from my init function:
// Use the SDK to set the root ARM clock PLL to 396MHz
// Note: This calls pmu_init();
int freq = cpu_workpoint_set(CPU_WORKPOINT_400MHZ);
assert (freq != 0);
* Configure Clocks
// First Initialize clock sources, dividers, with the SDK provided function
* This code causes a fault that is not well understood!!!!
* If this code is executed then the code will jump in to the weeds.
* Not every time, but if the code is run and then stopped with the debugger 2 or 3 times then
* it will fail with PC = to some "random" location.
// Gate unused clocks to save power
// Note that some clocks are gated here that will be turned on later via individual drivers
HW_CCM_CCGR0_WR(0xffffffff); // CPUDBG, AIPS
HW_CCM_CCGR1_WR(0xf30C0f3f); // GPU, GPT, ESAI, EPIT2/1, ECSPI4-1
HW_CCM_CCGR2_WR(0xFFFFF03F); // IPSYNC?, IPMUX, IOMUX, OCOTP, I2C3-1
HW_CCM_CCGR3_WR(0xfffff000); // OCRAM, MMDC, EPDC, LCDIF, PXP, CSI
HW_CCM_CCGR4_WR(0x0000ffff); // RAW NAND, PWM4-1, PL301?,
HW_CCM_CCGR5_WR(0xf0030fcf); // UART, SSI3-1, SPDIF, SPBA, SDMA, 100MHz, ROM CLK
HW_CCM_CCGR6_WR(0xffff0c00); // VPU, VDOA, EIM (SLOW), USDHC4-1, USB OH3
// Disable unused PLLs after the downstream peripherals have been disabled
// Note: The *_ENABLED bit should be left asserted even after the PLL is SHUTDOWN
HW_CCM_ANALOG_PLL_ENET_SET(BM_CCM_ANALOG_PLL_ENET_BYPASS); // Bypass the PLL
HW_CCM_ANALOG_PLL_ENET_SET(BM_CCM_ANALOG_PLL_ENET_POWERDOWN); // Power off the PLL
HW_CCM_ANALOG_PLL_USB2_SET(BM_CCM_ANALOG_PLL_USB2_BYPASS); // Bypass the PLL
HW_CCM_ANALOG_PLL_USB2_CLR(BM_CCM_ANALOG_PLL_USB2_POWER); // USB Uses a POWER bit instead of POWERDOWN
HW_CCM_ANALOG_PLL_AUDIO_SET(BM_CCM_ANALOG_PLL_AUDIO_BYPASS); // Bypass the PLL
HW_CCM_ANALOG_PLL_AUDIO_SET(BM_CCM_ANALOG_PLL_AUDIO_POWERDOWN); // Power off the PLL
HW_CCM_ANALOG_PLL_VIDEO_SET(BM_CCM_ANALOG_PLL_VIDEO_BYPASS); // Bypass the PLL
HW_CCM_ANALOG_PLL_VIDEO_SET(BM_CCM_ANALOG_PLL_VIDEO_POWERDOWN); // Power off the PLL