]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/arm/cpu/arm926ejs/mxs/clock.c
mxs: Reset the EMI block on mx23
[karo-tx-uboot.git] / arch / arm / cpu / arm926ejs / mxs / clock.c
index 4ff19c37efe91ac7247f2b48c0d78097de9fd9e1..00b9aba457ed4f9a0e9cb2669bc21fb2bc983b36 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Freescale i.MX28 clock setup code
+ * Freescale i.MX23/i.MX28 clock setup code
  *
  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
  * on behalf of DENX Software Engineering GmbH
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
 
-/* The PLL frequency is always 480MHz, see section 10.2 in iMX28 datasheet. */
+/*
+ * The PLL frequency is 480MHz and XTAL frequency is 24MHz
+ *   iMX23: datasheet section 4.2
+ *   iMX28: datasheet section 10.2
+ */
 #define        PLL_FREQ_KHZ    480000
 #define        PLL_FREQ_COEF   18
-/* The XTAL frequency is always 24MHz, see section 10.2 in iMX28 datasheet. */
 #define        XTAL_FREQ_KHZ   24000
 
 #define        PLL_FREQ_MHZ    (PLL_FREQ_KHZ / 1000)
 #define        XTAL_FREQ_MHZ   (XTAL_FREQ_KHZ / 1000)
 
-static uint32_t mx28_get_pclk(void)
+#if defined(CONFIG_MX23)
+#define MXC_SSPCLK_MAX MXC_SSPCLK0
+#elif defined(CONFIG_MX28)
+#define MXC_SSPCLK_MAX MXC_SSPCLK3
+#endif
+
+static uint32_t mxs_get_pclk(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -73,7 +82,7 @@ static uint32_t mx28_get_pclk(void)
        return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
 }
 
-static uint32_t mx28_get_hclk(void)
+static uint32_t mxs_get_hclk(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -88,10 +97,10 @@ static uint32_t mx28_get_hclk(void)
                return 0;
 
        div = clkctrl & CLKCTRL_HBUS_DIV_MASK;
-       return mx28_get_pclk() / div;
+       return mxs_get_pclk() / div;
 }
 
-static uint32_t mx28_get_emiclk(void)
+static uint32_t mxs_get_emiclk(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -116,11 +125,17 @@ static uint32_t mx28_get_emiclk(void)
        return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
 }
 
-static uint32_t mx28_get_gpmiclk(void)
+static uint32_t mxs_get_gpmiclk(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
-
+#if defined(CONFIG_MX23)
+       uint8_t *reg =
+               &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU];
+#elif defined(CONFIG_MX28)
+       uint8_t *reg =
+               &clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_GPMI];
+#endif
        uint32_t clkctrl, clkseq, div;
        uint8_t clkfrac, frac;
 
@@ -134,7 +149,7 @@ static uint32_t mx28_get_gpmiclk(void)
        }
 
        /* REF Path */
-       clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_GPMI]);
+       clkfrac = readb(reg);
        frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
        div = clkctrl & CLKCTRL_GPMI_DIV_MASK;
        return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
@@ -143,7 +158,7 @@ static uint32_t mx28_get_gpmiclk(void)
 /*
  * Set IO clock frequency, in kHz
  */
-void mx28_set_ioclk(enum mxs_ioclock io, uint32_t freq)
+void mxs_set_ioclk(enum mxs_ioclock io, uint32_t freq)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -176,7 +191,7 @@ void mx28_set_ioclk(enum mxs_ioclock io, uint32_t freq)
 /*
  * Get IO clock, returns IO clock in kHz
  */
-static uint32_t mx28_get_ioclk(enum mxs_ioclock io)
+static uint32_t mxs_get_ioclk(enum mxs_ioclock io)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -197,13 +212,13 @@ static uint32_t mx28_get_ioclk(enum mxs_ioclock io)
 /*
  * Configure SSP clock frequency, in kHz
  */
-void mx28_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
+void mxs_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)
+       if (ssp > MXC_SSPCLK_MAX)
                return;
 
        clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
