Skip to contentSkip to conversation

mx25: Fix decode_pll

PATCH New Benoît Thébaudeau 3 participants 13 messages Sep 27, 2012 – Sep 30, 2012 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 1/7 mx25: Fix decode_pll

The MFN bit-field of the PLL registers represents a signed value. See the reference manual.

---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +6 -3
index 90e584a..2283a89 100644
@@ -48,7 +48,7 @@ static unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref)
 {
 	unsigned int mfi = (pll >> CCM_PLL_MFI_SHIFT)
 	    & CCM_PLL_MFI_MASK;
-	unsigned int mfn = (pll >> CCM_PLL_MFN_SHIFT)
+	int mfn = (pll >> CCM_PLL_MFN_SHIFT)
 	    & CCM_PLL_MFN_MASK;
 	unsigned int mfd = (pll >> CCM_PLL_MFD_SHIFT)
 	    & CCM_PLL_MFD_MASK;
@@ -56,9 +56,12 @@ static unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref)
 	    & CCM_PLL_PD_MASK;
 
 	mfi = mfi <= 5 ? 5 : mfi;
+	mfn = mfn >= 512 ? mfn - 1024 : mfn;
+	mfd += 1;
+	pd += 1;
 
-	return lldiv(2 * (u64) f_ref * (mfi * (mfd + 1) + mfn),
-		      (mfd + 1) * (pd + 1));
+	return lldiv(2 * (u64) f_ref * (mfi * mfd + mfn),
+		     mfd * pd);
 }
 
 static ulong imx_get_mpllclk(void)
#1 lore raw

PATCH 2/7 mx25: Clean up clock calculations

Avoid possible overflow in clock calculations, and do not waste calls to lldiv() to divide simple ulongs.

---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +4 -4
index 2283a89..5503522 100644
@@ -80,12 +80,12 @@ ulong imx_get_armclk(void)
 	ulong div;
 
 	if (cctl & CCM_CCTL_ARM_SRC)
-		fref = lldiv((fref * 3), 4);
+		fref = lldiv((u64) fref * 3, 4);
 
 	div = ((cctl >> CCM_CCTL_ARM_DIV_SHIFT)
 	       & CCM_CCTL_ARM_DIV_MASK) + 1;
 
-	return lldiv(fref, div);
+	return fref / div;
 }
 
 ulong imx_get_ahbclk(void)
@@ -98,7 +98,7 @@ ulong imx_get_ahbclk(void)
 	div = ((cctl >> CCM_CCTL_AHB_DIV_SHIFT)
 	       & CCM_CCTL_AHB_DIV_MASK) + 1;
 
-	return lldiv(fref, div);
+	return fref / div;
 }
 
 ulong imx_get_perclk(int clk)
@@ -110,7 +110,7 @@ ulong imx_get_perclk(int clk)
 	div = readl(&ccm->pcdr[CCM_PERCLK_REG(clk)]);
 	div = ((div >> CCM_PERCLK_SHIFT(clk)) & CCM_PERCLK_MASK) + 1;
 
-	return lldiv(fref, div);
+	return fref / div;
 }
 
 unsigned int mxc_get_clock(enum mxc_clock clk)
#2 lore raw

PATCH 3/7 mx25: Define more standard clocks

In reply to Benoît Thébaudeau

Define AHB, IPG and CSPI clocks.

---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |   10 ++++++++++
 .../arch/arm/include/asm/arch-mx25/clock.h         |    5 +++++
 2 files changed, 15 insertions(+)
arch/arm/cpu/arm926ejs/mx25/generic.c +10 -0
index 5503522..219c9eb 100644
@@ -101,6 +101,11 @@ ulong imx_get_ahbclk(void)
 	return fref / div;
 }
 
