#define PLL_FREQ_MHZ (PLL_FREQ_KHZ / 1000)
#define XTAL_FREQ_MHZ (XTAL_FREQ_KHZ / 1000)
+static struct mxs_clkctrl_regs *clkctrl_regs = (void *)MXS_CLKCTRL_BASE;
+
static uint32_t mx28_get_pclk(void)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
-
uint32_t clkctrl, clkseq, div;
uint8_t clkfrac, frac;
static uint32_t mx28_get_hclk(void)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
-
uint32_t div;
uint32_t clkctrl;
static uint32_t mx28_get_emiclk(void)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
-
uint32_t clkctrl, clkseq, div;
uint8_t clkfrac, frac;
static uint32_t mx28_get_gpmiclk(void)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
-
uint32_t clkctrl, clkseq, div;
uint8_t clkfrac, frac;
*/
void mx28_set_ioclk(enum mxs_ioclock io, uint32_t freq)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
uint32_t div;
int io_reg;
*/
static uint32_t mx28_get_ioclk(enum mxs_ioclock io)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
uint8_t ret;
int io_reg;
- if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1))
+ if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) {
+ printf("%s: IO clock selector %u out of range %u..%u\n",
+ __func__, io, MXC_IOCLK0, MXC_IOCLK1);
return 0;
-
+ }
io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */
ret = readb(&clkctrl_regs->hw_clkctrl_frac0[io_reg]) &
*/
void mx28_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
uint32_t clk, clkreg;
if (ssp > MXC_SSPCLK3)
*/
static uint32_t mx28_get_sspclk(enum mxs_sspclock ssp)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
- uint32_t clkreg;
+ uint32_t *clkreg;
uint32_t clk, tmp;
if (ssp > MXC_SSPCLK3)
if (tmp & (CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp))
return XTAL_FREQ_KHZ;
- clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
- (ssp * sizeof(struct mxs_register_32));
+ clkreg = &clkctrl_regs->hw_clkctrl_ssp0 +
+ ssp * sizeof(struct mxs_register_32);
tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK;
-
if (tmp == 0)
return 0;
clk = mx28_get_ioclk(ssp >> 1);
-
return clk / tmp;
}
bus, tgtclk, freq);
}
+static uint32_t mx28_get_xbus_clk(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t div;
+ uint32_t clkctrl;
+ uint32_t refclk = mx28_get_pclk();
+
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_xbus);
+ div = clkctrl & CLKCTRL_XBUS_DIV_MASK;
+
+ if (clkctrl & CLKCTRL_XBUS_DIV_FRAC_EN)
+ return 0;
+
+ return refclk / div;
+}
+
uint32_t mxc_get_clock(enum mxc_clock clk)
{
switch (clk) {
return mx28_get_sspclk(MXC_SSPCLK2);
case MXC_SSP3_CLK:
return mx28_get_sspclk(MXC_SSPCLK3);
+ case MXC_XTAL_CLK:
+ return XTAL_FREQ_KHZ * 1000;
+ case MXC_XBUS_CLK:
+ return mx28_get_xbus_clk() * 1000000;
+ default:
+ printf("Invalid clock selector %u\n", clk);
}
return 0;