void imx_dump_clocks(void) { printf("mpll: %10u kHz\n", imx_get_mpllclk() / 1000); printf("arm: %10u kHz\n", imx_get_armclk() / 1000); printf("ioclk0: %10u kHz\n", imx_get_ioclk(0) / 1000); printf("ioclk1: %10u kHz\n", imx_get_ioclk(1) / 1000); printf("emiclk: %10u kHz\n", imx_get_emiclk() / 1000); printf("hclk: %10u kHz\n", imx_get_hclk() / 1000); printf("xclk: %10u kHz\n", imx_get_xclk() / 1000); printf("ssp0: %10u kHz\n", imx_get_sspclk(0) / 1000); printf("ssp1: %10u kHz\n", imx_get_sspclk(1) / 1000); printf("ssp2: %10u kHz\n", imx_get_sspclk(2) / 1000); printf("ssp3: %10u kHz\n", imx_get_sspclk(3) / 1000); }
/** * @param index The SSP unit (0...3) * @param nc New frequency in [Hz] * @param high != 0 if ioclk should be the source * @return The new possible frequency */ unsigned imx_set_sspclk(unsigned index, unsigned nc, int high) { uint32_t reg; unsigned ssp_div, offset, shift, ioclk_index; if (index > 3) { pr_debug("Unknown SSP unit: %u\n", index); return 0; } ioclk_index = index >> 1; offset = HW_CLKCTRL_SSP0 + (0x10 * index); shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index; reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_CLKGATE; /* Datasheet says: Do not change the DIV setting if the clock is off */ writel(reg, IMX_CCM_BASE + offset); /* Wait while clock is gated */ while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE) ; if (high) ssp_div = imx_get_ioclk(ioclk_index); else ssp_div = imx_get_xtalclk(); if (nc > ssp_div) { printf("Cannot setup SSP unit clock to %u kHz, base clock is " "only %u kHz\n", nc, ssp_div); ssp_div = 1; } else { ssp_div = DIV_ROUND_UP(ssp_div, nc); if (ssp_div > CLKCTRL_SSP_DIV_MASK) ssp_div = CLKCTRL_SSP_DIV_MASK; } /* Set new divider value */ reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_DIV_MASK; writel(reg | SET_SSP_DIV(ssp_div), IMX_CCM_BASE + offset); /* Wait until new divider value is set */ while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_BUSY) ; if (high) /* switch to ioclock */ writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR); else /* switch to 24 MHz crystal */ writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET); return imx_get_sspclk(index); }
/** * Get the SSP clock rate * @param hw_dev Host interface device instance * @return Unit's clock in [Hz] */ static unsigned mxs_mci_get_unit_clock(struct mxs_mci_host *mxs_mci) { return imx_get_sspclk(mxs_mci->index); }