* [PATCH v8 0/6] efuse driver for Tegra
@ 2014-06-12 15:36 Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel Peter De Schrijver
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Peter De Schrijver @ 2014-06-12 15:36 UTC (permalink / raw)
To: linux-arm-kernel
This driver allows userspace to read the raw efuse data. Its userspace
interface is modelled after the sunxi_sid driver which provides similar
functionality for some Allwinner SoCs. It has been tested on
Tegra20 (ventana), Tegra30 (beaverboard), Tegra114 (dalmore) and
Tegra124 (jetson TK1).
Changes since v1:
* Add documentation for sysfs interface
* Cleanup messages
Changes since v2:
* Incorporate early fuse code
* Remove module support
* Make driver always build when Tegra platform is selected
* Add DT binding document
* Address comments on v2
Changes since v3:
* Document sysfs file format
* Added apbmisc DT node for access to the apbmisc registers
* Address comments on v3
Changes since v4:
* Provide fallback to hardcoded 0x70000800 in case the apbmisc DT node is
missing. This is exactly what the current code does and prevents a system
crash in that case due to an invalid memory access by tegra_read_chipid()
* Added tegra_fuse_readl() function for drivers to read calibration data
Changes since v5:
* Fix kernel panic when booting on Tegra20 A03 with a missing fuse DT node
* Incorporate review comments
Changes since v6:
* Add the fix when booting on Tegra20 A03 which was supposed to be in v6 but
missing
Changes since v7:
* Initialize speedo info and randomness in early boot
* Expose speedo, sku and revision related info in tegra_sku_info
* Move APB DMA into Tegra20 fuse driver and remove apbio
* Make code more complex to support systems without conforming DT
Peter De Schrijver (6):
ARM: tegra: export apb dma readl/writel
ARM: tegra: move fuse exports to tegra-soc.h
misc: fuse: Add efuse driver for Tegra
ARM: tegra: Add efuse and apbmisc bindings
ARM: tegra: build new fuse driver in drivers/misc
misc: fuse: move APB DMA into Tegra20 fuse driver
Documentation/ABI/testing/sysfs-driver-tegra-fuse | 11 +
.../bindings/fuse/nvidia,tegra20-fuse.txt | 40 +++
.../bindings/misc/nvidia,tegra20-apbmisc.txt | 13 +
arch/arm/boot/dts/tegra114.dtsi | 15 +
arch/arm/boot/dts/tegra124.dtsi | 15 +
arch/arm/boot/dts/tegra20.dtsi | 15 +
arch/arm/boot/dts/tegra30.dtsi | 15 +
arch/arm/mach-tegra/Makefile | 5 -
arch/arm/mach-tegra/apbio.c | 206 --------------
arch/arm/mach-tegra/apbio.h | 22 --
arch/arm/mach-tegra/cpuidle.c | 2 +-
arch/arm/mach-tegra/flowctrl.c | 2 +-
arch/arm/mach-tegra/fuse.c | 252 -----------------
arch/arm/mach-tegra/fuse.h | 79 ------
arch/arm/mach-tegra/hotplug.c | 2 +-
arch/arm/mach-tegra/platsmp.c | 2 +-
arch/arm/mach-tegra/pm.c | 2 +-
arch/arm/mach-tegra/pmc.c | 2 +-
arch/arm/mach-tegra/powergate.c | 2 +-
arch/arm/mach-tegra/reset-handler.S | 2 +-
arch/arm/mach-tegra/reset.c | 2 +-
arch/arm/mach-tegra/sleep-tegra30.S | 2 +-
arch/arm/mach-tegra/tegra.c | 7 +-
arch/arm/mach-tegra/tegra114_speedo.c | 104 -------
arch/arm/mach-tegra/tegra20_speedo.c | 109 --------
arch/arm/mach-tegra/tegra30_speedo.c | 292 --------------------
drivers/misc/Makefile | 1 +
drivers/misc/fuse/Makefile | 1 +
drivers/misc/fuse/tegra/Makefile | 8 +
drivers/misc/fuse/tegra/fuse-tegra.c | 154 ++++++++++
drivers/misc/fuse/tegra/fuse-tegra20.c | 214 ++++++++++++++
drivers/misc/fuse/tegra/fuse-tegra30.c | 223 +++++++++++++++
drivers/misc/fuse/tegra/fuse.h | 71 +++++
drivers/misc/fuse/tegra/speedo-tegra114.c | 109 ++++++++
drivers/misc/fuse/tegra/speedo-tegra124.c | 167 +++++++++++
drivers/misc/fuse/tegra/speedo-tegra20.c | 109 ++++++++
drivers/misc/fuse/tegra/speedo-tegra30.c | 287 +++++++++++++++++++
drivers/misc/fuse/tegra/tegra-apbmisc.c | 110 ++++++++
include/linux/tegra-soc.h | 42 +++
39 files changed, 1633 insertions(+), 1083 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-driver-tegra-fuse
create mode 100644 Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt
create mode 100644 Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt
delete mode 100644 arch/arm/mach-tegra/apbio.c
delete mode 100644 arch/arm/mach-tegra/apbio.h
delete mode 100644 arch/arm/mach-tegra/fuse.c
delete mode 100644 arch/arm/mach-tegra/fuse.h
delete mode 100644 arch/arm/mach-tegra/tegra114_speedo.c
delete mode 100644 arch/arm/mach-tegra/tegra20_speedo.c
delete mode 100644 arch/arm/mach-tegra/tegra30_speedo.c
create mode 100644 drivers/misc/fuse/Makefile
create mode 100644 drivers/misc/fuse/tegra/Makefile
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra.c
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra20.c
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra30.c
create mode 100644 drivers/misc/fuse/tegra/fuse.h
create mode 100644 drivers/misc/fuse/tegra/speedo-tegra114.c
create mode 100644 drivers/misc/fuse/tegra/speedo-tegra124.c
create mode 100644 drivers/misc/fuse/tegra/speedo-tegra20.c
create mode 100644 drivers/misc/fuse/tegra/speedo-tegra30.c
create mode 100644 drivers/misc/fuse/tegra/tegra-apbmisc.c
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
@ 2014-06-12 15:36 ` Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 2/6] ARM: tegra: move fuse exports to tegra-soc.h Peter De Schrijver
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Peter De Schrijver @ 2014-06-12 15:36 UTC (permalink / raw)
To: linux-arm-kernel
Export APB DMA readl and writel. These are needed because we can't access
the fuses directly on Tegra20 without potentially causing a system hang.
Also have the APB DMA readl and writel return an error in case of a read
failure instead of just returning zero or ignore write failures.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/apbio.c | 51 ++++++++++++++++++++++++++----------------
include/linux/tegra-soc.h | 14 +++++++++++
2 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index bc47197..e0bf49d 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -32,8 +32,8 @@ static u32 *tegra_apb_bb;
static dma_addr_t tegra_apb_bb_phys;
static DECLARE_COMPLETION(tegra_apb_wait);
-static u32 tegra_apb_readl_direct(unsigned long offset);
-static void tegra_apb_writel_direct(u32 value, unsigned long offset);
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value);
+static int tegra_apb_writel_direct(u32 value, unsigned long offset);
static struct dma_chan *tegra_apb_dma_chan;
static struct dma_slave_config dma_sconfig;
@@ -128,58 +128,64 @@ static int do_dma_transfer(unsigned long apb_add,
return 0;
}
-static u32 tegra_apb_readl_using_dma(unsigned long offset)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
{
int ret;
if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
- return tegra_apb_readl_direct(offset);
+ return tegra_apb_readl_direct(offset, value);
mutex_lock(&tegra_apb_dma_lock);
ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);
- if (ret < 0) {
+ if (ret < 0)
pr_err("error in reading offset 0x%08lx using dma\n", offset);
- *(u32 *)tegra_apb_bb = 0;
- }
+ else
+ *value = *tegra_apb_bb;
+
mutex_unlock(&tegra_apb_dma_lock);
- return *((u32 *)tegra_apb_bb);
+
+ return ret;
}
-static void tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
{
int ret;
- if (!tegra_apb_dma_chan && !tegra_apb_dma_init()) {
- tegra_apb_writel_direct(value, offset);
- return;
- }
+ if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
+ return tegra_apb_writel_direct(value, offset);
mutex_lock(&tegra_apb_dma_lock);
*((u32 *)tegra_apb_bb) = value;
ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);
+ mutex_unlock(&tegra_apb_dma_lock);
if (ret < 0)
pr_err("error in writing offset 0x%08lx using dma\n", offset);
- mutex_unlock(&tegra_apb_dma_lock);
+
+ return ret;
}
#else
#define tegra_apb_readl_using_dma tegra_apb_readl_direct
#define tegra_apb_writel_using_dma tegra_apb_writel_direct
#endif
-typedef u32 (*apbio_read_fptr)(unsigned long offset);
-typedef void (*apbio_write_fptr)(u32 value, unsigned long offset);
+typedef int (*apbio_read_fptr)(unsigned long offset, u32 *value);
+typedef int (*apbio_write_fptr)(u32 value, unsigned long offset);
static apbio_read_fptr apbio_read;
static apbio_write_fptr apbio_write;
-static u32 tegra_apb_readl_direct(unsigned long offset)
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value)
{
- return readl(IO_ADDRESS(offset));
+ *value = readl(IO_ADDRESS(offset));
+
+ return 0;
}
-static void tegra_apb_writel_direct(u32 value, unsigned long offset)
+static int tegra_apb_writel_direct(u32 value, unsigned long offset)
{
writel(value, IO_ADDRESS(offset));
+
+ return 0;
}
void tegra_apb_io_init(void)
@@ -197,7 +203,12 @@ void tegra_apb_io_init(void)
u32 tegra_apb_readl(unsigned long offset)
{
- return apbio_read(offset);
+ u32 val;
+
+ if (apbio_read(offset, &val) < 0)
+ return 0;
+ else
+ return val;
}
void tegra_apb_writel(u32 value, unsigned long offset)
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index 95f611d..b02d73b 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -19,4 +19,18 @@
u32 tegra_read_chipid(void);
+
+#if defined(CONFIG_TEGRA20_APB_DMA)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value);
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset);
+#else
+static inline int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
+{
+ return -EINVAL;
+}
+static inline int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+{
+ return -EINVAL;
+}
+#endif
#endif /* __LINUX_TEGRA_SOC_H_ */
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 2/6] ARM: tegra: move fuse exports to tegra-soc.h
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel Peter De Schrijver
@ 2014-06-12 15:36 ` Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 4/6] ARM: tegra: Add efuse and apbmisc bindings Peter De Schrijver
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Peter De Schrijver @ 2014-06-12 15:36 UTC (permalink / raw)
To: linux-arm-kernel
All fuse related functionality will move to a driver in the following patches.
To prepare for this, export all the required functionality in a global header
file and move all users of fuse.h to tegra-soc.h. While we're at it, remove
tegra_bct_strapping, as its only user was removed in Commit a7cbe92cef27
("ARM: tegra: remove tegra EMC scaling driver").
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/cpuidle.c | 2 +-
arch/arm/mach-tegra/flowctrl.c | 2 +-
arch/arm/mach-tegra/fuse.h | 18 ------------------
arch/arm/mach-tegra/hotplug.c | 2 +-
arch/arm/mach-tegra/platsmp.c | 2 +-
arch/arm/mach-tegra/pm.c | 2 +-
arch/arm/mach-tegra/pmc.c | 2 +-
arch/arm/mach-tegra/powergate.c | 2 +-
arch/arm/mach-tegra/reset-handler.S | 2 +-
arch/arm/mach-tegra/reset.c | 2 +-
arch/arm/mach-tegra/sleep-tegra30.S | 2 +-
arch/arm/mach-tegra/tegra.c | 2 +-
arch/arm/mach-tegra/tegra114_speedo.c | 1 +
arch/arm/mach-tegra/tegra20_speedo.c | 1 +
arch/arm/mach-tegra/tegra30_speedo.c | 1 +
include/linux/tegra-soc.h | 24 ++++++++++++++++++++++++
16 files changed, 38 insertions(+), 29 deletions(-)
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index 7bc5d8d..ff0a10b 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -23,8 +23,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/tegra-soc.h>
-#include "fuse.h"
#include "cpuidle.h"
void __init tegra_cpuidle_init(void)
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index ce8ab8a..4b31091 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -22,10 +22,10 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/cpumask.h>
+#include <linux/tegra-soc.h>
#include "flowctrl.h"
#include "iomap.h"
-#include "fuse.h"
static u8 flowctrl_offset_halt_cpu[] = {
FLOW_CTRL_HALT_CPU0_EVENTS,
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index c01d047..b17c4ba 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -26,21 +26,7 @@
#define SKU_ID_AP25E 27
#define SKU_ID_T25E 28
-#define TEGRA20 0x20
-#define TEGRA30 0x30
-#define TEGRA114 0x35
-#define TEGRA124 0x40
-
#ifndef __ASSEMBLY__
-enum tegra_revision {
- TEGRA_REVISION_UNKNOWN = 0,
- TEGRA_REVISION_A01,
- TEGRA_REVISION_A02,
- TEGRA_REVISION_A03,
- TEGRA_REVISION_A03p,
- TEGRA_REVISION_A04,
- TEGRA_REVISION_MAX,
-};
extern int tegra_sku_id;
extern int tegra_cpu_process_id;
@@ -48,12 +34,8 @@ extern int tegra_core_process_id;
extern int tegra_chip_id;
extern int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
extern int tegra_soc_speedo_id;
-extern enum tegra_revision tegra_revision;
-
-extern int tegra_bct_strapping;
unsigned long long tegra_chip_uid(void);
-void tegra_init_fuse(void);
bool tegra_spare_fuse(int bit);
u32 tegra_fuse_readl(unsigned long offset);
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index ff26af2..38c5170 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -10,10 +10,10 @@
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/clk/tegra.h>
+#include <linux/tegra-soc.h>
#include <asm/smp_plat.h>
-#include "fuse.h"
#include "sleep.h"
static void (*tegra_hotplug_shutdown)(void);
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 929d104..d9878ac 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -19,13 +19,13 @@
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/clk/tegra.h>
+#include <linux/tegra-soc.h>
#include <asm/cacheflush.h>
#include <asm/mach-types.h>
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
-#include "fuse.h"
#include "flowctrl.h"
#include "reset.h"
#include "pmc.h"
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index f55b05a..d7e6370 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -26,6 +26,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/clk/tegra.h>
+#include <linux/tegra-soc.h>
#include <asm/smp_plat.h>
#include <asm/cacheflush.h>
@@ -37,7 +38,6 @@
#include "iomap.h"
#include "reset.h"
#include "flowctrl.h"
-#include "fuse.h"
#include "pm.h"
#include "pmc.h"
#include "sleep.h"
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index fb79202..d8fe587 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -21,9 +21,9 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/tegra-powergate.h>
+#include <linux/tegra-soc.h>
#include "flowctrl.h"
-#include "fuse.h"
#include "pm.h"
#include "pmc.h"
#include "sleep.h"
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index 4cefc5c..50a9af4 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -30,8 +30,8 @@
#include <linux/spinlock.h>
#include <linux/clk/tegra.h>
#include <linux/tegra-powergate.h>
+#include <linux/tegra-soc.h>
-#include "fuse.h"
#include "iomap.h"
#define DPD_SAMPLE 0x020
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 8c1ba4f..0c480d69 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -20,9 +20,9 @@
#include <asm/cache.h>
#include <asm/asm-offsets.h>
#include <asm/hardware/cache-l2x0.h>
+#include <linux/tegra-soc.h>
#include "flowctrl.h"
-#include "fuse.h"
#include "iomap.h"
#include "reset.h"
#include "sleep.h"
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 146fe8e..203bac5 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -22,12 +22,12 @@
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/firmware.h>
+#include <linux/tegra-soc.h>
#include "iomap.h"
#include "irammap.h"
#include "reset.h"
#include "sleep.h"
-#include "fuse.h"
#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
TEGRA_IRAM_RESET_HANDLER_OFFSET)
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index b16d4a57..f808c2c 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -15,13 +15,13 @@
*/
#include <linux/linkage.h>
+#include <linux/tegra-soc.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/cache.h>
#include "irammap.h"
-#include "fuse.h"
#include "sleep.h"
#include "flowctrl.h"
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index 6191603..e48b271 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -34,6 +34,7 @@
#include <linux/usb/tegra_usb_phy.h>
#include <linux/clk/tegra.h>
#include <linux/irqchip.h>
+#include <linux/tegra-soc.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach-types.h>
@@ -46,7 +47,6 @@
#include "board.h"
#include "common.h"
#include "cpuidle.h"
-#include "fuse.h"
#include "iomap.h"
#include "irq.h"
#include "pmc.h"
diff --git a/arch/arm/mach-tegra/tegra114_speedo.c b/arch/arm/mach-tegra/tegra114_speedo.c
index 5218d48..7c73716 100644
--- a/arch/arm/mach-tegra/tegra114_speedo.c
+++ b/arch/arm/mach-tegra/tegra114_speedo.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/bug.h>
+#include <linux/tegra-soc.h>
#include "fuse.h"
diff --git a/arch/arm/mach-tegra/tegra20_speedo.c b/arch/arm/mach-tegra/tegra20_speedo.c
index fa6eb57..3b1bb53 100644
--- a/arch/arm/mach-tegra/tegra20_speedo.c
+++ b/arch/arm/mach-tegra/tegra20_speedo.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/bug.h>
+#include <linux/tegra-soc.h>
#include "fuse.h"
diff --git a/arch/arm/mach-tegra/tegra30_speedo.c b/arch/arm/mach-tegra/tegra30_speedo.c
index 125cb16..81a958d 100644
--- a/arch/arm/mach-tegra/tegra30_speedo.c
+++ b/arch/arm/mach-tegra/tegra30_speedo.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/bug.h>
+#include <linux/tegra-soc.h>
#include "fuse.h"
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index b02d73b..db93b77 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -17,8 +17,29 @@
#ifndef __LINUX_TEGRA_SOC_H_
#define __LINUX_TEGRA_SOC_H_
+#define TEGRA20 0x20
+#define TEGRA30 0x30
+#define TEGRA114 0x35
+#define TEGRA124 0x40
+
+#ifndef __ASSEMBLY__
+
+enum tegra_revision {
+ TEGRA_REVISION_UNKNOWN = 0,
+ TEGRA_REVISION_A01,
+ TEGRA_REVISION_A02,
+ TEGRA_REVISION_A03,
+ TEGRA_REVISION_A03p,
+ TEGRA_REVISION_A04,
+ TEGRA_REVISION_MAX,
+};
+
+u32 tegra_read_straps(void);
u32 tegra_read_chipid(void);
+void tegra_init_fuse(void);
+extern int tegra_chip_id;
+extern enum tegra_revision tegra_revision;
#if defined(CONFIG_TEGRA20_APB_DMA)
int tegra_apb_readl_using_dma(unsigned long offset, u32 *value);
@@ -33,4 +54,7 @@ static inline int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
return -EINVAL;
}
#endif
+
+#endif /* __ASSEMBLY__ */
+
#endif /* __LINUX_TEGRA_SOC_H_ */
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 4/6] ARM: tegra: Add efuse and apbmisc bindings
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 2/6] ARM: tegra: move fuse exports to tegra-soc.h Peter De Schrijver
@ 2014-06-12 15:36 ` Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 5/6] ARM: tegra: build new fuse driver in drivers/misc Peter De Schrijver
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Peter De Schrijver @ 2014-06-12 15:36 UTC (permalink / raw)
To: linux-arm-kernel
Add efuse and apbmisc bindings for Tegra20, Tegra30, Tegra114 and Tegra124.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
.../bindings/fuse/nvidia,tegra20-fuse.txt | 40 ++++++++++++++++++++
.../bindings/misc/nvidia,tegra20-apbmisc.txt | 13 ++++++
arch/arm/boot/dts/tegra114.dtsi | 15 +++++++
arch/arm/boot/dts/tegra124.dtsi | 15 +++++++
arch/arm/boot/dts/tegra20.dtsi | 15 +++++++
arch/arm/boot/dts/tegra30.dtsi | 15 +++++++
6 files changed, 113 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt
create mode 100644 Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt
diff --git a/Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt b/Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt
new file mode 100644
index 0000000..d8c98c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt
@@ -0,0 +1,40 @@
+NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse block.
+
+Required properties:
+- compatible : should be:
+ "nvidia,tegra20-efuse"
+ "nvidia,tegra30-efuse"
+ "nvidia,tegra114-efuse"
+ "nvidia,tegra124-efuse"
+ Details:
+ nvidia,tegra20-efuse: Tegra20 requires using APB DMA to read the fuse data
+ due to a hardware bug. Tegra20 also lacks certain information which is
+ available in later generations such as fab code, lot code, wafer id,..
+ nvidia,tegra30-efuse, nvidia,tegra114-efuse and nvidia,tegra124-efuse:
+ The differences between these SoCs are the size of the efuse array,
+ the location of the spare (OEM programmable) bits and the location of
+ the speedo data.
+- reg: Should contain 1 entry: the entry gives the physical address and length
+ of the fuse registers.
+- clocks: Must contain an entry for each entry in clock-names.
+ See ../clocks/clock-bindings.txt for details.
+- clock-names: Must include the following entries:
+ - fuse
+- resets: Must contain an entry for each entry in reset-names.
+ See ../reset/reset.txt for details.
+- reset-names: Must include the following entries:
+ - fuse
+
+Example:
+
+ fuse at 7000f800 {
+ compatible = "nvidia,tegra20-efuse";
+ reg = <0x7000F800 0x400>,
+ <0x70000000 0x400>;
+ clocks = <&tegra_car TEGRA20_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
+
diff --git a/Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt b/Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt
new file mode 100644
index 0000000..b97b8be
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt
@@ -0,0 +1,13 @@
+NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block
+
+Required properties:
+- compatible : should be:
+ "nvidia,tegra20-apbmisc"
+ "nvidia,tegra30-apbmisc"
+ "nvidia,tegra114-apbmisc"
+ "nvidia,tegra124-apbmisc"
+- reg: Should contain 2 entries: the first entry gives the physical address
+ and length of the registers which contain revision and debug features.
+ The second entry gives the physical address and length of the
+ registers indicating the strapping options.
+
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
index fdc559a..335a1d8 100644
--- a/arch/arm/boot/dts/tegra114.dtsi
+++ b/arch/arm/boot/dts/tegra114.dtsi
@@ -220,6 +220,12 @@
interrupt-controller;
};
+ apbmisc at 70000800 {
+ compatible = "nvidia,tegra114-apbmisc", "nvidia,tegra20-apbmisc";
+ reg = <0x70000800 0x64 /* Chip revision */
+ 0x70000008 0x04>; /* Strapping options */
+ };
+
pinmux: pinmux at 70000868 {
compatible = "nvidia,tegra114-pinmux";
reg = <0x70000868 0x148 /* Pad control registers */
@@ -485,6 +491,15 @@
clock-names = "pclk", "clk32k_in";
};
+ fuse@7000f800 {
+ compatible = "nvidia,tegra114-efuse";
+ reg = <0x7000f800 0x400>;
+ clocks = <&tegra_car TEGRA114_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
iommu at 70019010 {
compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu";
reg = <0x70019010 0x02c
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 6d540a0..9739a13 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -167,6 +167,12 @@
#dma-cells = <1>;
};
+ apbmisc at 0,70000800 {
+ compatible = "nvidia,tegra124-apbmisc", "nvidia,tegra20-apbmisc";
+ reg = <0x0 0x70000800 0x0 0x64>, /* Chip revision */
+ <0x0 0x7000E864 0x0 0x04>; /* Strapping options */
+ };
+
pinmux: pinmux at 0,70000868 {
compatible = "nvidia,tegra124-pinmux";
reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */
@@ -437,6 +443,15 @@
clock-names = "pclk", "clk32k_in";
};
+ fuse at 0,7000f800 {
+ compatible = "nvidia,tegra124-efuse";
+ reg = <0x0 0x7000f800 0x0 0x400>;
+ clocks = <&tegra_car TEGRA124_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
sdhci at 0,700b0000 {
compatible = "nvidia,tegra124-sdhci";
reg = <0x0 0x700b0000 0x0 0x200>;
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index a7ddf70..243d84c 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -236,6 +236,12 @@
interrupt-controller;
};
+ apbmisc at 70000800 {
+ compatible = "nvidia,tegra20-apbmisc";
+ reg = <0x70000800 0x64 /* Chip revision */
+ 0x70000008 0x04>; /* Strapping options */
+ };
+
pinmux: pinmux at 70000014 {
compatible = "nvidia,tegra20-pinmux";
reg = <0x70000014 0x10 /* Tri-state registers */
@@ -545,6 +551,15 @@
#size-cells = <0>;
};
+ fuse at 7000f800 {
+ compatible = "nvidia,tegra20-efuse";
+ reg = <0x7000F800 0x400>;
+ clocks = <&tegra_car TEGRA20_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
pcie-controller at 80003000 {
compatible = "nvidia,tegra20-pcie";
device_type = "pci";
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index dec4fc8..0b1ede9 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -335,6 +335,12 @@
interrupt-controller;
};
+ apbmisc at 70000800 {
+ compatible = "nvidia,tegra30-apbmisc", "nvidia,tegra20-apbmisc";
+ reg = <0x70000800 0x64 /* Chip revision */
+ 0x70000008 0x04>; /* Strapping options */
+ };
+
pinmux: pinmux at 70000868 {
compatible = "nvidia,tegra30-pinmux";
reg = <0x70000868 0xd4 /* Pad control registers */
@@ -631,6 +637,15 @@
nvidia,ahb = <&ahb>;
};
+ fuse at 7000f800 {
+ compatible = "nvidia,tegra30-efuse";
+ reg = <0x7000f800 0x400>;
+ clocks = <&tegra_car TEGRA30_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
ahub at 70080000 {
compatible = "nvidia,tegra30-ahub";
reg = <0x70080000 0x200
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 5/6] ARM: tegra: build new fuse driver in drivers/misc
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
` (2 preceding siblings ...)
2014-06-12 15:36 ` [PATCH v8 4/6] ARM: tegra: Add efuse and apbmisc bindings Peter De Schrijver
@ 2014-06-12 15:36 ` Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 6/6] misc: fuse: move APB DMA into Tegra20 fuse driver Peter De Schrijver
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Peter De Schrijver @ 2014-06-12 15:36 UTC (permalink / raw)
To: linux-arm-kernel
The Tegra fuse code has moved to drivers/misc/fuse/tegra. Enable the
building of that code, and disable the building of the old fuse code in
arch/arm/mach-tegra/. Also move the only user of tegra_revision over to
tegra_sku_info.revision and export tegra_fuse_readl to allow drivers to read
calibration fuses.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/Makefile | 4 -
arch/arm/mach-tegra/fuse.c | 252 ----------------------------
arch/arm/mach-tegra/fuse.h | 61 -------
arch/arm/mach-tegra/tegra.c | 3 +-
arch/arm/mach-tegra/tegra114_speedo.c | 105 ------------
arch/arm/mach-tegra/tegra20_speedo.c | 110 ------------
arch/arm/mach-tegra/tegra30_speedo.c | 293 ---------------------------------
drivers/misc/Makefile | 1 +
drivers/misc/fuse/tegra/fuse-tegra.c | 10 +
include/linux/tegra-soc.h | 2 +-
10 files changed, 14 insertions(+), 827 deletions(-)
delete mode 100644 arch/arm/mach-tegra/fuse.c
delete mode 100644 arch/arm/mach-tegra/fuse.h
delete mode 100644 arch/arm/mach-tegra/tegra114_speedo.c
delete mode 100644 arch/arm/mach-tegra/tegra20_speedo.c
delete mode 100644 arch/arm/mach-tegra/tegra30_speedo.c
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 6fbfbb7..e8601bb 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -2,7 +2,6 @@ asflags-y += -march=armv7-a
obj-y += io.o
obj-y += irq.o
-obj-y += fuse.o
obj-y += pmc.o
obj-y += flowctrl.o
obj-y += powergate.o
@@ -13,13 +12,11 @@ obj-y += reset-handler.o
obj-y += sleep.o
obj-y += tegra.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
ifeq ($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
endif
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
ifeq ($(CONFIG_CPU_IDLE),y)
@@ -28,7 +25,6 @@ endif
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
ifeq ($(CONFIG_CPU_IDLE),y)
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
deleted file mode 100644
index c9ac23b..0000000
--- a/arch/arm/mach-tegra/fuse.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * arch/arm/mach-tegra/fuse.c
- *
- * Copyright (C) 2010 Google, Inc.
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
- *
- * Author:
- * Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/export.h>
-#include <linux/random.h>
-#include <linux/clk.h>
-#include <linux/tegra-soc.h>
-
-#include "fuse.h"
-#include "iomap.h"
-#include "apbio.h"
-
-/* Tegra20 only */
-#define FUSE_UID_LOW 0x108
-#define FUSE_UID_HIGH 0x10c
-
-/* Tegra30 and later */
-#define FUSE_VENDOR_CODE 0x200
-#define FUSE_FAB_CODE 0x204
-#define FUSE_LOT_CODE_0 0x208
-#define FUSE_LOT_CODE_1 0x20c
-#define FUSE_WAFER_ID 0x210
-#define FUSE_X_COORDINATE 0x214
-#define FUSE_Y_COORDINATE 0x218
-
-#define FUSE_SKU_INFO 0x110
-
-#define TEGRA20_FUSE_SPARE_BIT 0x200
-#define TEGRA30_FUSE_SPARE_BIT 0x244
-
-int tegra_sku_id;
-int tegra_cpu_process_id;
-int tegra_core_process_id;
-int tegra_chip_id;
-int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
-int tegra_soc_speedo_id;
-enum tegra_revision tegra_revision;
-
-static struct clk *fuse_clk;
-static int tegra_fuse_spare_bit;
-static void (*tegra_init_speedo_data)(void);
-
-/* The BCT to use at boot is specified by board straps that can be read
- * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
- */
-int tegra_bct_strapping;
-
-#define STRAP_OPT 0x008
-#define GMI_AD0 (1 << 4)
-#define GMI_AD1 (1 << 5)
-#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
-#define RAM_CODE_SHIFT 4
-
-static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
- [TEGRA_REVISION_UNKNOWN] = "unknown",
- [TEGRA_REVISION_A01] = "A01",
- [TEGRA_REVISION_A02] = "A02",
- [TEGRA_REVISION_A03] = "A03",
- [TEGRA_REVISION_A03p] = "A03 prime",
- [TEGRA_REVISION_A04] = "A04",
-};
-
-static void tegra_fuse_enable_clk(void)
-{
- if (IS_ERR(fuse_clk))
- fuse_clk = clk_get_sys(NULL, "fuse");
- if (IS_ERR(fuse_clk))
- return;
- clk_prepare_enable(fuse_clk);
-}
-
-static void tegra_fuse_disable_clk(void)
-{
- if (IS_ERR(fuse_clk))
- return;
- clk_disable_unprepare(fuse_clk);
-}
-
-u32 tegra_fuse_readl(unsigned long offset)
-{
- return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
-}
-
-bool tegra_spare_fuse(int bit)
-{
- bool ret;
-
- tegra_fuse_enable_clk();
-
- ret = tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);
-
- tegra_fuse_disable_clk();
-
- return ret;
-}
-
-static enum tegra_revision tegra_get_revision(u32 id)
-{
- u32 minor_rev = (id >> 16) & 0xf;
-
- switch (minor_rev) {
- case 1:
- return TEGRA_REVISION_A01;
- case 2:
- return TEGRA_REVISION_A02;
- case 3:
- if (tegra_chip_id == TEGRA20 &&
- (tegra_spare_fuse(18) || tegra_spare_fuse(19)))
- return TEGRA_REVISION_A03p;
- else
- return TEGRA_REVISION_A03;
- case 4:
- return TEGRA_REVISION_A04;
- default:
- return TEGRA_REVISION_UNKNOWN;
- }
-}
-
-static void tegra_get_process_id(void)
-{
- u32 reg;
-
- tegra_fuse_enable_clk();
-
- reg = tegra_fuse_readl(tegra_fuse_spare_bit);
- tegra_cpu_process_id = (reg >> 6) & 3;
- reg = tegra_fuse_readl(tegra_fuse_spare_bit);
- tegra_core_process_id = (reg >> 12) & 3;
-
- tegra_fuse_disable_clk();
-}
-
-u32 tegra_read_chipid(void)
-{
- return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
-}
-
-static void __init tegra20_fuse_init_randomness(void)
-{
- u32 randomness[2];
-
- randomness[0] = tegra_fuse_readl(FUSE_UID_LOW);
- randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH);
-
- add_device_randomness(randomness, sizeof(randomness));
-}
-
-/* Applies to Tegra30 or later */
-static void __init tegra30_fuse_init_randomness(void)
-{
- u32 randomness[7];
-
- randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE);
- randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE);
- randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0);
- randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1);
- randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID);
- randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE);
- randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE);
-
- add_device_randomness(randomness, sizeof(randomness));
-}
-
-void __init tegra_init_fuse(void)
-{
- u32 id;
- u32 randomness[5];
-
- u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
- reg |= 1 << 28;
- writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
-
- /*
- * Enable FUSE clock. This needs to be hardcoded because the clock
- * subsystem is not active during early boot.
- */
- reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
- reg |= 1 << 7;
- writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
- fuse_clk = ERR_PTR(-EINVAL);
-
- reg = tegra_fuse_readl(FUSE_SKU_INFO);
- randomness[0] = reg;
- tegra_sku_id = reg & 0xFF;
-
- reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
- randomness[1] = reg;
- tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
-
- id = tegra_read_chipid();
- randomness[2] = id;
- tegra_chip_id = (id >> 8) & 0xff;
-
- switch (tegra_chip_id) {
- case TEGRA20:
- tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
- tegra_init_speedo_data = &tegra20_init_speedo_data;
- break;
- case TEGRA30:
- tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
- tegra_init_speedo_data = &tegra30_init_speedo_data;
- break;
- case TEGRA114:
- tegra_init_speedo_data = &tegra114_init_speedo_data;
- break;
- default:
- pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
- tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
- tegra_init_speedo_data = &tegra_get_process_id;
- }
-
- tegra_revision = tegra_get_revision(id);
- tegra_init_speedo_data();
- randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id;
- randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id;
-
- add_device_randomness(randomness, sizeof(randomness));
- switch (tegra_chip_id) {
- case TEGRA20:
- tegra20_fuse_init_randomness();
- break;
- case TEGRA30:
- case TEGRA114:
- default:
- tegra30_fuse_init_randomness();
- break;
- }
-
- pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
- tegra_revision_name[tegra_revision],
- tegra_sku_id, tegra_cpu_process_id,
- tegra_core_process_id);
-}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
deleted file mode 100644
index b17c4ba..0000000
--- a/arch/arm/mach-tegra/fuse.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc.
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
- *
- * Author:
- * Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __MACH_TEGRA_FUSE_H
-#define __MACH_TEGRA_FUSE_H
-
-#define SKU_ID_T20 8
-#define SKU_ID_T25SE 20
-#define SKU_ID_AP25 23
-#define SKU_ID_T25 24
-#define SKU_ID_AP25E 27
-#define SKU_ID_T25E 28
-
-#ifndef __ASSEMBLY__
-
-extern int tegra_sku_id;
-extern int tegra_cpu_process_id;
-extern int tegra_core_process_id;
-extern int tegra_chip_id;
-extern int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
-extern int tegra_soc_speedo_id;
-
-unsigned long long tegra_chip_uid(void);
-bool tegra_spare_fuse(int bit);
-u32 tegra_fuse_readl(unsigned long offset);
-
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void tegra20_init_speedo_data(void);
-#else
-static inline void tegra20_init_speedo_data(void) {}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-void tegra30_init_speedo_data(void);
-#else
-static inline void tegra30_init_speedo_data(void) {}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
-void tegra114_init_speedo_data(void);
-#else
-static inline void tegra114_init_speedo_data(void) {}
-#endif
-#endif /* __ASSEMBLY__ */
-
-#endif
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index e48b271..093d5f4 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -131,7 +131,8 @@ static void __init tegra_dt_init(void)
goto out;
soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra");
- soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_revision);
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d",
+ tegra_sku_info.revision);
soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", tegra_chip_id);
soc_dev = soc_device_register(soc_dev_attr);
diff --git a/arch/arm/mach-tegra/tegra114_speedo.c b/arch/arm/mach-tegra/tegra114_speedo.c
deleted file mode 100644
index 7c73716..0000000
--- a/arch/arm/mach-tegra/tegra114_speedo.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/bug.h>
-#include <linux/tegra-soc.h>
-
-#include "fuse.h"
-
-#define CORE_PROCESS_CORNERS_NUM 2
-#define CPU_PROCESS_CORNERS_NUM 2
-
-enum {
- THRESHOLD_INDEX_0,
- THRESHOLD_INDEX_1,
- THRESHOLD_INDEX_COUNT,
-};
-
-static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
- {1123, UINT_MAX},
- {0, UINT_MAX},
-};
-
-static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
- {1695, UINT_MAX},
- {0, UINT_MAX},
-};
-
-static void rev_sku_to_speedo_ids(int rev, int sku, int *threshold)
-{
- u32 tmp;
-
- switch (sku) {
- case 0x00:
- case 0x10:
- case 0x05:
- case 0x06:
- tegra_cpu_speedo_id = 1;
- tegra_soc_speedo_id = 0;
- *threshold = THRESHOLD_INDEX_0;
- break;
-
- case 0x03:
- case 0x04:
- tegra_cpu_speedo_id = 2;
- tegra_soc_speedo_id = 1;
- *threshold = THRESHOLD_INDEX_1;
- break;
-
- default:
- pr_err("Tegra114 Unknown SKU %d\n", sku);
- tegra_cpu_speedo_id = 0;
- tegra_soc_speedo_id = 0;
- *threshold = THRESHOLD_INDEX_0;
- break;
- }
-
- if (rev == TEGRA_REVISION_A01) {
- tmp = tegra_fuse_readl(0x270) << 1;
- tmp |= tegra_fuse_readl(0x26c);
- if (!tmp)
- tegra_cpu_speedo_id = 0;
- }
-}
-
-void tegra114_init_speedo_data(void)
-{
- u32 cpu_speedo_val;
- u32 core_speedo_val;
- int threshold;
- int i;
-
- BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
- THRESHOLD_INDEX_COUNT);
- BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
- THRESHOLD_INDEX_COUNT);
-
- rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id, &threshold);
-
- cpu_speedo_val = tegra_fuse_readl(0x12c) + 1024;
- core_speedo_val = tegra_fuse_readl(0x134);
-
- for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++)
- if (cpu_speedo_val < cpu_process_speedos[threshold][i])
- break;
- tegra_cpu_process_id = i;
-
- for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++)
- if (core_speedo_val < core_process_speedos[threshold][i])
- break;
- tegra_core_process_id = i;
-}
diff --git a/arch/arm/mach-tegra/tegra20_speedo.c b/arch/arm/mach-tegra/tegra20_speedo.c
deleted file mode 100644
index 3b1bb53..0000000
--- a/arch/arm/mach-tegra/tegra20_speedo.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/bug.h>
-#include <linux/tegra-soc.h>
-
-#include "fuse.h"
-
-#define CPU_SPEEDO_LSBIT 20
-#define CPU_SPEEDO_MSBIT 29
-#define CPU_SPEEDO_REDUND_LSBIT 30
-#define CPU_SPEEDO_REDUND_MSBIT 39
-#define CPU_SPEEDO_REDUND_OFFS (CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT)
-
-#define CORE_SPEEDO_LSBIT 40
-#define CORE_SPEEDO_MSBIT 47
-#define CORE_SPEEDO_REDUND_LSBIT 48
-#define CORE_SPEEDO_REDUND_MSBIT 55
-#define CORE_SPEEDO_REDUND_OFFS (CORE_SPEEDO_REDUND_MSBIT - CORE_SPEEDO_MSBIT)
-
-#define SPEEDO_MULT 4
-
-#define PROCESS_CORNERS_NUM 4
-
-#define SPEEDO_ID_SELECT_0(rev) ((rev) <= 2)
-#define SPEEDO_ID_SELECT_1(sku) \
- (((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \
- ((sku) != 27) && ((sku) != 28))
-
-enum {
- SPEEDO_ID_0,
- SPEEDO_ID_1,
- SPEEDO_ID_2,
- SPEEDO_ID_COUNT,
-};
-
-static const u32 cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
- {315, 366, 420, UINT_MAX},
- {303, 368, 419, UINT_MAX},
- {316, 331, 383, UINT_MAX},
-};
-
-static const u32 core_process_speedos[][PROCESS_CORNERS_NUM] = {
- {165, 195, 224, UINT_MAX},
- {165, 195, 224, UINT_MAX},
- {165, 195, 224, UINT_MAX},
-};
-
-void tegra20_init_speedo_data(void)
-{
- u32 reg;
- u32 val;
- int i;
-
- BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT);
- BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT);
-
- if (SPEEDO_ID_SELECT_0(tegra_revision))
- tegra_soc_speedo_id = SPEEDO_ID_0;
- else if (SPEEDO_ID_SELECT_1(tegra_sku_id))
- tegra_soc_speedo_id = SPEEDO_ID_1;
- else
- tegra_soc_speedo_id = SPEEDO_ID_2;
-
- val = 0;
- for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) {
- reg = tegra_spare_fuse(i) |
- tegra_spare_fuse(i + CPU_SPEEDO_REDUND_OFFS);
- val = (val << 1) | (reg & 0x1);
- }
- val = val * SPEEDO_MULT;
- pr_debug("%s CPU speedo value %u\n", __func__, val);
-
- for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
- if (val <= cpu_process_speedos[tegra_soc_speedo_id][i])
- break;
- }
- tegra_cpu_process_id = i;
-
- val = 0;
- for (i = CORE_SPEEDO_MSBIT; i >= CORE_SPEEDO_LSBIT; i--) {
- reg = tegra_spare_fuse(i) |
- tegra_spare_fuse(i + CORE_SPEEDO_REDUND_OFFS);
- val = (val << 1) | (reg & 0x1);
- }
- val = val * SPEEDO_MULT;
- pr_debug("%s Core speedo value %u\n", __func__, val);
-
- for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
- if (val <= core_process_speedos[tegra_soc_speedo_id][i])
- break;
- }
- tegra_core_process_id = i;
-
- pr_info("Tegra20 Soc Speedo ID %d", tegra_soc_speedo_id);
-}
diff --git a/arch/arm/mach-tegra/tegra30_speedo.c b/arch/arm/mach-tegra/tegra30_speedo.c
deleted file mode 100644
index 81a958d..0000000
--- a/arch/arm/mach-tegra/tegra30_speedo.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/bug.h>
-#include <linux/tegra-soc.h>
-
-#include "fuse.h"
-
-#define CORE_PROCESS_CORNERS_NUM 1
-#define CPU_PROCESS_CORNERS_NUM 6
-
-#define FUSE_SPEEDO_CALIB_0 0x114
-#define FUSE_PACKAGE_INFO 0X1FC
-#define FUSE_TEST_PROG_VER 0X128
-
-#define G_SPEEDO_BIT_MINUS1 58
-#define G_SPEEDO_BIT_MINUS1_R 59
-#define G_SPEEDO_BIT_MINUS2 60
-#define G_SPEEDO_BIT_MINUS2_R 61
-#define LP_SPEEDO_BIT_MINUS1 62
-#define LP_SPEEDO_BIT_MINUS1_R 63
-#define LP_SPEEDO_BIT_MINUS2 64
-#define LP_SPEEDO_BIT_MINUS2_R 65
-
-enum {
- THRESHOLD_INDEX_0,
- THRESHOLD_INDEX_1,
- THRESHOLD_INDEX_2,
- THRESHOLD_INDEX_3,
- THRESHOLD_INDEX_4,
- THRESHOLD_INDEX_5,
- THRESHOLD_INDEX_6,
- THRESHOLD_INDEX_7,
- THRESHOLD_INDEX_8,
- THRESHOLD_INDEX_9,
- THRESHOLD_INDEX_10,
- THRESHOLD_INDEX_11,
- THRESHOLD_INDEX_COUNT,
-};
-
-static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
- {180},
- {170},
- {195},
- {180},
- {168},
- {192},
- {180},
- {170},
- {195},
- {180},
- {180},
- {180},
-};
-
-static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
- {306, 338, 360, 376, UINT_MAX},
- {295, 336, 358, 375, UINT_MAX},
- {325, 325, 358, 375, UINT_MAX},
- {325, 325, 358, 375, UINT_MAX},
- {292, 324, 348, 364, UINT_MAX},
- {324, 324, 348, 364, UINT_MAX},
- {324, 324, 348, 364, UINT_MAX},
- {295, 336, 358, 375, UINT_MAX},
- {358, 358, 358, 358, 397, UINT_MAX},
- {364, 364, 364, 364, 397, UINT_MAX},
- {295, 336, 358, 375, 391, UINT_MAX},
- {295, 336, 358, 375, 391, UINT_MAX},
-};
-
-static int threshold_index;
-static int package_id;
-
-static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
-{
- u32 reg;
- int ate_ver;
- int bit_minus1;
- int bit_minus2;
-
- reg = tegra_fuse_readl(FUSE_SPEEDO_CALIB_0);
-
- *speedo_lp = (reg & 0xFFFF) * 4;
- *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
-
- ate_ver = tegra_fuse_readl(FUSE_TEST_PROG_VER);
- pr_info("%s: ATE prog ver %d.%d\n", __func__, ate_ver/10, ate_ver%10);
-
- if (ate_ver >= 26) {
- bit_minus1 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1);
- bit_minus1 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1_R);
- bit_minus2 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2);
- bit_minus2 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2_R);
- *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
-
- bit_minus1 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS1);
- bit_minus1 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS1_R);
- bit_minus2 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS2);
- bit_minus2 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS2_R);
- *speedo_g |= (bit_minus1 << 1) | bit_minus2;
- } else {
- *speedo_lp |= 0x3;
- *speedo_g |= 0x3;
- }
-}
-
-static void rev_sku_to_speedo_ids(int rev, int sku)
-{
- switch (rev) {
- case TEGRA_REVISION_A01:
- tegra_cpu_speedo_id = 0;
- tegra_soc_speedo_id = 0;
- threshold_index = THRESHOLD_INDEX_0;
- break;
- case TEGRA_REVISION_A02:
- case TEGRA_REVISION_A03:
- switch (sku) {
- case 0x87:
- case 0x82:
- tegra_cpu_speedo_id = 1;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_1;
- break;
- case 0x81:
- switch (package_id) {
- case 1:
- tegra_cpu_speedo_id = 2;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_2;
- break;
- case 2:
- tegra_cpu_speedo_id = 4;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_7;
- break;
- default:
- pr_err("Tegra30: Unknown pkg %d\n", package_id);
- BUG();
- break;
- }
- break;
- case 0x80:
- switch (package_id) {
- case 1:
- tegra_cpu_speedo_id = 5;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_8;
- break;
- case 2:
- tegra_cpu_speedo_id = 6;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_9;
- break;
- default:
- pr_err("Tegra30: Unknown pkg %d\n", package_id);
- BUG();
- break;
- }
- break;
- case 0x83:
- switch (package_id) {
- case 1:
- tegra_cpu_speedo_id = 7;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_10;
- break;
- case 2:
- tegra_cpu_speedo_id = 3;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_3;
- break;
- default:
- pr_err("Tegra30: Unknown pkg %d\n", package_id);
- BUG();
- break;
- }
- break;
- case 0x8F:
- tegra_cpu_speedo_id = 8;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_11;
- break;
- case 0x08:
- tegra_cpu_speedo_id = 1;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_4;
- break;
- case 0x02:
- tegra_cpu_speedo_id = 2;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_5;
- break;
- case 0x04:
- tegra_cpu_speedo_id = 3;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_6;
- break;
- case 0:
- switch (package_id) {
- case 1:
- tegra_cpu_speedo_id = 2;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_2;
- break;
- case 2:
- tegra_cpu_speedo_id = 3;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_3;
- break;
- default:
- pr_err("Tegra30: Unknown pkg %d\n", package_id);
- BUG();
- break;
- }
- break;
- default:
- pr_warn("Tegra30: Unknown SKU %d\n", sku);
- tegra_cpu_speedo_id = 0;
- tegra_soc_speedo_id = 0;
- threshold_index = THRESHOLD_INDEX_0;
- break;
- }
- break;
- default:
- pr_warn("Tegra30: Unknown chip rev %d\n", rev);
- tegra_cpu_speedo_id = 0;
- tegra_soc_speedo_id = 0;
- threshold_index = THRESHOLD_INDEX_0;
- break;
- }
-}
-
-void tegra30_init_speedo_data(void)
-{
- u32 cpu_speedo_val;
- u32 core_speedo_val;
- int i;
-
- BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
- THRESHOLD_INDEX_COUNT);
- BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
- THRESHOLD_INDEX_COUNT);
-
- package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
-
- rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id);
- fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);
- pr_debug("%s CPU speedo value %u\n", __func__, cpu_speedo_val);
- pr_debug("%s Core speedo value %u\n", __func__, core_speedo_val);
-
- for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
- if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
- break;
- }
- tegra_cpu_process_id = i - 1;
-
- if (tegra_cpu_process_id == -1) {
- pr_warn("Tegra30: CPU speedo value %3d out of range",
- cpu_speedo_val);
- tegra_cpu_process_id = 0;
- tegra_cpu_speedo_id = 1;
- }
-
- for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) {
- if (core_speedo_val < core_process_speedos[threshold_index][i])
- break;
- }
- tegra_core_process_id = i - 1;
-
- if (tegra_core_process_id == -1) {
- pr_warn("Tegra30: CORE speedo value %3d out of range",
- core_speedo_val);
- tegra_core_process_id = 0;
- tegra_soc_speedo_id = 1;
- }
-
- pr_info("Tegra30: CPU Speedo ID %d, Soc Speedo ID %d",
- tegra_cpu_speedo_id, tegra_soc_speedo_id);
-}
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7eb4b69..ecb9349 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_SRAM) += sram.o
obj-y += mic/
obj-$(CONFIG_GENWQE) += genwqe/
obj-$(CONFIG_ECHO) += echo/
+obj-y += fuse/
diff --git a/drivers/misc/fuse/tegra/fuse-tegra.c b/drivers/misc/fuse/tegra/fuse-tegra.c
index 3fa6f74..934073e 100644
--- a/drivers/misc/fuse/tegra/fuse-tegra.c
+++ b/drivers/misc/fuse/tegra/fuse-tegra.c
@@ -98,6 +98,16 @@ static void tegra_enable_fuse_clk(void __iomem *base)
writel(reg, base + 0x14);
}
+int tegra_fuse_readl(u32 offset, u32 *val)
+{
+ if (!fuse_readl)
+ return -EPROBE_DEFER;
+
+ *val = fuse_readl(offset);
+
+ return 0;
+}
+
int tegra_fuse_create_sysfs(struct device *dev, int size,
u32 (*readl)(const unsigned int offset))
{
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index 5c33b16..1ca3756 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -54,9 +54,9 @@ struct tegra_sku_info {
u32 tegra_read_straps(void);
u32 tegra_read_chipid(void);
void tegra_init_fuse(void);
+int tegra_fuse_readl(u32 offset, u32 *val);
extern int tegra_chip_id;
-extern enum tegra_revision tegra_revision;
extern struct tegra_sku_info tegra_sku_info;
#if defined(CONFIG_TEGRA20_APB_DMA)
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 6/6] misc: fuse: move APB DMA into Tegra20 fuse driver
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
` (3 preceding siblings ...)
2014-06-12 15:36 ` [PATCH v8 5/6] ARM: tegra: build new fuse driver in drivers/misc Peter De Schrijver
@ 2014-06-12 15:36 ` Peter De Schrijver
2014-06-12 22:17 ` [PATCH v8 0/6] efuse driver for Tegra Stephen Warren
2014-06-16 18:42 ` Stephen Warren
6 siblings, 0 replies; 11+ messages in thread
From: Peter De Schrijver @ 2014-06-12 15:36 UTC (permalink / raw)
To: linux-arm-kernel
The Tegra20 fuse driver is the only user of tegra_apb_readl_using_dma().
Therefore we can simply the code by incorporating the APB DMA handling into
the driver directly. tegra_apb_writel_using_dma() is dropped because there
are no users.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/Makefile | 1 -
arch/arm/mach-tegra/apbio.c | 217 --------------------------------
arch/arm/mach-tegra/apbio.h | 22 ----
arch/arm/mach-tegra/tegra.c | 2 -
drivers/misc/fuse/tegra/fuse-tegra20.c | 79 +++++++++++-
include/linux/tegra-soc.h | 14 --
6 files changed, 76 insertions(+), 259 deletions(-)
delete mode 100644 arch/arm/mach-tegra/apbio.c
delete mode 100644 arch/arm/mach-tegra/apbio.h
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index e8601bb..c303b55 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -5,7 +5,6 @@ obj-y += irq.o
obj-y += pmc.o
obj-y += flowctrl.o
obj-y += powergate.o
-obj-y += apbio.o
obj-y += pm.o
obj-y += reset.o
obj-y += reset-handler.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
deleted file mode 100644
index e0bf49d..0000000
--- a/arch/arm/mach-tegra/apbio.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2010 NVIDIA Corporation.
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-
-#include "apbio.h"
-#include "iomap.h"
-
-#if defined(CONFIG_TEGRA20_APB_DMA)
-static DEFINE_MUTEX(tegra_apb_dma_lock);
-static u32 *tegra_apb_bb;
-static dma_addr_t tegra_apb_bb_phys;
-static DECLARE_COMPLETION(tegra_apb_wait);
-
-static int tegra_apb_readl_direct(unsigned long offset, u32 *value);
-static int tegra_apb_writel_direct(u32 value, unsigned long offset);
-
-static struct dma_chan *tegra_apb_dma_chan;
-static struct dma_slave_config dma_sconfig;
-
-static bool tegra_apb_dma_init(void)
-{
- dma_cap_mask_t mask;
-
- mutex_lock(&tegra_apb_dma_lock);
-
- /* Check to see if we raced to setup */
- if (tegra_apb_dma_chan)
- goto skip_init;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
- tegra_apb_dma_chan = dma_request_channel(mask, NULL, NULL);
- if (!tegra_apb_dma_chan) {
- /*
- * This is common until the device is probed, so don't
- * shout about it.
- */
- pr_debug("%s: can not allocate dma channel\n", __func__);
- goto err_dma_alloc;
- }
-
- tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),
- &tegra_apb_bb_phys, GFP_KERNEL);
- if (!tegra_apb_bb) {
- pr_err("%s: can not allocate bounce buffer\n", __func__);
- goto err_buff_alloc;
- }
-
- dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- dma_sconfig.src_maxburst = 1;
- dma_sconfig.dst_maxburst = 1;
-
-skip_init:
- mutex_unlock(&tegra_apb_dma_lock);
- return true;
-
-err_buff_alloc:
- dma_release_channel(tegra_apb_dma_chan);
- tegra_apb_dma_chan = NULL;
-
-err_dma_alloc:
- mutex_unlock(&tegra_apb_dma_lock);
- return false;
-}
-
-static void apb_dma_complete(void *args)
-{
- complete(&tegra_apb_wait);
-}
-
-static int do_dma_transfer(unsigned long apb_add,
- enum dma_transfer_direction dir)
-{
- struct dma_async_tx_descriptor *dma_desc;
- int ret;
-
- if (dir == DMA_DEV_TO_MEM)
- dma_sconfig.src_addr = apb_add;
- else
- dma_sconfig.dst_addr = apb_add;
-
- ret = dmaengine_slave_config(tegra_apb_dma_chan, &dma_sconfig);
- if (ret)
- return ret;
-
- dma_desc = dmaengine_prep_slave_single(tegra_apb_dma_chan,
- tegra_apb_bb_phys, sizeof(u32), dir,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!dma_desc)
- return -EINVAL;
-
- dma_desc->callback = apb_dma_complete;
- dma_desc->callback_param = NULL;
-
- reinit_completion(&tegra_apb_wait);
-
- dmaengine_submit(dma_desc);
- dma_async_issue_pending(tegra_apb_dma_chan);
- ret = wait_for_completion_timeout(&tegra_apb_wait,
- msecs_to_jiffies(50));
-
- if (WARN(ret == 0, "apb read dma timed out")) {
- dmaengine_terminate_all(tegra_apb_dma_chan);
- return -EFAULT;
- }
- return 0;
-}
-
-int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
-{
- int ret;
-
- if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
- return tegra_apb_readl_direct(offset, value);
-
- mutex_lock(&tegra_apb_dma_lock);
- ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);
- if (ret < 0)
- pr_err("error in reading offset 0x%08lx using dma\n", offset);
- else
- *value = *tegra_apb_bb;
-
- mutex_unlock(&tegra_apb_dma_lock);
-
- return ret;
-}
-
-int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
-{
- int ret;
-
- if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
- return tegra_apb_writel_direct(value, offset);
-
- mutex_lock(&tegra_apb_dma_lock);
- *((u32 *)tegra_apb_bb) = value;
- ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);
- mutex_unlock(&tegra_apb_dma_lock);
- if (ret < 0)
- pr_err("error in writing offset 0x%08lx using dma\n", offset);
-
- return ret;
-}
-#else
-#define tegra_apb_readl_using_dma tegra_apb_readl_direct
-#define tegra_apb_writel_using_dma tegra_apb_writel_direct
-#endif
-
-typedef int (*apbio_read_fptr)(unsigned long offset, u32 *value);
-typedef int (*apbio_write_fptr)(u32 value, unsigned long offset);
-
-static apbio_read_fptr apbio_read;
-static apbio_write_fptr apbio_write;
-
-static int tegra_apb_readl_direct(unsigned long offset, u32 *value)
-{
- *value = readl(IO_ADDRESS(offset));
-
- return 0;
-}
-
-static int tegra_apb_writel_direct(u32 value, unsigned long offset)
-{
- writel(value, IO_ADDRESS(offset));
-
- return 0;
-}
-
-void tegra_apb_io_init(void)
-{
- /* Need to use dma only when it is Tegra20 based platform */
- if (of_machine_is_compatible("nvidia,tegra20") ||
- !of_have_populated_dt()) {
- apbio_read = tegra_apb_readl_using_dma;
- apbio_write = tegra_apb_writel_using_dma;
- } else {
- apbio_read = tegra_apb_readl_direct;
- apbio_write = tegra_apb_writel_direct;
- }
-}
-
-u32 tegra_apb_readl(unsigned long offset)
-{
- u32 val;
-
- if (apbio_read(offset, &val) < 0)
- return 0;
- else
- return val;
-}
-
-void tegra_apb_writel(u32 value, unsigned long offset)
-{
- apbio_write(value, offset);
-}
diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h
deleted file mode 100644
index f05d71c..0000000
--- a/arch/arm/mach-tegra/apbio.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2010 NVIDIA Corporation.
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __MACH_TEGRA_APBIO_H
-#define __MACH_TEGRA_APBIO_H
-
-void tegra_apb_io_init(void);
-u32 tegra_apb_readl(unsigned long offset);
-void tegra_apb_writel(u32 value, unsigned long offset);
-#endif
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index 093d5f4..ee6fbc6 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -43,7 +43,6 @@
#include <asm/setup.h>
#include <asm/trusted_foundations.h>
-#include "apbio.h"
#include "board.h"
#include "common.h"
#include "cpuidle.h"
@@ -100,7 +99,6 @@ static void __init tegra_init_cache(void)
static void __init tegra_init_early(void)
{
of_register_trusted_foundations();
- tegra_apb_io_init();
tegra_init_fuse();
tegra_cpu_reset_handler_init();
tegra_init_cache();
diff --git a/drivers/misc/fuse/tegra/fuse-tegra20.c b/drivers/misc/fuse/tegra/fuse-tegra20.c
index 09f91bf..c3dcf11 100644
--- a/drivers/misc/fuse/tegra/fuse-tegra20.c
+++ b/drivers/misc/fuse/tegra/fuse-tegra20.c
@@ -18,6 +18,9 @@
#include <linux/device.h>
#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
@@ -38,18 +41,58 @@ static phys_addr_t fuse_phys;
static struct clk *fuse_clk;
static void __iomem __initdata *fuse_base;
+static DEFINE_MUTEX(apb_dma_lock);
+static DECLARE_COMPLETION(apb_dma_wait);
+static struct dma_chan *apb_dma_chan;
+static struct dma_slave_config dma_sconfig;
+static u32 *apb_buffer;
+static dma_addr_t apb_buffer_phys;
+
+static void apb_dma_complete(void *args)
+{
+ complete(&apb_dma_wait);
+}
+
static u32 tegra20_fuse_readl(const unsigned int offset)
{
int ret;
- u32 val;
+ u32 val = 0;
+ struct dma_async_tx_descriptor *dma_desc;
+
+ mutex_lock(&apb_dma_lock);
+
+ dma_sconfig.src_addr = fuse_phys + FUSE_BEGIN + offset;
+ ret = dmaengine_slave_config(apb_dma_chan, &dma_sconfig);
+ if (ret)
+ goto out;
+
+ dma_desc = dmaengine_prep_slave_single(apb_dma_chan, apb_buffer_phys,
+ sizeof(u32), DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!dma_desc)
+ goto out;
+
+ dma_desc->callback = apb_dma_complete;
+ dma_desc->callback_param = NULL;
+
+ reinit_completion(&apb_dma_wait);
clk_prepare_enable(fuse_clk);
- ret = tegra_apb_readl_using_dma(fuse_phys + FUSE_BEGIN + offset, &val);
+ dmaengine_submit(dma_desc);
+ dma_async_issue_pending(apb_dma_chan);
+ ret = wait_for_completion_timeout(&apb_dma_wait, msecs_to_jiffies(50));
+
+ if (WARN(ret == 0, "apb read dma timed out"))
+ dmaengine_terminate_all(apb_dma_chan);
+ else
+ val = *apb_buffer;
clk_disable_unprepare(fuse_clk);
+out:
+ mutex_unlock(&apb_dma_lock);
- return (ret < 0) ? 0 : val;
+ return val;
}
static const struct of_device_id tegra20_fuse_of_match[] = {
@@ -57,9 +100,35 @@ static const struct of_device_id tegra20_fuse_of_match[] = {
{},
};
+static int apb_dma_init(void)
+{
+ dma_cap_mask_t mask;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ apb_dma_chan = dma_request_channel(mask, NULL, NULL);
+ if (!apb_dma_chan)
+ return -EPROBE_DEFER;
+
+ apb_buffer = dma_alloc_coherent(NULL, sizeof(u32), &apb_buffer_phys,
+ GFP_KERNEL);
+ if (!apb_buffer) {
+ dma_release_channel(apb_dma_chan);
+ return -ENOMEM;
+ }
+
+ dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ dma_sconfig.src_maxburst = 1;
+ dma_sconfig.dst_maxburst = 1;
+
+ return 0;
+}
+
static int tegra20_fuse_probe(struct platform_device *pdev)
{
struct resource *res;
+ int err;
fuse_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(fuse_clk)) {
@@ -72,6 +141,10 @@ static int tegra20_fuse_probe(struct platform_device *pdev)
return -EINVAL;
fuse_phys = res->start;
+ err = apb_dma_init();
+ if (err)
+ return err;
+
if (tegra_fuse_create_sysfs(&pdev->dev, FUSE_SIZE, tegra20_fuse_readl))
return -ENODEV;
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index 1ca3756..fcf65ec 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -59,20 +59,6 @@ int tegra_fuse_readl(u32 offset, u32 *val);
extern int tegra_chip_id;
extern struct tegra_sku_info tegra_sku_info;
-#if defined(CONFIG_TEGRA20_APB_DMA)
-int tegra_apb_readl_using_dma(unsigned long offset, u32 *value);
-int tegra_apb_writel_using_dma(u32 value, unsigned long offset);
-#else
-static inline int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
-{
- return -EINVAL;
-}
-static inline int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
-{
- return -EINVAL;
-}
-#endif
-
#endif /* __ASSEMBLY__ */
#endif /* __LINUX_TEGRA_SOC_H_ */
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 0/6] efuse driver for Tegra
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
` (4 preceding siblings ...)
2014-06-12 15:36 ` [PATCH v8 6/6] misc: fuse: move APB DMA into Tegra20 fuse driver Peter De Schrijver
@ 2014-06-12 22:17 ` Stephen Warren
2014-06-13 7:23 ` Peter De Schrijver
2014-06-16 18:42 ` Stephen Warren
6 siblings, 1 reply; 11+ messages in thread
From: Stephen Warren @ 2014-06-12 22:17 UTC (permalink / raw)
To: linux-arm-kernel
On 06/12/2014 09:36 AM, Peter De Schrijver wrote:
> This driver allows userspace to read the raw efuse data. Its userspace
> interface is modelled after the sunxi_sid driver which provides similar
> functionality for some Allwinner SoCs. It has been tested on
> Tegra20 (ventana), Tegra30 (beaverboard), Tegra114 (dalmore) and
> Tegra124 (jetson TK1).
I think this series looks OK now. However, I noticed one change in
behaviour that I don't think is expected:
The current code/DTB print:
Tegra Revision: A01 SKU: 0 CPU Process: 0 Core Process: 0
However, applying these patches and booting yields:
Tegra Revision: A01 SKU: 0 CPU Process: 1 Core Process: 1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v8 0/6] efuse driver for Tegra
2014-06-12 22:17 ` [PATCH v8 0/6] efuse driver for Tegra Stephen Warren
@ 2014-06-13 7:23 ` Peter De Schrijver
2014-06-13 8:00 ` Peter De Schrijver
0 siblings, 1 reply; 11+ messages in thread
From: Peter De Schrijver @ 2014-06-13 7:23 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jun 13, 2014 at 12:17:02AM +0200, Stephen Warren wrote:
> On 06/12/2014 09:36 AM, Peter De Schrijver wrote:
> > This driver allows userspace to read the raw efuse data. Its userspace
> > interface is modelled after the sunxi_sid driver which provides similar
> > functionality for some Allwinner SoCs. It has been tested on
> > Tegra20 (ventana), Tegra30 (beaverboard), Tegra114 (dalmore) and
> > Tegra124 (jetson TK1).
>
> I think this series looks OK now. However, I noticed one change in
> behaviour that I don't think is expected:
>
> The current code/DTB print:
> Tegra Revision: A01 SKU: 0 CPU Process: 0 Core Process: 0
>
> However, applying these patches and booting yields:
> Tegra Revision: A01 SKU: 0 CPU Process: 1 Core Process: 1
>
On which board/SoC?
Cheers,
Peter.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v8 0/6] efuse driver for Tegra
2014-06-13 7:23 ` Peter De Schrijver
@ 2014-06-13 8:00 ` Peter De Schrijver
2014-06-13 16:38 ` Stephen Warren
0 siblings, 1 reply; 11+ messages in thread
From: Peter De Schrijver @ 2014-06-13 8:00 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jun 13, 2014 at 09:23:28AM +0200, Peter De Schrijver wrote:
> On Fri, Jun 13, 2014 at 12:17:02AM +0200, Stephen Warren wrote:
> > On 06/12/2014 09:36 AM, Peter De Schrijver wrote:
> > > This driver allows userspace to read the raw efuse data. Its userspace
> > > interface is modelled after the sunxi_sid driver which provides similar
> > > functionality for some Allwinner SoCs. It has been tested on
> > > Tegra20 (ventana), Tegra30 (beaverboard), Tegra114 (dalmore) and
> > > Tegra124 (jetson TK1).
> >
> > I think this series looks OK now. However, I noticed one change in
> > behaviour that I don't think is expected:
> >
> > The current code/DTB print:
> > Tegra Revision: A01 SKU: 0 CPU Process: 0 Core Process: 0
> >
> > However, applying these patches and booting yields:
> > Tegra Revision: A01 SKU: 0 CPU Process: 1 Core Process: 1
> >
>
> On which board/SoC?
>
I'm guessing you're running on Tegra124 because the silicon revision reported
is A01. If this is correct then, the current output is bogus. The current fuse
code does not have any Tegra124 support and will fall back to reading the same
fuse bits as on Tegra20 to determine the process IDs. You should get a warning
message though: 'Tegra: unknown chip id'
Cheers,
Peter.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v8 0/6] efuse driver for Tegra
2014-06-13 8:00 ` Peter De Schrijver
@ 2014-06-13 16:38 ` Stephen Warren
0 siblings, 0 replies; 11+ messages in thread
From: Stephen Warren @ 2014-06-13 16:38 UTC (permalink / raw)
To: linux-arm-kernel
On 06/13/2014 02:00 AM, Peter De Schrijver wrote:
> On Fri, Jun 13, 2014 at 09:23:28AM +0200, Peter De Schrijver wrote:
>> On Fri, Jun 13, 2014 at 12:17:02AM +0200, Stephen Warren wrote:
>>> On 06/12/2014 09:36 AM, Peter De Schrijver wrote:
>>>> This driver allows userspace to read the raw efuse data. Its userspace
>>>> interface is modelled after the sunxi_sid driver which provides similar
>>>> functionality for some Allwinner SoCs. It has been tested on
>>>> Tegra20 (ventana), Tegra30 (beaverboard), Tegra114 (dalmore) and
>>>> Tegra124 (jetson TK1).
>>>
>>> I think this series looks OK now. However, I noticed one change in
>>> behaviour that I don't think is expected:
>>>
>>> The current code/DTB print:
>>> Tegra Revision: A01 SKU: 0 CPU Process: 0 Core Process: 0
>>>
>>> However, applying these patches and booting yields:
>>> Tegra Revision: A01 SKU: 0 CPU Process: 1 Core Process: 1
>>
>> On which board/SoC?
Oops. Venice2/Tegra124.
> I'm guessing you're running on Tegra124 because the silicon revision reported
> is A01. If this is correct then, the current output is bogus. The current fuse
> code does not have any Tegra124 support and will fall back to reading the same
> fuse bits as on Tegra20 to determine the process IDs. You should get a warning
> message though: 'Tegra: unknown chip id'
Ah yes:
Tegra: unknown chip id 64
OK, so there's nothing wrong with this change in behaviour:-)
If that error message still exists, it might be nice if that value was
printed in hex since that's what the data sheets and code usually
represents it as. That can certainly be a followon patch though; no need
for a respin.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v8 0/6] efuse driver for Tegra
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
` (5 preceding siblings ...)
2014-06-12 22:17 ` [PATCH v8 0/6] efuse driver for Tegra Stephen Warren
@ 2014-06-16 18:42 ` Stephen Warren
6 siblings, 0 replies; 11+ messages in thread
From: Stephen Warren @ 2014-06-16 18:42 UTC (permalink / raw)
To: linux-arm-kernel
On 06/12/2014 09:36 AM, Peter De Schrijver wrote:
> This driver allows userspace to read the raw efuse data. Its userspace
> interface is modelled after the sunxi_sid driver which provides similar
> functionality for some Allwinner SoCs. It has been tested on
> Tegra20 (ventana), Tegra30 (beaverboard), Tegra114 (dalmore) and
> Tegra124 (jetson TK1).
I've applied this series to Tegra's for-3.17/fuse-move branch.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2014-06-16 18:42 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 2/6] ARM: tegra: move fuse exports to tegra-soc.h Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 4/6] ARM: tegra: Add efuse and apbmisc bindings Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 5/6] ARM: tegra: build new fuse driver in drivers/misc Peter De Schrijver
2014-06-12 15:36 ` [PATCH v8 6/6] misc: fuse: move APB DMA into Tegra20 fuse driver Peter De Schrijver
2014-06-12 22:17 ` [PATCH v8 0/6] efuse driver for Tegra Stephen Warren
2014-06-13 7:23 ` Peter De Schrijver
2014-06-13 8:00 ` Peter De Schrijver
2014-06-13 16:38 ` Stephen Warren
2014-06-16 18:42 ` Stephen Warren
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).