ARM: tegra: emc: Fix low speed DLL transitions
Alex Waterman [Wed, 12 Jun 2013 18:09:07 +0000 (11:09 -0700)]
EMC DFS was seeing some issues with the DLL at certain low speeds.
This patch fixes the issues seen with those low speed transitions. They
were:

  102 MHz -> high speed
  DLL freq -> 326.4 MHz

Reviewed-on: http://git-master/r/241017
(cherry picked from commit b4c953c341a1c1d626681a00e336ea00a4652f93)
Change-Id: Ib8d3f7cb3536b08f9bf331c04502eebc29b1183b
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: http://git-master/r/248537
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>

arch/arm/mach-tegra/tegra14_emc.c
arch/arm/mach-tegra/tegra14_emc.h

index 1279acb..c365ee3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-tegra/tegra14_emc.c
  *
- * Copyright (C) 2013 NVIDIA Corporation
+ * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -545,6 +545,10 @@ skip_dll_disable:
        emc_cfg_dig_dll &= ~(EMC_CFG_DIG_DLL_UDSET_MASK <<
                             EMC_CFG_DIG_DLL_UDSET_SHIFT);
        emc_cfg_dig_dll |= (0x2 << EMC_CFG_DIG_DLL_UDSET_SHIFT);
+       emc_cfg_dig_dll &= ~(EMC_CFG_DIG_DLL_LOCK_LIMIT_MASK <<
+                            EMC_CFG_DIG_DLL_LOCK_LIMIT_SHIFT);
+       emc_cfg_dig_dll |= (next_timing->emc_cfg_dig_dll &
+                           (3 << EMC_CFG_DIG_DLL_LOCK_LIMIT_SHIFT));
        emc_writel(emc_cfg_dig_dll, EMC_CFG_DIG_DLL);
        emc_timing_update();
 
@@ -576,10 +580,12 @@ skip_dll_disable:
        fbio_spare_new = fbio_spare_old | FBIO_SPARE_CFG_SW_DLL_RST_CTRL_N;
 
        emc_writel(fbio_spare_new, EMC_FBIO_SPARE);
+       emc_timing_update();
        emc_writel(fbio_spare_old, EMC_FBIO_SPARE);
+       emc_timing_update();
 
        emc_cfg_dig_dll = emc_readl(EMC_CFG_DIG_DLL);
-       emc_cfg_dig_dll |= (EMC_CFG_DIG_DLL_EN | EMC_CFG_DIG_DLL_RESET);
+       emc_cfg_dig_dll |= (EMC_CFG_DIG_DLL_EN);
        emc_writel(emc_cfg_dig_dll, EMC_CFG_DIG_DLL);
        emc_timing_update();
        udelay(1);
index 64c5075..aa7adba 100644 (file)
@@ -226,6 +226,8 @@ enum {
 #define EMC_CFG_DIG_DLL_UDSET_MASK             0xf
 #define EMC_CFG_DIG_DLL_OVERRIDE_VAL_SHIFT     0x10
 #define EMC_CFG_DIG_DLL_OVERRIDE_VAL_MASK      0x3ff
+#define EMC_CFG_DIG_DLL_LOCK_LIMIT_SHIFT       0x1c /* 28 */
+#define EMC_CFG_DIG_DLL_LOCK_LIMIT_MASK                0x3
 #define EMC_CFG_DIG_DLL_USE_OVERRIDE_UNTIL_LOCK        (0x1 << 31)
 
 #define EMC_CFG_DIG_DLL_MODE_RUN_TIL_LOCK      0x1