
Hi Antoine,
On Sun, Apr 30, 2017 at 03:29:54PM +0200, Antoine Tenart wrote:
+/*
- The PSCI suspend function switch cpuclk to another source and disable
- pll1. As this function is called per-CPU, it should only do this when
- all the CPUs are in idle state.
- The 'cnt' variable keeps track of the number of CPU which are in the idle
- state. The last one setup cpuclk for idle.
- The 'clk_state' varibale holds the cpu clk state (idle or normal).
- */
+atomic_t __secure_data cnt, clk_state;
+#define CLK_NORMAL 0 +#define CLK_IDLE 1
+static void __secure sunxi_clock_enter_idle(struct sunxi_ccm_reg *ccm) +{
- /* switch cpuclk to osc24m */
- clrsetbits_le32(&ccm->cpu_ahb_apb0_cfg, 0x3 << CPU_CLK_SRC_SHIFT,
CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT);
- /* disable pll1 */
- clrbits_le32(&ccm->pll1_cfg, CCM_PLL1_CTRL_EN);
+#ifndef CONFIG_MACH_SUN7I
- /*
* Switch cpuclk to losc. Based on my experience this didn't worked for
* sun7i, hence the ifndef.
*/
- clrbits_le32(&ccm->cpu_ahb_apb0_cfg, 0x3 << CPU_CLK_SRC_SHIFT);
+#endif
Do we enter idle per-core, or is it a cluster-wide state?
The A20 has a single clock for both CPUs, so that might explain why it didn't work for you: if you enter idle for only one core, and change the clock for both, then you're probably crashing the second core in the process.
+static void __secure sunxi_clock_leave_idle(struct sunxi_ccm_reg *ccm) +{ +#ifndef CONFIG_MACH_SUN7I
- /* switch cpuclk to osc24m */
- clrsetbits_le32(&ccm->cpu_ahb_apb0_cfg, 0x3 << CPU_CLK_SRC_SHIFT,
CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT);
+#endif
Is that really needed? Whatever state we're in at this point, we just want to switch back to the PLL1, right?
Thanks, Maxime