2 * arch/arm/mach-tegra/kfuse.c
4 * Copyright (C) 2010-2011 NVIDIA Corporation.
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 /* The kfuse block stores downstream and upstream HDCP keys for use by HDMI
21 #include <linux/kernel.h>
23 #include <linux/err.h>
24 #include <linux/string.h>
25 #include <linux/delay.h>
27 #include <mach/iomap.h>
28 #include <mach/kfuse.h>
32 /* register definition */
33 #define KFUSE_STATE 0x80
34 #define KFUSE_STATE_DONE (1u << 16)
35 #define KFUSE_STATE_CRCPASS (1u << 17)
36 #define KFUSE_KEYADDR 0x88
37 #define KFUSE_KEYADDR_AUTOINC (1u << 16)
38 #define KFUSE_KEYS 0x8c
40 static inline u32 tegra_kfuse_readl(unsigned long offset)
42 return tegra_apb_readl(TEGRA_KFUSE_BASE + offset);
45 static inline void tegra_kfuse_writel(u32 value, unsigned long offset)
47 tegra_apb_writel(value, TEGRA_KFUSE_BASE + offset);
50 static int wait_for_done(void)
55 reg = tegra_kfuse_readl(KFUSE_STATE);
56 if (reg & KFUSE_STATE_DONE);
63 /* read up to KFUSE_DATA_SZ bytes into dest.
64 * always starts at the first kfuse.
66 int tegra_kfuse_read(void *dest, size_t len)
71 if (len > KFUSE_DATA_SZ)
74 tegra_kfuse_writel(KFUSE_KEYADDR_AUTOINC, KFUSE_KEYADDR);
77 if ((tegra_kfuse_readl(KFUSE_STATE) & KFUSE_STATE_CRCPASS) == 0) {
78 pr_err("kfuse: crc failed\n");
82 for (cnt = 0; cnt < len; cnt += 4) {
83 v = tegra_kfuse_readl(KFUSE_KEYS);
84 memcpy(dest + cnt, &v, sizeof v);