aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorValentin Longchamp <valentin.longchamp@keymile.com>2015-02-10 10:46:33 -0500
committerWolfram Sang <wsa@the-dreams.de>2015-03-15 06:04:54 -0400
commit8ce795cb0c6b8214779c4a220781a26f096e4442 (patch)
treeec29263e34e460c18806c9db94bb10c94c69f44b
parent913b1d85cdde5f1fc081aa84f548270a15027abb (diff)
i2c: mpc: assign the correct prescaler from SVR
For the 85xx platforms, the source clock for the i2c-mpc can change from one SoC to another. This is documented in the AN2919 "Determining the I2C Frequency Divider Ratio for SCL" by Freescale. Not taking this into account can lead to the output SCL frequency to by off by an offset. It was observed on the P2041 from the QorIQ family. This patch fixes this problem by setting the prescaler value to the appropriate value when required. The SoCs that required a different prescaler than 1 are identified by reading out the SVR as discussed in http://thread.gmane.org/gmane.linux.drivers.devicetree/94247/focus=20556 Signed-off-by: Valentin Longchamp <valentin.longchamp@keymile.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--drivers/i2c/busses/i2c-mpc.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index c74cc2be613b..dc03a9164772 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -29,6 +29,7 @@
29#include <linux/delay.h> 29#include <linux/delay.h>
30 30
31#include <asm/mpc52xx.h> 31#include <asm/mpc52xx.h>
32#include <asm/mpc85xx.h>
32#include <sysdev/fsl_soc.h> 33#include <sysdev/fsl_soc.h>
33 34
34#define DRV_NAME "mpc-i2c" 35#define DRV_NAME "mpc-i2c"
@@ -346,6 +347,33 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void)
346 return val; 347 return val;
347} 348}
348 349
350static u32 mpc_i2c_get_prescaler_8xxx(void)
351{
352 /* mpc83xx and mpc82xx all have prescaler 1 */
353 u32 prescaler = 1;
354
355 /* mpc85xx */
356 if (pvr_version_is(PVR_VER_E500V1) || pvr_version_is(PVR_VER_E500V2)
357 || pvr_version_is(PVR_VER_E500MC)
358 || pvr_version_is(PVR_VER_E5500)
359 || pvr_version_is(PVR_VER_E6500)) {
360 unsigned int svr = mfspr(SPRN_SVR);
361
362 if ((SVR_SOC_VER(svr) == SVR_8540)
363 || (SVR_SOC_VER(svr) == SVR_8541)
364 || (SVR_SOC_VER(svr) == SVR_8560)
365 || (SVR_SOC_VER(svr) == SVR_8555)
366 || (SVR_SOC_VER(svr) == SVR_8610))
367 /* the above 85xx SoCs have prescaler 1 */
368 prescaler = 1;
369 else
370 /* all the other 85xx have prescaler 2 */
371 prescaler = 2;
372 }
373
374 return prescaler;
375}
376
349static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, 377static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
350 u32 prescaler, u32 *real_clk) 378 u32 prescaler, u32 *real_clk)
351{ 379{
@@ -363,7 +391,7 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
363 if (of_device_is_compatible(node, "fsl,mpc8544-i2c")) 391 if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
364 prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2; 392 prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
365 if (!prescaler) 393 if (!prescaler)
366 prescaler = 1; 394 prescaler = mpc_i2c_get_prescaler_8xxx();
367 395
368 divider = fsl_get_sys_freq() / clock / prescaler; 396 divider = fsl_get_sys_freq() / clock / prescaler;
369 397