Example #1
0
static inline uint32_t
cpufreq_actual_mhz(struct imx6_anatop_softc *sc, uint32_t cpu_mhz)
{
	uint32_t corediv, plldiv;

	cpufreq_mhz_to_div(sc, cpu_mhz, &corediv, &plldiv);
	return (cpufreq_mhz_from_div(sc, corediv, plldiv));
}
Example #2
0
static void 
cpufreq_set_clock(struct imx6_anatop_softc * sc, struct oppt *op)
{
	uint32_t corediv, plldiv, timeout, wrk32;

	/* If increasing the frequency, we must first increase the voltage. */
	if (op->mhz > sc->cpu_curmhz) {
		vdd_set(sc, op->mv);
	}

	/*
	 * I can't find a documented procedure for changing the ARM PLL divisor,
	 * but some trial and error came up with this:
	 *  - Set the bypass clock source to REF_CLK_24M (source #0).
	 *  - Set the PLL into bypass mode; cpu should now be running at 24mhz.
	 *  - Change the divisor.
	 *  - Wait for the LOCK bit to come on; it takes ~50 loop iterations.
	 *  - Turn off bypass mode; cpu should now be running at the new speed.
	 */
	cpufreq_mhz_to_div(sc, op->mhz, &corediv, &plldiv);
	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR, 
	    IMX6_ANALOG_CCM_PLL_ARM_CLK_SRC_MASK);
	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_SET, 
	    IMX6_ANALOG_CCM_PLL_ARM_BYPASS);

	wrk32 = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM);
	wrk32 &= ~IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK;
	wrk32 |= plldiv;
	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM, wrk32);

	timeout = 10000;
	while ((imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM) &
	    IMX6_ANALOG_CCM_PLL_ARM_LOCK) == 0)
		if (--timeout == 0)
			panic("imx6_set_cpu_clock(): PLL never locked");

	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR, 
	    IMX6_ANALOG_CCM_PLL_ARM_BYPASS);
	imx_ccm_set_cacrr(corediv);

	/* If lowering the frequency, it is now safe to lower the voltage. */
	if (op->mhz < sc->cpu_curmhz)
		vdd_set(sc, op->mv);
	sc->cpu_curmhz = op->mhz;

	/* Tell the mpcore timer that its frequency has changed. */
	arm_tmr_change_frequency(
	    cpufreq_actual_mhz(sc, sc->cpu_curmhz) * 1000000 / 2);
}
Example #3
0
static inline uint32_t
cpufreq_actual_mhz(struct imx6_anatop_softc *sc, uint32_t cpu_mhz)
{

	return (cpufreq_mhz_from_div(sc, cpufreq_mhz_to_div(sc, cpu_mhz)));
}