@@ -216,7 +231,7 @@ void mx28_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
        if (xtal)
                clk = XTAL_FREQ_KHZ;
        else
-               clk = mx28_get_ioclk(ssp >> 1);
+               clk = mxs_get_ioclk(ssp >> 1);
 
        if (freq > clk)
                return;
@@ -241,14 +256,14 @@ void mx28_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
 /*
  * Return SSP frequency, in kHz
  */
-static uint32_t mx28_get_sspclk(enum mxs_sspclock ssp)
+static uint32_t mxs_get_sspclk(enum mxs_sspclock ssp)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
        uint32_t clkreg;
        uint32_t clk, tmp;
 
-       if (ssp > MXC_SSPCLK3)
+       if (ssp > MXC_SSPCLK_MAX)
                return 0;
 
        tmp = readl(&clkctrl_regs->hw_clkctrl_clkseq);
@@ -263,7 +278,7 @@ static uint32_t mx28_get_sspclk(enum mxs_sspclock ssp)
        if (tmp == 0)
                return 0;
 
-       clk = mx28_get_ioclk(ssp >> 1);
+       clk = mxs_get_ioclk(ssp >> 1);
 
        return clk / tmp;
 }
@@ -271,14 +286,14 @@ static uint32_t mx28_get_sspclk(enum mxs_sspclock ssp)
 /*
  * Set SSP/MMC bus frequency, in kHz)
  */
-void mx28_set_ssp_busclock(unsigned int bus, uint32_t freq)
+void mxs_set_ssp_busclock(unsigned int bus, uint32_t freq)
 {
        struct mxs_ssp_regs *ssp_regs;
-       const uint32_t sspclk = mx28_get_sspclk(bus);
+       const uint32_t sspclk = mxs_get_sspclk(bus);
        uint32_t reg;
        uint32_t divide, rate, tgtclk;
 
-       ssp_regs = (struct mxs_ssp_regs *)(MXS_SSP0_BASE + (bus * 0x2000));
+       ssp_regs = mxs_ssp_regs_by_bus(bus);
 
        /*
         * SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)),
@@ -313,28 +328,30 @@ uint32_t mxc_get_clock(enum mxc_clock clk)
 {
        switch (clk) {
        case MXC_ARM_CLK:
-               return mx28_get_pclk() * 1000000;
+               return mxs_get_pclk() * 1000000;
        case MXC_GPMI_CLK:
-               return mx28_get_gpmiclk() * 1000000;
+               return mxs_get_gpmiclk() * 1000000;
        case MXC_AHB_CLK:
        case MXC_IPG_CLK:
-               return mx28_get_hclk() * 1000000;
+               return mxs_get_hclk() * 1000000;
        case MXC_EMI_CLK:
-               return mx28_get_emiclk();
+               return mxs_get_emiclk();
        case MXC_IO0_CLK:
-               return mx28_get_ioclk(MXC_IOCLK0);
+               return mxs_get_ioclk(MXC_IOCLK0);
        case MXC_IO1_CLK:
-               return mx28_get_ioclk(MXC_IOCLK1);
+               return mxs_get_ioclk(MXC_IOCLK1);
+       case MXC_XTAL_CLK:
+               return XTAL_FREQ_KHZ * 1000;
        case MXC_SSP0_CLK:
-               return mx28_get_sspclk(MXC_SSPCLK0);
+               return mxs_get_sspclk(MXC_SSPCLK0);
+#ifdef CONFIG_MX28
        case MXC_SSP1_CLK:
-               return mx28_get_sspclk(MXC_SSPCLK1);
+               return mxs_get_sspclk(MXC_SSPCLK1);
        case MXC_SSP2_CLK:
-               return mx28_get_sspclk(MXC_SSPCLK2);
+               return mxs_get_sspclk(MXC_SSPCLK2);
        case MXC_SSP3_CLK:
-               return mx28_get_sspclk(MXC_SSPCLK3);
-       case MXC_XTAL_CLK:
-               return XTAL_FREQ_KHZ * 1000;
+               return mxs_get_sspclk(MXC_SSPCLK3);
+#endif
        }
 
        return 0;