summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2011-03-31 16:04:16 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-04-01 19:25:50 -0700
commit82727cdc199df35484927ba44813e431cc4a7944 (patch)
tree9afad6688f59e5dc3f00164e08be688b97bd8f48 /arch
parent4c92e4f2ac11913c4ba19d3ffc1be0f5ae8c4ca6 (diff)
ARM: tegra: fuse: calculate pgm cycles from oscillator freq
calculate the number of programming cycles to be used to burn fuses from the oscillator frequency that is being used. Bug 796825 Change-Id: I1698017f1c9661560d36a9ad613f6a4b1c51df46 Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-on: http://git-master/r/24922 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/tegra2_fuse.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/tegra2_fuse.c b/arch/arm/mach-tegra/tegra2_fuse.c
index 6da0c5d7c885..ac2f02cfb669 100644
--- a/arch/arm/mach-tegra/tegra2_fuse.c
+++ b/arch/arm/mach-tegra/tegra2_fuse.c
@@ -46,6 +46,7 @@
#include <linux/wakelock.h>
#include <mach/tegra2_fuse.h>
+#include <mach/iomap.h>
#include "fuse.h"
@@ -547,10 +548,21 @@ static int fuse_set(enum fuse_io_param io_param, u32 *param, int size)
return 0;
}
+#define CAR_OSC_CTRL 0x50
+#define PMC_PLLP_OVERRIDE 0xF8
+#define PMC_OSC_OVERRIDE BIT(0)
+#define PMC_OSC_FREQ_MASK (BIT(2) | BIT(3))
+#define PMC_OSC_FREQ_SHIFT 2
+#define CAR_OSC_FREQ_SHIFT 30
+
+/* cycles corresponding to 13MHz, 19.2MHz, 12MHz, 26MHz */
+static int fuse_pgm_cycles[] = {130, 192, 120, 260};
+
int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags)
{
u32 reg;
int i = 0;
+ int index;
mutex_lock(&fuse_lock);
reg = tegra_fuse_readl(FUSE_DIS_PGM);
@@ -585,7 +597,18 @@ int tegra_fuse_program(struct fuse_data *pgm_data, u32 flags)
regulator_enable(vdd_fuse);
populate_fuse_arrs(&fuse_info, flags);
- fuse_program_array(0);
+
+ /* calculate the number of program cycles from the oscillator freq */
+ reg = readl(IO_ADDRESS(TEGRA_PMC_BASE) + PMC_PLLP_OVERRIDE);
+ if (reg & PMC_OSC_OVERRIDE) {
+ index = (reg & PMC_OSC_FREQ_MASK) >> PMC_OSC_FREQ_SHIFT;
+ } else {
+ reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE) + CAR_OSC_CTRL);
+ index = reg >> CAR_OSC_FREQ_SHIFT;
+ }
+
+ pr_debug("%s: use %d programming cycles\n", __func__, fuse_pgm_cycles[index]);
+ fuse_program_array(fuse_pgm_cycles[index]);
/* disable program bit */
reg = 0;