[U-Boot-Users] [PATCH] Fix calculation of I2C clock for some 85xx chips

Timur Tabi timur at freescale.com
Fri Apr 4 18:15:58 CEST 2008


Some 85xx chips use CCB as the base clock for the I2C.  Some use CCB/2, and
some use CCB/3.  There is no pattern that can be used to determine which
chips use which frequency, so the only way to determine is to look up the
actual SOC designation and use the right value for that SOC.

Update immap_85xx.h to include the GUTS PORDEVSR2 register.

Signed-off-by: Timur Tabi <timur at freescale.com>
---

Yes, this is ugly and stupid, but the only alternative is to update each
board configuration file with another CONFIG_ option.  And yes, this does
mean that as new 85xx variants are announced, cpu/mpc85xx/speed.c may need
to be updated.

 cpu/mpc85xx/speed.c          |   31 ++++++++++++++++++++++++++++++-
 include/asm-ppc/immap_85xx.h |    4 +++-
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c
index d90d397..699441b 100644
--- a/cpu/mpc85xx/speed.c
+++ b/cpu/mpc85xx/speed.c
@@ -65,6 +65,9 @@ void get_sys_info (sys_info_t * sysInfo)
 int get_clocks (void)
 {
 	sys_info_t sys_info;
+#ifdef CONFIG_MPC8544
+	volatile ccsr_gur_t *gur = (void *) CFG_MPC85xx_GUTS_ADDR;
+#endif
 #if defined(CONFIG_CPM2)
 	volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CFG_MPC85xx_CPM_ADDR;
 	uint sccr, dfbrg;
@@ -78,8 +81,34 @@ int get_clocks (void)
 	gd->cpu_clk = sys_info.freqProcessor;
 	gd->bus_clk = sys_info.freqSystemBus;
 	gd->mem_clk = sys_info.freqDDRBus;
+
+	/*
+	 * The base clock for I2C depends on the actual SOC.  Unfortunately,
+	 * there is no pattern that can be used to determine the frequency, so
+	 * the only choice is to look up the actual SOC number and use the value
+	 * for that SOC. This information is taken from application note
+	 * AN2919.
+	 */
+#if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+	defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555)
 	gd->i2c1_clk = sys_info.freqSystemBus;
-	gd->i2c2_clk = sys_info.freqSystemBus;
+#elif defined(CONFIG_MPC8544)
+	/*
+	 * On the 8544, the I2C clock is the same as the SEC clock.  This can be
+	 * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See
+	 * 4.4.3.3 of the 8544 RM.  Note that this might actually work for all
+	 * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the
+	 * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544.
+	 */
+	if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG)
+		gd->i2c1_clk = sys_info.freqSystemBus / 3;
+	else
+		gd->i2c1_clk = sys_info.freqSystemBus / 2;
+#else
+	/* Most 85xx SOCs use CCB/2, so this is the default behavior. */
+	gd->i2c1_clk = sys_info.freqSystemBus / 2;
+#endif
+	gd->i2c2_clk = gd->i2c1_clk;
 
 #if defined(CONFIG_CPM2)
 	gd->vco_out = 2*sys_info.freqSystemBus;
diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h
index 3506aec..42c066e 100644
--- a/include/asm-ppc/immap_85xx.h
+++ b/include/asm-ppc/immap_85xx.h
@@ -1570,7 +1570,9 @@ typedef struct ccsr_gur {
 #define MPC85xx_PORDEVSR_RIO_CTLS 	0x00000008
 #define MPC85xx_PORDEVSR_RIO_DEV_ID	0x00000007
 	uint	pordbgmsr;	/* 0xe0010 - POR debug mode status register */
-	char	res1[12];
+	uint	pordevsr2;	/* 0xe0014 - POR I/O device status regsiter 2 */
+#define MPC85xx_PORDEVSR2_SEC_CFG	0x00000020
+	char	res1[8];
 	uint	gpporcr;	/* 0xe0020 - General-purpose POR configuration register */
 	char	res2[12];
 	uint	gpiocr;		/* 0xe0030 - GPIO control register */
-- 
1.5.4





More information about the U-Boot mailing list