+static ulong imx_get_ipgclk(void)
+{
+	return imx_get_ahbclk() / 2;
+}
+
 ulong imx_get_perclk(int clk)
 {
 	struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
@@ -120,6 +125,11 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
 	switch (clk) {
 	case MXC_ARM_CLK:
 		return imx_get_armclk();
+	case MXC_AHB_CLK:
+		return imx_get_ahbclk();
+	case MXC_IPG_CLK:
+	case MXC_CSPI_CLK:
+		return imx_get_ipgclk();
 	case MXC_FEC_CLK:
 		return imx_get_ahbclk();
 	default:
arch/arm/include/asm/arch-mx25/clock.h +5 -0
index a313b80..9823f46 100644
@@ -41,6 +41,7 @@
 #endif
 
 enum mxc_clock {
+	/* PER clocks (do not change order) */
 	MXC_CSI_CLK,
 	MXC_EPIT_CLK,
 	MXC_ESAI_CLK,
@@ -57,7 +58,11 @@ enum mxc_clock {
 	MXC_SSI1_CLK,
 	MXC_SSI2_CLK,
 	MXC_UART_CLK,
+	/* Other clocks */
 	MXC_ARM_CLK,
+	MXC_AHB_CLK,
+	MXC_IPG_CLK,
+	MXC_CSPI_CLK,
 	MXC_FEC_CLK,
 	MXC_CLK_NUM
 };
#3 lore raw

PATCH 4/7 mx25 clocks: Fix MXC_FEC_CLK

In reply to Benoît Thébaudeau

mxc_get_clock(MXC_FEC_CLK) should return the IPG clock, not the AHB clock.

Also, imx_get_fecclk() was correct but reimplemented the calculation of the IPG clock, so remove the duplicated code.

---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |    3 +--
 .../arch/arm/include/asm/arch-mx25/clock.h         |    2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +1 -2
index 219c9eb..5879b18 100644
@@ -129,9 +129,8 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
 		return imx_get_ahbclk();
 	case MXC_IPG_CLK:
 	case MXC_CSPI_CLK:
-		return imx_get_ipgclk();
 	case MXC_FEC_CLK:
-		return imx_get_ahbclk();
+		return imx_get_ipgclk();
 	default:
 		return imx_get_perclk(clk);
 	}
arch/arm/include/asm/arch-mx25/clock.h +1 -1
index 9823f46..a532da5 100644
@@ -71,7 +71,7 @@ ulong imx_get_perclk(int clk);
 ulong imx_get_ahbclk(void);
 
 #define imx_get_uartclk() imx_get_perclk(15)
-#define imx_get_fecclk() (imx_get_ahbclk()/2)
+#define imx_get_fecclk() mxc_get_clock(MXC_FEC_CLK)
 
 unsigned int mxc_get_clock(enum mxc_clock clk);
 
#4 lore raw

PATCH 4/7 mx25 clocks: Fix MXC_FEC_CLK

Quoted 33 lines · Beno?t Th?baudeau

mxc_get_clock(MXC_FEC_CLK) should return the IPG clock, not the AHB clock.

Also, imx_get_fecclk() was correct but reimplemented the calculation of the IPG clock, so remove the duplicated code.

---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |    3 +--
 .../arch/arm/include/asm/arch-mx25/clock.h         |    2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +1 -2
index 219c9eb..5879b18 100644
@@ -129,9 +129,8 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
 		return imx_get_ahbclk();
 	case MXC_IPG_CLK:
 	case MXC_CSPI_CLK:
-		return imx_get_ipgclk();
 	case MXC_FEC_CLK:
-		return imx_get_ahbclk();
+		return imx_get_ipgclk();
 	default:
 		return imx_get_perclk(clk);
 	}
arch/arm/include/asm/arch-mx25/clock.h +0 -0
index 9823f46..a532da5 100644

arch/arm/include/asm/arch-mx25/clock.h ulong imx_get_perclk(int clk); · line 77

Quoted 8 lines
arch/arm/include/asm/arch-mx25/clock.h +1 -1
@@ -71,7 +71,7 @@ ulong imx_get_perclk(int clk);
 ulong imx_get_ahbclk(void);
 
 #define imx_get_uartclk() imx_get_perclk(15)
-#define imx_get_fecclk() (imx_get_ahbclk()/2)
+#define imx_get_fecclk() mxc_get_clock(MXC_FEC_CLK)
 
 unsigned int mxc_get_clock(enum mxc_clock clk);
 

Tested on tx25.

Regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#5 lore raw

PATCH 5/7 mx25: Clean up clocks API

In reply to Benoît Thébaudeau

Use the standard mxc_get_clock() instead of exporting internal functions and using literal constant values.

---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |    6 +++---
 .../arch/arm/include/asm/arch-mx25/clock.h         |    9 +++------
 2 files changed, 6 insertions(+), 9 deletions(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +3 -3
index 5879b18..5da2582 100644
@@ -72,7 +72,7 @@ static ulong imx_get_mpllclk(void)
 	return imx_decode_pll(readl(&ccm->mpctl), fref);
 }
 
-ulong imx_get_armclk(void)
+static ulong imx_get_armclk(void)
 {
 	struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
 	ulong cctl = readl(&ccm->cctl);
@@ -88,7 +88,7 @@ ulong imx_get_armclk(void)
 	return fref / div;
 }
 
-ulong imx_get_ahbclk(void)
+static ulong imx_get_ahbclk(void)
 {
 	struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
 	ulong cctl = readl(&ccm->cctl);
@@ -106,7 +106,7 @@ static ulong imx_get_ipgclk(void)
 	return imx_get_ahbclk() / 2;
 }
 
-ulong imx_get_perclk(int clk)
+static ulong imx_get_perclk(int clk)
 {
 	struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
 	ulong fref = imx_get_ahbclk();
arch/arm/include/asm/arch-mx25/clock.h +3 -6
index a532da5..efbe038 100644
@@ -67,12 +67,9 @@ enum mxc_clock {
 	MXC_CLK_NUM
 };
 
-ulong imx_get_perclk(int clk);
-ulong imx_get_ahbclk(void);
-
-#define imx_get_uartclk() imx_get_perclk(15)
-#define imx_get_fecclk() mxc_get_clock(MXC_FEC_CLK)
-
 unsigned int mxc_get_clock(enum mxc_clock clk);
 
+#define imx_get_uartclk()	mxc_get_clock(MXC_UART_CLK)
+#define imx_get_fecclk()	mxc_get_clock(MXC_FEC_CLK)
+
 #endif /* __ASM_ARCH_CLOCK_H */
#6 lore raw

PATCH 5/7 mx25: Clean up clocks API

Quoted 52 lines · Beno?t Th?baudeau

Use the standard mxc_get_clock() instead of exporting internal functions and using literal constant values.

---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |    6 +++---
 .../arch/arm/include/asm/arch-mx25/clock.h         |    9 +++------
 2 files changed, 6 insertions(+), 9 deletions(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +3 -3
index 5879b18..5da2582 100644
@@ -72,7 +72,7 @@ static ulong imx_get_mpllclk(void)
 	return imx_decode_pll(readl(&ccm->mpctl), fref);
 }
 
-ulong imx_get_armclk(void)
+static ulong imx_get_armclk(void)
 {
 	struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
 	ulong cctl = readl(&ccm->cctl);
@@ -88,7 +88,7 @@ ulong imx_get_armclk(void)
 	return fref / div;
 }
 
-ulong imx_get_ahbclk(void)
+static ulong imx_get_ahbclk(void)
 {
 	struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
 	ulong cctl = readl(&ccm->cctl);
@@ -106,7 +106,7 @@ static ulong imx_get_ipgclk(void)
 	return imx_get_ahbclk() / 2;
 }
 
-ulong imx_get_perclk(int clk)
+static ulong imx_get_perclk(int clk)
 {
 	struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
 	ulong fref = imx_get_ahbclk();
arch/arm/include/asm/arch-mx25/clock.h +0 -2
index a532da5..efbe038 100644
@@ -67,12 +67,9 @@ enum mxc_clock {
 	MXC_CLK_NUM
 };
 
-ulong imx_get_perclk(int clk);
-ulong imx_get_ahbclk(void);

arch/arm/include/asm/arch-mx25/clock.h enum mxc_clock { · line 75

Quoted 10 lines
arch/arm/include/asm/arch-mx25/clock.h +3 -4
-
-#define imx_get_uartclk() imx_get_perclk(15)
-#define imx_get_fecclk() mxc_get_clock(MXC_FEC_CLK)
-
 unsigned int mxc_get_clock(enum mxc_clock clk);
 
+#define imx_get_uartclk()	mxc_get_clock(MXC_UART_CLK)
+#define imx_get_fecclk()	mxc_get_clock(MXC_FEC_CLK)
+
 #endif /* __ASM_ARCH_CLOCK_H */

Tested on tx25.

Regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#7 lore raw

PATCH 6/7 mx25: Define cpu_eth_init() only if needed

In reply to Benoît Thébaudeau

The FEC is the only SoC Ethernet support available on i.MX25, so define cpu_eth_init() only for it instead of returning a misleading success code.

---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +6 -4
index 5da2582..6374248 100644
@@ -206,9 +206,13 @@ void enable_caches(void)
 #endif
 }
 
+#if defined(CONFIG_FEC_MXC)
+/*
+ * Initializes on-chip ethernet controllers.
+ * to override, implement board_eth_init()
+ */
 int cpu_eth_init(bd_t *bis)
 {
-#if defined(CONFIG_FEC_MXC)
 	struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
 	ulong val;
 
@@ -216,10 +220,8 @@ int cpu_eth_init(bd_t *bis)
 	val |= (1 << 23);
 	writel(val, &ccm->cgr0);
 	return fecmxc_initialize(bis);
-#else
-	return 0;
-#endif
 }
+#endif
 
 int get_clocks(void)
 {
#8 lore raw

PATCH 6/7 mx25: Define cpu_eth_init() only if needed

Hi Beno?t,

Quoted 2 lines · Beno?t Th?baudeau

The FEC is the only SoC Ethernet support available on i.MX25, so define cpu_eth_init() only for it instead of returning a misleading success code.

Yes, but someone may want to use mx25 with a external LAN device (such as LAN92xx) instead of FEC.

Regards,

Fabio Estevam

#9 lore raw

PATCH 6/7 mx25: Define cpu_eth_init() only if needed

Hi Fabio,

Quoted 4 lines · Fabio Estevam

Hi Beno?t,

On Thu, Sep 27, 2012 at 5:28 PM, Beno?t Th?baudeau <[email protected]> wrote:

Quoted 8 lines
Quoted 4 lines

The FEC is the only SoC Ethernet support available on i.MX25, so define
cpu_eth_init() only for it instead of returning a misleading success code.

Yes, but someone may want to use mx25 with a external LAN device (such
as LAN92xx) instead of FEC.

Yes, but in that case I think that there should be a board_eth_init() function defined, so this patch won't cause any trouble here. See in net/eth.c:eth_initialize() how these functions and their default implementations are handled.

Best regards,
Beno?t

#10 lore raw

PATCH 6/7 mx25: Define cpu_eth_init() only if needed

Quoted 12 lines · Beno?t Th?baudeau

Hi Fabio,

Quoted 9 lines · Fabio Estevam

Hi Beno?t,

Quoted 4 lines · Beno?t Th?baudeau

The FEC is the only SoC Ethernet support available on i.MX25, so define
cpu_eth_init() only for it instead of returning a misleading success code.

Quoted 8 lines
Quoted 3 lines

Yes, but someone may want to use mx25 with a external LAN device (such
as LAN92xx) instead of FEC.

Yes, but in that case I think that there should be a board_eth_init() function defined, so this patch won't cause any trouble here. See in net/eth.c:eth_initialize() how these functions and their default implementations are handled.

I think also that in this case a board_eth_init() must be used - the #ifdef in cpu_eth_init() is then superflous.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#11 lore raw

PATCH 7/7 mx25: Fix eSDHC support

In reply to Benoît Thébaudeau

The MMC driver appropriate for the i.MX25 is fsl_esdhc, which has nothing to do with mxcmmc.

Also, each eSDHC instance has a dedicated clock, so gd->sdhc_clk must be set accordingly. This is good for the case only a single SDHC instance is used (initialization made with fsl_esdhc_mmc_init()). A future patch will fix the multi-instance use case (initialization made directly with fsl_esdhc_initialize()).

Cc Stefano Babic <[email protected]>
Cc Eric B?nard <[email protected]>
Cc Otavio Salvador <[email protected]>
---
 .../arch/arm/cpu/arm926ejs/mx25/generic.c          |   19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)
arch/arm/cpu/arm926ejs/mx25/generic.c +10 -9
index 6374248..af81b33 100644
@@ -29,11 +29,10 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/imx25-pinmux.h>
 #include <asm/arch/clock.h>
-#ifdef CONFIG_MXC_MMC
-#include <asm/arch/mxcmmc.h>
-#endif
 
 #ifdef CONFIG_FSL_ESDHC
+#include <fsl_esdhc.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 #endif
 
@@ -226,23 +225,25 @@ int cpu_eth_init(bd_t *bis)
 int get_clocks(void)
 {
 #ifdef CONFIG_FSL_ESDHC
-	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+#if CONFIG_SYS_FSL_ESDHC_ADDR == IMX_MMC_SDHC2_BASE
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+#else
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
+#endif
 #endif
 	return 0;
 }
 
+#ifdef CONFIG_FSL_ESDHC
 /*
  * Initializes on-chip MMC controllers.
  * to override, implement board_mmc_init()
  */
 int cpu_mmc_init(bd_t *bis)
 {
-#ifdef CONFIG_MXC_MMC
-	return mxc_mmc_init(bis);
-#else
-	return 0;
-#endif
+	return fsl_esdhc_mmc_init(bis);
 }
+#endif
 
 #ifdef CONFIG_MXC_UART
 void mx25_uart1_init_pins(void)
#12 lore raw

PATCH 1/7 mx25: Fix decode_pll

In reply to Benoît Thébaudeau
Quoted 6 lines · Beno?t Th?baudeau

The MFN bit-field of the PLL registers represents a signed value. See the reference manual.

---

All series applied to u-boot-imx, next branch, thanks.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================