aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2014-07-19 15:29:11 -0400
committerOlof Johansson <olof@lixom.net>2014-07-19 15:29:11 -0400
commit23e892929e7ccee8b5977a673a147dec96ac1351 (patch)
treee73f436972663a14e0d5da51d01205b0e40eb13e
parent4cfab57e47079482dd0350a1912b0c38823f76aa (diff)
parent2fa937a767bd0933dfe6017cabd038ce52594171 (diff)
Merge tag 'tegra-for-3.17-fuse-move' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/cleanup
Merge "ARM: tegra: move fuse code out of arch/arm" from Thierry Reding: This branch moves code related to the Tegra fuses out of arch/arm and into a centralized location which could be shared with ARM64. It also adds support for reading the fuse data through sysfs. Included is also some preparatory work that moves Tegra-related header files from include/linux to include/soc/tegra as suggested by Arnd. Furthermore the Tegra chip ID is now retrieved using a function rather than a variable so that sanity checks can be done. This is convenient in subsequent patches that will move some of the code that's currently called from Tegra machine setup into regular initcalls so that it can be reused on 64-bit ARM. The sanity checks help with verifying that no code tries to obtain the Tegra chip ID before the underlying driver is properly initialized. * tag 'tegra-for-3.17-fuse-move' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: soc/tegra: fuse: fix dummy functions soc/tegra: fuse: move APB DMA into Tegra20 fuse driver soc/tegra: Add efuse and apbmisc bindings soc/tegra: Add efuse driver for Tegra ARM: tegra: move fuse exports to soc/tegra/fuse.h ARM: tegra: export apb dma readl/writel ARM: tegra: Use a function to get the chip ID ARM: tegra: Sort includes alphabetically ARM: tegra: Move includes to include/soc/tegra Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--Documentation/ABI/testing/sysfs-driver-tegra-fuse11
-rw-r--r--Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt40
-rw-r--r--Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt13
-rw-r--r--arch/arm/boot/dts/tegra114.dtsi15
-rw-r--r--arch/arm/boot/dts/tegra124.dtsi15
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi15
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi15
-rw-r--r--arch/arm/mach-tegra/Makefile5
-rw-r--r--arch/arm/mach-tegra/apbio.c206
-rw-r--r--arch/arm/mach-tegra/apbio.h22
-rw-r--r--arch/arm/mach-tegra/board-paz00.c3
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra114.c10
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra20.c16
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra30.c10
-rw-r--r--arch/arm/mach-tegra/cpuidle.c7
-rw-r--r--arch/arm/mach-tegra/flowctrl.c11
-rw-r--r--arch/arm/mach-tegra/fuse.c252
-rw-r--r--arch/arm/mach-tegra/fuse.h79
-rw-r--r--arch/arm/mach-tegra/hotplug.c14
-rw-r--r--arch/arm/mach-tegra/io.c8
-rw-r--r--arch/arm/mach-tegra/irq.c8
-rw-r--r--arch/arm/mach-tegra/platsmp.c29
-rw-r--r--arch/arm/mach-tegra/pm-tegra20.c1
-rw-r--r--arch/arm/mach-tegra/pm-tegra30.c1
-rw-r--r--arch/arm/mach-tegra/pm.c33
-rw-r--r--arch/arm/mach-tegra/pmc.c9
-rw-r--r--arch/arm/mach-tegra/powergate.c15
-rw-r--r--arch/arm/mach-tegra/reset-handler.S7
-rw-r--r--arch/arm/mach-tegra/reset.c11
-rw-r--r--arch/arm/mach-tegra/sleep-tegra30.S7
-rw-r--r--arch/arm/mach-tegra/tegra.c28
-rw-r--r--drivers/amba/tegra-ahb.c3
-rw-r--r--drivers/clk/tegra/clk-periph-gate.c3
-rw-r--r--drivers/clk/tegra/clk-tegra30.c5
-rw-r--r--drivers/clk/tegra/clk.c3
-rw-r--r--drivers/gpu/drm/tegra/gr3d.c3
-rw-r--r--drivers/gpu/drm/tegra/sor.c3
-rw-r--r--drivers/iommu/tegra-smmu.c3
-rw-r--r--drivers/misc/fuse/Makefile1
-rw-r--r--drivers/pci/host/pci-tegra.c5
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/tegra/Makefile1
-rw-r--r--drivers/soc/tegra/fuse/Makefile8
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra.c156
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra20.c215
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra30.c224
-rw-r--r--drivers/soc/tegra/fuse/fuse.h71
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra114.c (renamed from arch/arm/mach-tegra/tegra114_speedo.c)56
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra124.c168
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra20.c (renamed from arch/arm/mach-tegra/tegra20_speedo.c)45
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra30.c (renamed from arch/arm/mach-tegra/tegra30_speedo.c)176
-rw-r--r--drivers/soc/tegra/fuse/tegra-apbmisc.c112
-rw-r--r--include/linux/tegra-soc.h22
-rw-r--r--include/soc/tegra/ahb.h (renamed from include/linux/tegra-ahb.h)6
-rw-r--r--include/soc/tegra/cpuidle.h (renamed from include/linux/tegra-cpuidle.h)6
-rw-r--r--include/soc/tegra/fuse.h66
-rw-r--r--include/soc/tegra/powergate.h (renamed from include/linux/tegra-powergate.h)6
57 files changed, 1436 insertions, 848 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-tegra-fuse b/Documentation/ABI/testing/sysfs-driver-tegra-fuse
new file mode 100644
index 000000000000..69f5af632657
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-tegra-fuse
@@ -0,0 +1,11 @@
1What: /sys/devices/*/<our-device>/fuse
2Date: February 2014
3Contact: Peter De Schrijver <pdeschrijver@nvidia.com>
4Description: read-only access to the efuses on Tegra20, Tegra30, Tegra114
5 and Tegra124 SoC's from NVIDIA. The efuses contain write once
6 data programmed at the factory. The data is layed out in 32bit
7 words in LSB first format. Each bit represents a single value
8 as decoded from the fuse registers. Bits order/assignment
9 exactly matches the HW registers, including any unused bits.
10Users: any user space application which wants to read the efuses on
11 Tegra SoC's
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 000000000000..d8c98c7614d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt
@@ -0,0 +1,40 @@
1NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse block.
2
3Required properties:
4- compatible : should be:
5 "nvidia,tegra20-efuse"
6 "nvidia,tegra30-efuse"
7 "nvidia,tegra114-efuse"
8 "nvidia,tegra124-efuse"
9 Details:
10 nvidia,tegra20-efuse: Tegra20 requires using APB DMA to read the fuse data
11 due to a hardware bug. Tegra20 also lacks certain information which is
12 available in later generations such as fab code, lot code, wafer id,..
13 nvidia,tegra30-efuse, nvidia,tegra114-efuse and nvidia,tegra124-efuse:
14 The differences between these SoCs are the size of the efuse array,
15 the location of the spare (OEM programmable) bits and the location of
16 the speedo data.
17- reg: Should contain 1 entry: the entry gives the physical address and length
18 of the fuse registers.
19- clocks: Must contain an entry for each entry in clock-names.
20 See ../clocks/clock-bindings.txt for details.
21- clock-names: Must include the following entries:
22 - fuse
23- resets: Must contain an entry for each entry in reset-names.
24 See ../reset/reset.txt for details.
25- reset-names: Must include the following entries:
26 - fuse
27
28Example:
29
30 fuse@7000f800 {
31 compatible = "nvidia,tegra20-efuse";
32 reg = <0x7000F800 0x400>,
33 <0x70000000 0x400>;
34 clocks = <&tegra_car TEGRA20_CLK_FUSE>;
35 clock-names = "fuse";
36 resets = <&tegra_car 39>;
37 reset-names = "fuse";
38 };
39
40
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 000000000000..b97b8bef1fe5
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt
@@ -0,0 +1,13 @@
1NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block
2
3Required properties:
4- compatible : should be:
5 "nvidia,tegra20-apbmisc"
6 "nvidia,tegra30-apbmisc"
7 "nvidia,tegra114-apbmisc"
8 "nvidia,tegra124-apbmisc"
9- reg: Should contain 2 entries: the first entry gives the physical address
10 and length of the registers which contain revision and debug features.
11 The second entry gives the physical address and length of the
12 registers indicating the strapping options.
13
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
index fdc559ab2db3..335a1d8047f2 100644
--- a/arch/arm/boot/dts/tegra114.dtsi
+++ b/arch/arm/boot/dts/tegra114.dtsi
@@ -220,6 +220,12 @@
220 interrupt-controller; 220 interrupt-controller;
221 }; 221 };
222 222
223 apbmisc@70000800 {
224 compatible = "nvidia,tegra114-apbmisc", "nvidia,tegra20-apbmisc";
225 reg = <0x70000800 0x64 /* Chip revision */
226 0x70000008 0x04>; /* Strapping options */
227 };
228
223 pinmux: pinmux@70000868 { 229 pinmux: pinmux@70000868 {
224 compatible = "nvidia,tegra114-pinmux"; 230 compatible = "nvidia,tegra114-pinmux";
225 reg = <0x70000868 0x148 /* Pad control registers */ 231 reg = <0x70000868 0x148 /* Pad control registers */
@@ -485,6 +491,15 @@
485 clock-names = "pclk", "clk32k_in"; 491 clock-names = "pclk", "clk32k_in";
486 }; 492 };
487 493
494 fuse@7000f800 {
495 compatible = "nvidia,tegra114-efuse";
496 reg = <0x7000f800 0x400>;
497 clocks = <&tegra_car TEGRA114_CLK_FUSE>;
498 clock-names = "fuse";
499 resets = <&tegra_car 39>;
500 reset-names = "fuse";
501 };
502
488 iommu@70019010 { 503 iommu@70019010 {
489 compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu"; 504 compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu";
490 reg = <0x70019010 0x02c 505 reg = <0x70019010 0x02c
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 6e6bc4e8185c..226941c07d15 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -179,6 +179,12 @@
179 #dma-cells = <1>; 179 #dma-cells = <1>;
180 }; 180 };
181 181
182 apbmisc@0,70000800 {
183 compatible = "nvidia,tegra124-apbmisc", "nvidia,tegra20-apbmisc";
184 reg = <0x0 0x70000800 0x0 0x64>, /* Chip revision */
185 <0x0 0x7000E864 0x0 0x04>; /* Strapping options */
186 };
187
182 pinmux: pinmux@0,70000868 { 188 pinmux: pinmux@0,70000868 {
183 compatible = "nvidia,tegra124-pinmux"; 189 compatible = "nvidia,tegra124-pinmux";
184 reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */ 190 reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */
@@ -449,6 +455,15 @@
449 clock-names = "pclk", "clk32k_in"; 455 clock-names = "pclk", "clk32k_in";
450 }; 456 };
451 457
458 fuse@0,7000f800 {
459 compatible = "nvidia,tegra124-efuse";
460 reg = <0x0 0x7000f800 0x0 0x400>;
461 clocks = <&tegra_car TEGRA124_CLK_FUSE>;
462 clock-names = "fuse";
463 resets = <&tegra_car 39>;
464 reset-names = "fuse";
465 };
466
452 sdhci@0,700b0000 { 467 sdhci@0,700b0000 {
453 compatible = "nvidia,tegra124-sdhci"; 468 compatible = "nvidia,tegra124-sdhci";
454 reg = <0x0 0x700b0000 0x0 0x200>; 469 reg = <0x0 0x700b0000 0x0 0x200>;
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index a7ddf70df50b..243d84cdbae8 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -236,6 +236,12 @@
236 interrupt-controller; 236 interrupt-controller;
237 }; 237 };
238 238
239 apbmisc@70000800 {
240 compatible = "nvidia,tegra20-apbmisc";
241 reg = <0x70000800 0x64 /* Chip revision */
242 0x70000008 0x04>; /* Strapping options */
243 };
244
239 pinmux: pinmux@70000014 { 245 pinmux: pinmux@70000014 {
240 compatible = "nvidia,tegra20-pinmux"; 246 compatible = "nvidia,tegra20-pinmux";
241 reg = <0x70000014 0x10 /* Tri-state registers */ 247 reg = <0x70000014 0x10 /* Tri-state registers */
@@ -545,6 +551,15 @@
545 #size-cells = <0>; 551 #size-cells = <0>;
546 }; 552 };
547 553
554 fuse@7000f800 {
555 compatible = "nvidia,tegra20-efuse";
556 reg = <0x7000F800 0x400>;
557 clocks = <&tegra_car TEGRA20_CLK_FUSE>;
558 clock-names = "fuse";
559 resets = <&tegra_car 39>;
560 reset-names = "fuse";
561 };
562
548 pcie-controller@80003000 { 563 pcie-controller@80003000 {
549 compatible = "nvidia,tegra20-pcie"; 564 compatible = "nvidia,tegra20-pcie";
550 device_type = "pci"; 565 device_type = "pci";
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index dec4fc823901..0b1ede940d1f 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -335,6 +335,12 @@
335 interrupt-controller; 335 interrupt-controller;
336 }; 336 };
337 337
338 apbmisc@70000800 {
339 compatible = "nvidia,tegra30-apbmisc", "nvidia,tegra20-apbmisc";
340 reg = <0x70000800 0x64 /* Chip revision */
341 0x70000008 0x04>; /* Strapping options */
342 };
343
338 pinmux: pinmux@70000868 { 344 pinmux: pinmux@70000868 {
339 compatible = "nvidia,tegra30-pinmux"; 345 compatible = "nvidia,tegra30-pinmux";
340 reg = <0x70000868 0xd4 /* Pad control registers */ 346 reg = <0x70000868 0xd4 /* Pad control registers */
@@ -631,6 +637,15 @@
631 nvidia,ahb = <&ahb>; 637 nvidia,ahb = <&ahb>;
632 }; 638 };
633 639
640 fuse@7000f800 {
641 compatible = "nvidia,tegra30-efuse";
642 reg = <0x7000f800 0x400>;
643 clocks = <&tegra_car TEGRA30_CLK_FUSE>;
644 clock-names = "fuse";
645 resets = <&tegra_car 39>;
646 reset-names = "fuse";
647 };
648
634 ahub@70080000 { 649 ahub@70080000 {
635 compatible = "nvidia,tegra30-ahub"; 650 compatible = "nvidia,tegra30-ahub";
636 reg = <0x70080000 0x200 651 reg = <0x70080000 0x200
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 6fbfbb77dcd9..c303b55de22e 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -2,24 +2,20 @@ asflags-y += -march=armv7-a
2 2
3obj-y += io.o 3obj-y += io.o
4obj-y += irq.o 4obj-y += irq.o
5obj-y += fuse.o
6obj-y += pmc.o 5obj-y += pmc.o
7obj-y += flowctrl.o 6obj-y += flowctrl.o
8obj-y += powergate.o 7obj-y += powergate.o
9obj-y += apbio.o
10obj-y += pm.o 8obj-y += pm.o
11obj-y += reset.o 9obj-y += reset.o
12obj-y += reset-handler.o 10obj-y += reset-handler.o
13obj-y += sleep.o 11obj-y += sleep.o
14obj-y += tegra.o 12obj-y += tegra.o
15obj-$(CONFIG_CPU_IDLE) += cpuidle.o 13obj-$(CONFIG_CPU_IDLE) += cpuidle.o
16obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
17obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o 14obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
18obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o 15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
19ifeq ($(CONFIG_CPU_IDLE),y) 16ifeq ($(CONFIG_CPU_IDLE),y)
20obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o 17obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
21endif 18endif
22obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o
23obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o 19obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
24obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o 20obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
25ifeq ($(CONFIG_CPU_IDLE),y) 21ifeq ($(CONFIG_CPU_IDLE),y)
@@ -28,7 +24,6 @@ endif
28obj-$(CONFIG_SMP) += platsmp.o headsmp.o 24obj-$(CONFIG_SMP) += platsmp.o headsmp.o
29obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 25obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
30 26
31obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o
32obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o 27obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
33obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o 28obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
34ifeq ($(CONFIG_CPU_IDLE),y) 29ifeq ($(CONFIG_CPU_IDLE),y)
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
deleted file mode 100644
index bc471973cf04..000000000000
--- a/arch/arm/mach-tegra/apbio.c
+++ /dev/null
@@ -1,206 +0,0 @@
1/*
2 * Copyright (C) 2010 NVIDIA Corporation.
3 * Copyright (C) 2010 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/dmaengine.h>
20#include <linux/dma-mapping.h>
21#include <linux/spinlock.h>
22#include <linux/completion.h>
23#include <linux/sched.h>
24#include <linux/mutex.h>
25
26#include "apbio.h"
27#include "iomap.h"
28
29#if defined(CONFIG_TEGRA20_APB_DMA)
30static DEFINE_MUTEX(tegra_apb_dma_lock);
31static u32 *tegra_apb_bb;
32static dma_addr_t tegra_apb_bb_phys;
33static DECLARE_COMPLETION(tegra_apb_wait);
34
35static u32 tegra_apb_readl_direct(unsigned long offset);
36static void tegra_apb_writel_direct(u32 value, unsigned long offset);
37
38static struct dma_chan *tegra_apb_dma_chan;
39static struct dma_slave_config dma_sconfig;
40
41static bool tegra_apb_dma_init(void)
42{
43 dma_cap_mask_t mask;
44
45 mutex_lock(&tegra_apb_dma_lock);
46
47 /* Check to see if we raced to setup */
48 if (tegra_apb_dma_chan)
49 goto skip_init;
50
51 dma_cap_zero(mask);
52 dma_cap_set(DMA_SLAVE, mask);
53 tegra_apb_dma_chan = dma_request_channel(mask, NULL, NULL);
54 if (!tegra_apb_dma_chan) {
55 /*
56 * This is common until the device is probed, so don't
57 * shout about it.
58 */
59 pr_debug("%s: can not allocate dma channel\n", __func__);
60 goto err_dma_alloc;
61 }
62
63 tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),
64 &tegra_apb_bb_phys, GFP_KERNEL);
65 if (!tegra_apb_bb) {
66 pr_err("%s: can not allocate bounce buffer\n", __func__);
67 goto err_buff_alloc;
68 }
69
70 dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
71 dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
72 dma_sconfig.src_maxburst = 1;
73 dma_sconfig.dst_maxburst = 1;
74
75skip_init:
76 mutex_unlock(&tegra_apb_dma_lock);
77 return true;
78
79err_buff_alloc:
80 dma_release_channel(tegra_apb_dma_chan);
81 tegra_apb_dma_chan = NULL;
82
83err_dma_alloc:
84 mutex_unlock(&tegra_apb_dma_lock);
85 return false;
86}
87
88static void apb_dma_complete(void *args)
89{
90 complete(&tegra_apb_wait);
91}
92
93static int do_dma_transfer(unsigned long apb_add,
94 enum dma_transfer_direction dir)
95{
96 struct dma_async_tx_descriptor *dma_desc;
97 int ret;
98
99 if (dir == DMA_DEV_TO_MEM)
100 dma_sconfig.src_addr = apb_add;
101 else
102 dma_sconfig.dst_addr = apb_add;
103
104 ret = dmaengine_slave_config(tegra_apb_dma_chan, &dma_sconfig);
105 if (ret)
106 return ret;
107
108 dma_desc = dmaengine_prep_slave_single(tegra_apb_dma_chan,
109 tegra_apb_bb_phys, sizeof(u32), dir,
110 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
111 if (!dma_desc)
112 return -EINVAL;
113
114 dma_desc->callback = apb_dma_complete;
115 dma_desc->callback_param = NULL;
116
117 reinit_completion(&tegra_apb_wait);
118
119 dmaengine_submit(dma_desc);
120 dma_async_issue_pending(tegra_apb_dma_chan);
121 ret = wait_for_completion_timeout(&tegra_apb_wait,
122 msecs_to_jiffies(50));
123
124 if (WARN(ret == 0, "apb read dma timed out")) {
125 dmaengine_terminate_all(tegra_apb_dma_chan);
126 return -EFAULT;
127 }
128 return 0;
129}
130
131static u32 tegra_apb_readl_using_dma(unsigned long offset)
132{
133 int ret;
134
135 if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
136 return tegra_apb_readl_direct(offset);
137
138 mutex_lock(&tegra_apb_dma_lock);
139 ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);
140 if (ret < 0) {
141 pr_err("error in reading offset 0x%08lx using dma\n", offset);
142 *(u32 *)tegra_apb_bb = 0;
143 }
144 mutex_unlock(&tegra_apb_dma_lock);
145 return *((u32 *)tegra_apb_bb);
146}
147
148static void tegra_apb_writel_using_dma(u32 value, unsigned long offset)
149{
150 int ret;
151
152 if (!tegra_apb_dma_chan && !tegra_apb_dma_init()) {
153 tegra_apb_writel_direct(value, offset);
154 return;
155 }
156
157 mutex_lock(&tegra_apb_dma_lock);
158 *((u32 *)tegra_apb_bb) = value;
159 ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);
160 if (ret < 0)
161 pr_err("error in writing offset 0x%08lx using dma\n", offset);
162 mutex_unlock(&tegra_apb_dma_lock);
163}
164#else
165#define tegra_apb_readl_using_dma tegra_apb_readl_direct
166#define tegra_apb_writel_using_dma tegra_apb_writel_direct
167#endif
168
169typedef u32 (*apbio_read_fptr)(unsigned long offset);
170typedef void (*apbio_write_fptr)(u32 value, unsigned long offset);
171
172static apbio_read_fptr apbio_read;
173static apbio_write_fptr apbio_write;
174
175static u32 tegra_apb_readl_direct(unsigned long offset)
176{
177 return readl(IO_ADDRESS(offset));
178}
179
180static void tegra_apb_writel_direct(u32 value, unsigned long offset)
181{
182 writel(value, IO_ADDRESS(offset));
183}
184
185void tegra_apb_io_init(void)
186{
187 /* Need to use dma only when it is Tegra20 based platform */
188 if (of_machine_is_compatible("nvidia,tegra20") ||
189 !of_have_populated_dt()) {
190 apbio_read = tegra_apb_readl_using_dma;
191 apbio_write = tegra_apb_writel_using_dma;
192 } else {
193 apbio_read = tegra_apb_readl_direct;
194 apbio_write = tegra_apb_writel_direct;
195 }
196}
197
198u32 tegra_apb_readl(unsigned long offset)
199{
200 return apbio_read(offset);
201}
202
203void tegra_apb_writel(u32 value, unsigned long offset)
204{
205 apbio_write(value, offset);
206}
diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h
deleted file mode 100644
index f05d71c303c7..000000000000
--- a/arch/arm/mach-tegra/apbio.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) 2010 NVIDIA Corporation.
3 * Copyright (C) 2010 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef __MACH_TEGRA_APBIO_H
17#define __MACH_TEGRA_APBIO_H
18
19void tegra_apb_io_init(void);
20u32 tegra_apb_readl(unsigned long offset);
21void tegra_apb_writel(u32 value, unsigned long offset);
22#endif
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index 9c6029ba526f..bb4782a32713 100644
--- a/arch/arm/mach-tegra/board-paz00.c
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -17,9 +17,10 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/platform_device.h>
21#include <linux/gpio/driver.h> 20#include <linux/gpio/driver.h>
21#include <linux/platform_device.h>
22#include <linux/rfkill-gpio.h> 22#include <linux/rfkill-gpio.h>
23
23#include "board.h" 24#include "board.h"
24 25
25static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = { 26static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = {
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
index b5fb7c110c64..e3ebdce3e71f 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -14,16 +14,16 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/kernel.h> 17#include <asm/firmware.h>
18#include <linux/module.h> 18#include <linux/clockchips.h>
19#include <linux/cpuidle.h> 19#include <linux/cpuidle.h>
20#include <linux/cpu_pm.h> 20#include <linux/cpu_pm.h>
21#include <linux/clockchips.h> 21#include <linux/kernel.h>
22#include <asm/firmware.h> 22#include <linux/module.h>
23 23
24#include <asm/cpuidle.h> 24#include <asm/cpuidle.h>
25#include <asm/suspend.h>
26#include <asm/smp_plat.h> 25#include <asm/smp_plat.h>
26#include <asm/suspend.h>
27 27
28#include "pm.h" 28#include "pm.h"
29#include "sleep.h" 29#include "sleep.h"
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index b82dcaee2ef4..b30bf5cba65b 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -19,23 +19,23 @@
19 * more details. 19 * more details.
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/clk/tegra.h>
23#include <linux/module.h> 23#include <linux/clockchips.h>
24#include <linux/cpuidle.h> 24#include <linux/cpuidle.h>
25#include <linux/cpu_pm.h> 25#include <linux/cpu_pm.h>
26#include <linux/clockchips.h> 26#include <linux/kernel.h>
27#include <linux/clk/tegra.h> 27#include <linux/module.h>
28 28
29#include <asm/cpuidle.h> 29#include <asm/cpuidle.h>
30#include <asm/proc-fns.h> 30#include <asm/proc-fns.h>
31#include <asm/suspend.h>
32#include <asm/smp_plat.h> 31#include <asm/smp_plat.h>
32#include <asm/suspend.h>
33 33
34#include "pm.h" 34#include "flowctrl.h"
35#include "sleep.h"
36#include "iomap.h" 35#include "iomap.h"
37#include "irq.h" 36#include "irq.h"
38#include "flowctrl.h" 37#include "pm.h"
38#include "sleep.h"
39 39
40#ifdef CONFIG_PM_SLEEP 40#ifdef CONFIG_PM_SLEEP
41static bool abort_flag; 41static bool abort_flag;
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
index ed2a2a7bae4d..35561274f6cf 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -19,17 +19,17 @@
19 * more details. 19 * more details.
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/clk/tegra.h>
23#include <linux/module.h> 23#include <linux/clockchips.h>
24#include <linux/cpuidle.h> 24#include <linux/cpuidle.h>
25#include <linux/cpu_pm.h> 25#include <linux/cpu_pm.h>
26#include <linux/clockchips.h> 26#include <linux/kernel.h>
27#include <linux/clk/tegra.h> 27#include <linux/module.h>
28 28
29#include <asm/cpuidle.h> 29#include <asm/cpuidle.h>
30#include <asm/proc-fns.h> 30#include <asm/proc-fns.h>
31#include <asm/suspend.h>
32#include <asm/smp_plat.h> 31#include <asm/smp_plat.h>
32#include <asm/suspend.h>
33 33
34#include "pm.h" 34#include "pm.h"
35#include "sleep.h" 35#include "sleep.h"
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index 7bc5d8d667fe..316563141add 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -24,12 +24,13 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/module.h> 25#include <linux/module.h>
26 26
27#include "fuse.h" 27#include <soc/tegra/fuse.h>
28
28#include "cpuidle.h" 29#include "cpuidle.h"
29 30
30void __init tegra_cpuidle_init(void) 31void __init tegra_cpuidle_init(void)
31{ 32{
32 switch (tegra_chip_id) { 33 switch (tegra_get_chip_id()) {
33 case TEGRA20: 34 case TEGRA20:
34 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 35 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
35 tegra20_cpuidle_init(); 36 tegra20_cpuidle_init();
@@ -49,7 +50,7 @@ void __init tegra_cpuidle_init(void)
49 50
50void tegra_cpuidle_pcie_irqs_in_use(void) 51void tegra_cpuidle_pcie_irqs_in_use(void)
51{ 52{
52 switch (tegra_chip_id) { 53 switch (tegra_get_chip_id()) {
53 case TEGRA20: 54 case TEGRA20:
54 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 55 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
55 tegra20_cpuidle_pcie_irqs_in_use(); 56 tegra20_cpuidle_pcie_irqs_in_use();
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index ce8ab8abf061..ec55d1de1b55 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -18,14 +18,15 @@
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */ 19 */
20 20
21#include <linux/cpumask.h>
21#include <linux/init.h> 22#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/cpumask.h> 24#include <linux/kernel.h>
25
26#include <soc/tegra/fuse.h>
25 27
26#include "flowctrl.h" 28#include "flowctrl.h"
27#include "iomap.h" 29#include "iomap.h"
28#include "fuse.h"
29 30
30static u8 flowctrl_offset_halt_cpu[] = { 31static u8 flowctrl_offset_halt_cpu[] = {
31 FLOW_CTRL_HALT_CPU0_EVENTS, 32 FLOW_CTRL_HALT_CPU0_EVENTS,
@@ -76,7 +77,7 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
76 int i; 77 int i;
77 78
78 reg = flowctrl_read_cpu_csr(cpuid); 79 reg = flowctrl_read_cpu_csr(cpuid);
79 switch (tegra_chip_id) { 80 switch (tegra_get_chip_id()) {
80 case TEGRA20: 81 case TEGRA20:
81 /* clear wfe bitmap */ 82 /* clear wfe bitmap */
82 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP; 83 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
@@ -117,7 +118,7 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)
117 118
118 /* Disable powergating via flow controller for CPU0 */ 119 /* Disable powergating via flow controller for CPU0 */
119 reg = flowctrl_read_cpu_csr(cpuid); 120 reg = flowctrl_read_cpu_csr(cpuid);
120 switch (tegra_chip_id) { 121 switch (tegra_get_chip_id()) {
121 case TEGRA20: 122 case TEGRA20:
122 /* clear wfe bitmap */ 123 /* clear wfe bitmap */
123 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP; 124 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
deleted file mode 100644
index c9ac23b385be..000000000000
--- a/arch/arm/mach-tegra/fuse.c
+++ /dev/null
@@ -1,252 +0,0 @@
1/*
2 * arch/arm/mach-tegra/fuse.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
6 *
7 * Author:
8 * Colin Cross <ccross@android.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/io.h>
23#include <linux/export.h>
24#include <linux/random.h>
25#include <linux/clk.h>
26#include <linux/tegra-soc.h>
27
28#include "fuse.h"
29#include "iomap.h"
30#include "apbio.h"
31
32/* Tegra20 only */
33#define FUSE_UID_LOW 0x108
34#define FUSE_UID_HIGH 0x10c
35
36/* Tegra30 and later */
37#define FUSE_VENDOR_CODE 0x200
38#define FUSE_FAB_CODE 0x204
39#define FUSE_LOT_CODE_0 0x208
40#define FUSE_LOT_CODE_1 0x20c
41#define FUSE_WAFER_ID 0x210
42#define FUSE_X_COORDINATE 0x214
43#define FUSE_Y_COORDINATE 0x218
44
45#define FUSE_SKU_INFO 0x110
46
47#define TEGRA20_FUSE_SPARE_BIT 0x200
48#define TEGRA30_FUSE_SPARE_BIT 0x244
49
50int tegra_sku_id;
51int tegra_cpu_process_id;
52int tegra_core_process_id;
53int tegra_chip_id;
54int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
55int tegra_soc_speedo_id;
56enum tegra_revision tegra_revision;
57
58static struct clk *fuse_clk;
59static int tegra_fuse_spare_bit;
60static void (*tegra_init_speedo_data)(void);
61
62/* The BCT to use at boot is specified by board straps that can be read
63 * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
64 */
65int tegra_bct_strapping;
66
67#define STRAP_OPT 0x008
68#define GMI_AD0 (1 << 4)
69#define GMI_AD1 (1 << 5)
70#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
71#define RAM_CODE_SHIFT 4
72
73static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
74 [TEGRA_REVISION_UNKNOWN] = "unknown",
75 [TEGRA_REVISION_A01] = "A01",
76 [TEGRA_REVISION_A02] = "A02",
77 [TEGRA_REVISION_A03] = "A03",
78 [TEGRA_REVISION_A03p] = "A03 prime",
79 [TEGRA_REVISION_A04] = "A04",
80};
81
82static void tegra_fuse_enable_clk(void)
83{
84 if (IS_ERR(fuse_clk))
85 fuse_clk = clk_get_sys(NULL, "fuse");
86 if (IS_ERR(fuse_clk))
87 return;
88 clk_prepare_enable(fuse_clk);
89}
90
91static void tegra_fuse_disable_clk(void)
92{
93 if (IS_ERR(fuse_clk))
94 return;
95 clk_disable_unprepare(fuse_clk);
96}
97
98u32 tegra_fuse_readl(unsigned long offset)
99{
100 return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
101}
102
103bool tegra_spare_fuse(int bit)
104{
105 bool ret;
106
107 tegra_fuse_enable_clk();
108
109 ret = tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);
110
111 tegra_fuse_disable_clk();
112
113 return ret;
114}
115
116static enum tegra_revision tegra_get_revision(u32 id)
117{
118 u32 minor_rev = (id >> 16) & 0xf;
119
120 switch (minor_rev) {
121 case 1:
122 return TEGRA_REVISION_A01;
123 case 2:
124 return TEGRA_REVISION_A02;
125 case 3:
126 if (tegra_chip_id == TEGRA20 &&
127 (tegra_spare_fuse(18) || tegra_spare_fuse(19)))
128 return TEGRA_REVISION_A03p;
129 else
130 return TEGRA_REVISION_A03;
131 case 4:
132 return TEGRA_REVISION_A04;
133 default:
134 return TEGRA_REVISION_UNKNOWN;
135 }
136}
137
138static void tegra_get_process_id(void)
139{
140 u32 reg;
141
142 tegra_fuse_enable_clk();
143
144 reg = tegra_fuse_readl(tegra_fuse_spare_bit);
145 tegra_cpu_process_id = (reg >> 6) & 3;
146 reg = tegra_fuse_readl(tegra_fuse_spare_bit);
147 tegra_core_process_id = (reg >> 12) & 3;
148
149 tegra_fuse_disable_clk();
150}
151
152u32 tegra_read_chipid(void)
153{
154 return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
155}
156
157static void __init tegra20_fuse_init_randomness(void)
158{
159 u32 randomness[2];
160
161 randomness[0] = tegra_fuse_readl(FUSE_UID_LOW);
162 randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH);
163
164 add_device_randomness(randomness, sizeof(randomness));
165}
166
167/* Applies to Tegra30 or later */
168static void __init tegra30_fuse_init_randomness(void)
169{
170 u32 randomness[7];
171
172 randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE);
173 randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE);
174 randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0);
175 randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1);
176 randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID);
177 randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE);
178 randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE);
179
180 add_device_randomness(randomness, sizeof(randomness));
181}
182
183void __init tegra_init_fuse(void)
184{
185 u32 id;
186 u32 randomness[5];
187
188 u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
189 reg |= 1 << 28;
190 writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
191
192 /*
193 * Enable FUSE clock. This needs to be hardcoded because the clock
194 * subsystem is not active during early boot.
195 */
196 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
197 reg |= 1 << 7;
198 writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
199 fuse_clk = ERR_PTR(-EINVAL);
200
201 reg = tegra_fuse_readl(FUSE_SKU_INFO);
202 randomness[0] = reg;
203 tegra_sku_id = reg & 0xFF;
204
205 reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
206 randomness[1] = reg;
207 tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
208
209 id = tegra_read_chipid();
210 randomness[2] = id;
211 tegra_chip_id = (id >> 8) & 0xff;
212
213 switch (tegra_chip_id) {
214 case TEGRA20:
215 tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
216 tegra_init_speedo_data = &tegra20_init_speedo_data;
217 break;
218 case TEGRA30:
219 tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
220 tegra_init_speedo_data = &tegra30_init_speedo_data;
221 break;
222 case TEGRA114:
223 tegra_init_speedo_data = &tegra114_init_speedo_data;
224 break;
225 default:
226 pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
227 tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
228 tegra_init_speedo_data = &tegra_get_process_id;
229 }
230
231 tegra_revision = tegra_get_revision(id);
232 tegra_init_speedo_data();
233 randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id;
234 randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id;
235
236 add_device_randomness(randomness, sizeof(randomness));
237 switch (tegra_chip_id) {
238 case TEGRA20:
239 tegra20_fuse_init_randomness();
240 break;
241 case TEGRA30:
242 case TEGRA114:
243 default:
244 tegra30_fuse_init_randomness();
245 break;
246 }
247
248 pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
249 tegra_revision_name[tegra_revision],
250 tegra_sku_id, tegra_cpu_process_id,
251 tegra_core_process_id);
252}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
deleted file mode 100644
index c01d04785d67..000000000000
--- a/arch/arm/mach-tegra/fuse.h
+++ /dev/null
@@ -1,79 +0,0 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
4 *
5 * Author:
6 * Colin Cross <ccross@android.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#ifndef __MACH_TEGRA_FUSE_H
20#define __MACH_TEGRA_FUSE_H
21
22#define SKU_ID_T20 8
23#define SKU_ID_T25SE 20
24#define SKU_ID_AP25 23
25#define SKU_ID_T25 24
26#define SKU_ID_AP25E 27
27#define SKU_ID_T25E 28
28
29#define TEGRA20 0x20
30#define TEGRA30 0x30
31#define TEGRA114 0x35
32#define TEGRA124 0x40
33
34#ifndef __ASSEMBLY__
35enum tegra_revision {
36 TEGRA_REVISION_UNKNOWN = 0,
37 TEGRA_REVISION_A01,
38 TEGRA_REVISION_A02,
39 TEGRA_REVISION_A03,
40 TEGRA_REVISION_A03p,
41 TEGRA_REVISION_A04,
42 TEGRA_REVISION_MAX,
43};
44
45extern int tegra_sku_id;
46extern int tegra_cpu_process_id;
47extern int tegra_core_process_id;
48extern int tegra_chip_id;
49extern int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
50extern int tegra_soc_speedo_id;
51extern enum tegra_revision tegra_revision;
52
53extern int tegra_bct_strapping;
54
55unsigned long long tegra_chip_uid(void);
56void tegra_init_fuse(void);
57bool tegra_spare_fuse(int bit);
58u32 tegra_fuse_readl(unsigned long offset);
59
60#ifdef CONFIG_ARCH_TEGRA_2x_SOC
61void tegra20_init_speedo_data(void);
62#else
63static inline void tegra20_init_speedo_data(void) {}
64#endif
65
66#ifdef CONFIG_ARCH_TEGRA_3x_SOC
67void tegra30_init_speedo_data(void);
68#else
69static inline void tegra30_init_speedo_data(void) {}
70#endif
71
72#ifdef CONFIG_ARCH_TEGRA_114_SOC
73void tegra114_init_speedo_data(void);
74#else
75static inline void tegra114_init_speedo_data(void) {}
76#endif
77#endif /* __ASSEMBLY__ */
78
79#endif
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index ff26af26bd0c..d60339c996cb 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -7,13 +7,15 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10
11#include <linux/clk/tegra.h>
10#include <linux/kernel.h> 12#include <linux/kernel.h>
11#include <linux/smp.h> 13#include <linux/smp.h>
12#include <linux/clk/tegra.h> 14
15#include <soc/tegra/fuse.h>
13 16
14#include <asm/smp_plat.h> 17#include <asm/smp_plat.h>
15 18
16#include "fuse.h"
17#include "sleep.h" 19#include "sleep.h"
18 20
19static void (*tegra_hotplug_shutdown)(void); 21static void (*tegra_hotplug_shutdown)(void);
@@ -51,12 +53,12 @@ void __init tegra_hotplug_init(void)
51 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) 53 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
52 return; 54 return;
53 55
54 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) 56 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)
55 tegra_hotplug_shutdown = tegra20_hotplug_shutdown; 57 tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
56 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 58 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)
57 tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 59 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
58 if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) 60 if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)
59 tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 61 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
60 if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124) 62 if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)
61 tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 63 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
62} 64}
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
index bb9c9c29d181..352de159d2c5 100644
--- a/arch/arm/mach-tegra/io.c
+++ b/arch/arm/mach-tegra/io.c
@@ -18,14 +18,14 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/init.h> 21#include <linux/init.h>
24#include <linux/mm.h>
25#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/kernel.h>
24#include <linux/mm.h>
25#include <linux/module.h>
26 26
27#include <asm/page.h>
28#include <asm/mach/map.h> 27#include <asm/mach/map.h>
28#include <asm/page.h>
29 29
30#include "board.h" 30#include "board.h"
31#include "iomap.h" 31#include "iomap.h"
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 1a74d562dca1..da7be13aecce 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -17,14 +17,14 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/kernel.h>
21#include <linux/cpu_pm.h> 20#include <linux/cpu_pm.h>
22#include <linux/interrupt.h> 21#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/io.h> 22#include <linux/io.h>
25#include <linux/of.h>
26#include <linux/of_address.h>
27#include <linux/irqchip/arm-gic.h> 23#include <linux/irqchip/arm-gic.h>
24#include <linux/irq.h>
25#include <linux/kernel.h>
26#include <linux/of_address.h>
27#include <linux/of.h>
28#include <linux/syscore_ops.h> 28#include <linux/syscore_ops.h>
29 29
30#include "board.h" 30#include "board.h"
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 929d1046e2b4..0466a145b500 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -11,27 +11,28 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14#include <linux/init.h> 14
15#include <linux/errno.h> 15#include <linux/clk/tegra.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/errno.h>
19#include <linux/init.h>
20#include <linux/io.h>
18#include <linux/jiffies.h> 21#include <linux/jiffies.h>
19#include <linux/smp.h> 22#include <linux/smp.h>
20#include <linux/io.h> 23
21#include <linux/clk/tegra.h> 24#include <soc/tegra/fuse.h>
22 25
23#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
24#include <asm/mach-types.h> 27#include <asm/mach-types.h>
25#include <asm/smp_scu.h>
26#include <asm/smp_plat.h> 28#include <asm/smp_plat.h>
27 29#include <asm/smp_scu.h>
28#include "fuse.h"
29#include "flowctrl.h"
30#include "reset.h"
31#include "pmc.h"
32 30
33#include "common.h" 31#include "common.h"
32#include "flowctrl.h"
34#include "iomap.h" 33#include "iomap.h"
34#include "pmc.h"
35#include "reset.h"
35 36
36static cpumask_t tegra_cpu_init_mask; 37static cpumask_t tegra_cpu_init_mask;
37 38
@@ -170,13 +171,13 @@ static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle)
170static int tegra_boot_secondary(unsigned int cpu, 171static int tegra_boot_secondary(unsigned int cpu,
171 struct task_struct *idle) 172 struct task_struct *idle)
172{ 173{
173 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) 174 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)
174 return tegra20_boot_secondary(cpu, idle); 175 return tegra20_boot_secondary(cpu, idle);
175 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 176 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)
176 return tegra30_boot_secondary(cpu, idle); 177 return tegra30_boot_secondary(cpu, idle);
177 if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) 178 if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)
178 return tegra114_boot_secondary(cpu, idle); 179 return tegra114_boot_secondary(cpu, idle);
179 if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124) 180 if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)
180 return tegra114_boot_secondary(cpu, idle); 181 return tegra114_boot_secondary(cpu, idle);
181 182
182 return -EINVAL; 183 return -EINVAL;
diff --git a/arch/arm/mach-tegra/pm-tegra20.c b/arch/arm/mach-tegra/pm-tegra20.c
index d65e1d786400..39ac2b723f2e 100644
--- a/arch/arm/mach-tegra/pm-tegra20.c
+++ b/arch/arm/mach-tegra/pm-tegra20.c
@@ -13,6 +13,7 @@
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17 18
18#include "pm.h" 19#include "pm.h"
diff --git a/arch/arm/mach-tegra/pm-tegra30.c b/arch/arm/mach-tegra/pm-tegra30.c
index 8fa326d6ff1a..46cc19de9916 100644
--- a/arch/arm/mach-tegra/pm-tegra30.c
+++ b/arch/arm/mach-tegra/pm-tegra30.c
@@ -13,6 +13,7 @@
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17 18
18#include "pm.h" 19#include "pm.h"
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index f55b05a29b55..94db3b6664df 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -16,30 +16,31 @@
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19#include <linux/kernel.h> 19#include <linux/clk/tegra.h>
20#include <linux/spinlock.h>
21#include <linux/io.h>
22#include <linux/cpumask.h> 20#include <linux/cpumask.h>
23#include <linux/delay.h>
24#include <linux/cpu_pm.h> 21#include <linux/cpu_pm.h>
25#include <linux/suspend.h> 22#include <linux/delay.h>
26#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/kernel.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
28#include <linux/clk/tegra.h> 27#include <linux/spinlock.h>
28#include <linux/suspend.h>
29
30#include <soc/tegra/fuse.h>
29 31
30#include <asm/smp_plat.h>
31#include <asm/cacheflush.h> 32#include <asm/cacheflush.h>
32#include <asm/suspend.h>
33#include <asm/idmap.h> 33#include <asm/idmap.h>
34#include <asm/proc-fns.h> 34#include <asm/proc-fns.h>
35#include <asm/smp_plat.h>
36#include <asm/suspend.h>
35#include <asm/tlbflush.h> 37#include <asm/tlbflush.h>
36 38
37#include "iomap.h"
38#include "reset.h"
39#include "flowctrl.h" 39#include "flowctrl.h"
40#include "fuse.h" 40#include "iomap.h"
41#include "pm.h"
42#include "pmc.h" 41#include "pmc.h"
42#include "pm.h"
43#include "reset.h"
43#include "sleep.h" 44#include "sleep.h"
44 45
45#ifdef CONFIG_PM_SLEEP 46#ifdef CONFIG_PM_SLEEP
@@ -53,7 +54,7 @@ static int (*tegra_sleep_func)(unsigned long v2p);
53 54
54static void tegra_tear_down_cpu_init(void) 55static void tegra_tear_down_cpu_init(void)
55{ 56{
56 switch (tegra_chip_id) { 57 switch (tegra_get_chip_id()) {
57 case TEGRA20: 58 case TEGRA20:
58 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 59 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
59 tegra_tear_down_cpu = tegra20_tear_down_cpu; 60 tegra_tear_down_cpu = tegra20_tear_down_cpu;
@@ -143,7 +144,7 @@ bool tegra_set_cpu_in_lp2(void)
143 144
144 if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask)) 145 if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
145 last_cpu = true; 146 last_cpu = true;
146 else if (tegra_chip_id == TEGRA20 && phy_cpu_id == 1) 147 else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1)
147 tegra20_cpu_set_resettable_soon(); 148 tegra20_cpu_set_resettable_soon();
148 149
149 spin_unlock(&tegra_lp2_lock); 150 spin_unlock(&tegra_lp2_lock);
@@ -212,7 +213,7 @@ static int tegra_sleep_core(unsigned long v2p)
212 */ 213 */
213static bool tegra_lp1_iram_hook(void) 214static bool tegra_lp1_iram_hook(void)
214{ 215{
215 switch (tegra_chip_id) { 216 switch (tegra_get_chip_id()) {
216 case TEGRA20: 217 case TEGRA20:
217 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 218 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
218 tegra20_lp1_iram_hook(); 219 tegra20_lp1_iram_hook();
@@ -242,7 +243,7 @@ static bool tegra_lp1_iram_hook(void)
242 243
243static bool tegra_sleep_core_init(void) 244static bool tegra_sleep_core_init(void)
244{ 245{
245 switch (tegra_chip_id) { 246 switch (tegra_get_chip_id()) {
246 case TEGRA20: 247 case TEGRA20:
247 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 248 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
248 tegra20_sleep_core_init(); 249 tegra20_sleep_core_init();
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index 7c7123e7557b..69df18090c8b 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -15,15 +15,16 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/kernel.h>
19#include <linux/clk.h> 18#include <linux/clk.h>
20#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/kernel.h>
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23#include <linux/tegra-powergate.h> 23
24#include <soc/tegra/fuse.h>
25#include <soc/tegra/powergate.h>
24 26
25#include "flowctrl.h" 27#include "flowctrl.h"
26#include "fuse.h"
27#include "pm.h" 28#include "pm.h"
28#include "pmc.h" 29#include "pmc.h"
29#include "sleep.h" 30#include "sleep.h"
@@ -251,7 +252,7 @@ void tegra_pmc_pm_set(enum tegra_suspend_mode mode)
251 reg |= TEGRA_POWER_CPU_PWRREQ_OE; 252 reg |= TEGRA_POWER_CPU_PWRREQ_OE;
252 reg &= ~TEGRA_POWER_EFFECT_LP0; 253 reg &= ~TEGRA_POWER_EFFECT_LP0;
253 254
254 switch (tegra_chip_id) { 255 switch (tegra_get_chip_id()) {
255 case TEGRA20: 256 case TEGRA20:
256 case TEGRA30: 257 case TEGRA30:
257 break; 258 break;
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index 4cefc5cd6bed..0a14b8638437 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -17,21 +17,22 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/kernel.h>
21#include <linux/clk.h> 20#include <linux/clk.h>
21#include <linux/clk/tegra.h>
22#include <linux/debugfs.h> 22#include <linux/debugfs.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/export.h> 25#include <linux/export.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/kernel.h>
28#include <linux/reset.h> 29#include <linux/reset.h>
29#include <linux/seq_file.h> 30#include <linux/seq_file.h>
30#include <linux/spinlock.h> 31#include <linux/spinlock.h>
31#include <linux/clk/tegra.h>
32#include <linux/tegra-powergate.h>
33 32
34#include "fuse.h" 33#include <soc/tegra/fuse.h>
34#include <soc/tegra/powergate.h>
35
35#include "iomap.h" 36#include "iomap.h"
36 37
37#define DPD_SAMPLE 0x020 38#define DPD_SAMPLE 0x020
@@ -157,7 +158,7 @@ int tegra_powergate_remove_clamping(int id)
157 * The Tegra124 GPU has a separate register (with different semantics) 158 * The Tegra124 GPU has a separate register (with different semantics)
158 * to remove clamps. 159 * to remove clamps.
159 */ 160 */
160 if (tegra_chip_id == TEGRA124) { 161 if (tegra_get_chip_id() == TEGRA124) {
161 if (id == TEGRA_POWERGATE_3D) { 162 if (id == TEGRA_POWERGATE_3D) {
162 pmc_write(0, GPU_RG_CNTRL); 163 pmc_write(0, GPU_RG_CNTRL);
163 return 0; 164 return 0;
@@ -227,7 +228,7 @@ int tegra_cpu_powergate_id(int cpuid)
227 228
228int __init tegra_powergate_init(void) 229int __init tegra_powergate_init(void)
229{ 230{
230 switch (tegra_chip_id) { 231 switch (tegra_get_chip_id()) {
231 case TEGRA20: 232 case TEGRA20:
232 tegra_num_powerdomains = 7; 233 tegra_num_powerdomains = 7;
233 break; 234 break;
@@ -368,7 +369,7 @@ int __init tegra_powergate_debugfs_init(void)
368{ 369{
369 struct dentry *d; 370 struct dentry *d;
370 371
371 switch (tegra_chip_id) { 372 switch (tegra_get_chip_id()) {
372 case TEGRA20: 373 case TEGRA20:
373 powergate_name = powergate_name_t20; 374 powergate_name = powergate_name_t20;
374 break; 375 break;
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 578d4d1ad648..7b2baab0f0bd 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -14,14 +14,15 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/linkage.h>
18#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/linkage.h>
19
20#include <soc/tegra/fuse.h>
19 21
20#include <asm/cache.h>
21#include <asm/asm-offsets.h> 22#include <asm/asm-offsets.h>
23#include <asm/cache.h>
22 24
23#include "flowctrl.h" 25#include "flowctrl.h"
24#include "fuse.h"
25#include "iomap.h" 26#include "iomap.h"
26#include "reset.h" 27#include "reset.h"
27#include "sleep.h" 28#include "sleep.h"
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 146fe8e0ae7c..5377495d41b8 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -14,20 +14,21 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/bitops.h>
18#include <linux/cpumask.h>
17#include <linux/init.h> 19#include <linux/init.h>
18#include <linux/io.h> 20#include <linux/io.h>
19#include <linux/cpumask.h> 21
20#include <linux/bitops.h> 22#include <soc/tegra/fuse.h>
21 23
22#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
23#include <asm/hardware/cache-l2x0.h>
24#include <asm/firmware.h> 25#include <asm/firmware.h>
26#include <asm/hardware/cache-l2x0.h>
25 27
26#include "iomap.h" 28#include "iomap.h"
27#include "irammap.h" 29#include "irammap.h"
28#include "reset.h" 30#include "reset.h"
29#include "sleep.h" 31#include "sleep.h"
30#include "fuse.h"
31 32
32#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \ 33#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
33 TEGRA_IRAM_RESET_HANDLER_OFFSET) 34 TEGRA_IRAM_RESET_HANDLER_OFFSET)
@@ -53,7 +54,7 @@ static void __init tegra_cpu_reset_handler_set(const u32 reset_address)
53 * Prevent further modifications to the physical reset vector. 54 * Prevent further modifications to the physical reset vector.
54 * NOTE: Has no effect on chips prior to Tegra30. 55 * NOTE: Has no effect on chips prior to Tegra30.
55 */ 56 */
56 if (tegra_chip_id != TEGRA20) { 57 if (tegra_get_chip_id() != TEGRA20) {
57 reg = readl(sb_ctrl); 58 reg = readl(sb_ctrl);
58 reg |= 2; 59 reg |= 2;
59 writel(reg, sb_ctrl); 60 writel(reg, sb_ctrl);
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index b16d4a57fa59..8ea699b8e3cb 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -16,14 +16,15 @@
16 16
17#include <linux/linkage.h> 17#include <linux/linkage.h>
18 18
19#include <asm/assembler.h> 19#include <soc/tegra/fuse.h>
20
20#include <asm/asm-offsets.h> 21#include <asm/asm-offsets.h>
22#include <asm/assembler.h>
21#include <asm/cache.h> 23#include <asm/cache.h>
22 24
25#include "flowctrl.h"
23#include "irammap.h" 26#include "irammap.h"
24#include "fuse.h"
25#include "sleep.h" 27#include "sleep.h"
26#include "flowctrl.h"
27 28
28#define EMC_CFG 0xc 29#define EMC_CFG 0xc
29#define EMC_ADR_CFG 0x10 30#define EMC_ADR_CFG 0x10
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index 15ac9fcc96b1..6ccbc8ca1db5 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -16,37 +16,37 @@
16 * 16 *
17 */ 17 */
18 18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/serial_8250.h>
23#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/clk/tegra.h>
24#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <linux/irqchip.h>
25#include <linux/irqdomain.h> 25#include <linux/irqdomain.h>
26#include <linux/of.h> 26#include <linux/kernel.h>
27#include <linux/of_address.h> 27#include <linux/of_address.h>
28#include <linux/of_fdt.h> 28#include <linux/of_fdt.h>
29#include <linux/of.h>
29#include <linux/of_platform.h> 30#include <linux/of_platform.h>
30#include <linux/pda_power.h> 31#include <linux/pda_power.h>
31#include <linux/io.h> 32#include <linux/platform_device.h>
33#include <linux/serial_8250.h>
32#include <linux/slab.h> 34#include <linux/slab.h>
33#include <linux/sys_soc.h> 35#include <linux/sys_soc.h>
34#include <linux/usb/tegra_usb_phy.h> 36#include <linux/usb/tegra_usb_phy.h>
35#include <linux/clk/tegra.h> 37
36#include <linux/irqchip.h> 38#include <soc/tegra/fuse.h>
37 39
38#include <asm/hardware/cache-l2x0.h> 40#include <asm/hardware/cache-l2x0.h>
39#include <asm/mach-types.h>
40#include <asm/mach/arch.h> 41#include <asm/mach/arch.h>
41#include <asm/mach/time.h> 42#include <asm/mach/time.h>
43#include <asm/mach-types.h>
42#include <asm/setup.h> 44#include <asm/setup.h>
43#include <asm/trusted_foundations.h> 45#include <asm/trusted_foundations.h>
44 46
45#include "apbio.h"
46#include "board.h" 47#include "board.h"
47#include "common.h" 48#include "common.h"
48#include "cpuidle.h" 49#include "cpuidle.h"
49#include "fuse.h"
50#include "iomap.h" 50#include "iomap.h"
51#include "irq.h" 51#include "irq.h"
52#include "pmc.h" 52#include "pmc.h"
@@ -73,7 +73,6 @@ u32 tegra_uart_config[3] = {
73static void __init tegra_init_early(void) 73static void __init tegra_init_early(void)
74{ 74{
75 of_register_trusted_foundations(); 75 of_register_trusted_foundations();
76 tegra_apb_io_init();
77 tegra_init_fuse(); 76 tegra_init_fuse();
78 tegra_cpu_reset_handler_init(); 77 tegra_cpu_reset_handler_init();
79 tegra_powergate_init(); 78 tegra_powergate_init();
@@ -103,8 +102,9 @@ static void __init tegra_dt_init(void)
103 goto out; 102 goto out;
104 103
105 soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra"); 104 soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra");
106 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_revision); 105 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d",
107 soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", tegra_chip_id); 106 tegra_sku_info.revision);
107 soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
108 108
109 soc_dev = soc_device_register(soc_dev_attr); 109 soc_dev = soc_device_register(soc_dev_attr);
110 if (IS_ERR(soc_dev)) { 110 if (IS_ERR(soc_dev)) {
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
index 558a239954e8..d8961ef4d2e7 100644
--- a/drivers/amba/tegra-ahb.c
+++ b/drivers/amba/tegra-ahb.c
@@ -25,7 +25,8 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/tegra-ahb.h> 28
29#include <soc/tegra/ahb.h>
29 30
30#define DRV_NAME "tegra-ahb" 31#define DRV_NAME "tegra-ahb"
31 32
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c
index 507015314827..0aa8830ae7cc 100644
--- a/drivers/clk/tegra/clk-periph-gate.c
+++ b/drivers/clk/tegra/clk-periph-gate.c
@@ -20,7 +20,8 @@
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/tegra-soc.h> 23
24#include <soc/tegra/fuse.h>
24 25
25#include "clk.h" 26#include "clk.h"
26 27
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 8b10c38b6e3c..5679ffdb3f8c 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -22,8 +22,11 @@
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/of_address.h> 23#include <linux/of_address.h>
24#include <linux/clk/tegra.h> 24#include <linux/clk/tegra.h>
25#include <linux/tegra-powergate.h> 25
26#include <soc/tegra/powergate.h>
27
26#include <dt-bindings/clock/tegra30-car.h> 28#include <dt-bindings/clock/tegra30-car.h>
29
27#include "clk.h" 30#include "clk.h"
28#include "clk-id.h" 31#include "clk-id.h"
29 32
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index c0a7d7723510..f4503ba97400 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -19,7 +19,8 @@
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/clk/tegra.h> 20#include <linux/clk/tegra.h>
21#include <linux/reset-controller.h> 21#include <linux/reset-controller.h>
22#include <linux/tegra-soc.h> 22
23#include <soc/tegra/fuse.h>
23 24
24#include "clk.h" 25#include "clk.h"
25 26
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
index 30f5ba9bd6d0..69974851e564 100644
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ b/drivers/gpu/drm/tegra/gr3d.c
@@ -12,7 +12,8 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/reset.h> 14#include <linux/reset.h>
15#include <linux/tegra-powergate.h> 15
16#include <soc/tegra/powergate.h>
16 17
17#include "drm.h" 18#include "drm.h"
18#include "gem.h" 19#include "gem.h"
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 27c979b50111..eafd0b8a71d2 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -11,7 +11,8 @@
11#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/reset.h> 13#include <linux/reset.h>
14#include <linux/tegra-powergate.h> 14
15#include <soc/tegra/powergate.h>
15 16
16#include <drm/drm_dp_helper.h> 17#include <drm/drm_dp_helper.h>
17 18
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 605b5b46a903..230d06c9328b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -35,7 +35,8 @@
35#include <linux/of_iommu.h> 35#include <linux/of_iommu.h>
36#include <linux/debugfs.h> 36#include <linux/debugfs.h>
37#include <linux/seq_file.h> 37#include <linux/seq_file.h>
38#include <linux/tegra-ahb.h> 38
39#include <soc/tegra/ahb.h>
39 40
40#include <asm/page.h> 41#include <asm/page.h>
41#include <asm/cacheflush.h> 42#include <asm/cacheflush.h>
diff --git a/drivers/misc/fuse/Makefile b/drivers/misc/fuse/Makefile
new file mode 100644
index 000000000000..0679c4febc89
--- /dev/null
+++ b/drivers/misc/fuse/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_ARCH_TEGRA) += tegra/
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 083cf37ca047..a2f0f88be382 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -41,11 +41,12 @@
41#include <linux/reset.h> 41#include <linux/reset.h>
42#include <linux/sizes.h> 42#include <linux/sizes.h>
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/tegra-cpuidle.h>
45#include <linux/tegra-powergate.h>
46#include <linux/vmalloc.h> 44#include <linux/vmalloc.h>
47#include <linux/regulator/consumer.h> 45#include <linux/regulator/consumer.h>
48 46
47#include <soc/tegra/cpuidle.h>
48#include <soc/tegra/powergate.h>
49
49#include <asm/mach/irq.h> 50#include <asm/mach/irq.h>
50#include <asm/mach/map.h> 51#include <asm/mach/map.h>
51#include <asm/mach/pci.h> 52#include <asm/mach/pci.h>
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 0f7c44793b29..3b1b95d932d1 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -3,3 +3,4 @@
3# 3#
4 4
5obj-$(CONFIG_ARCH_QCOM) += qcom/ 5obj-$(CONFIG_ARCH_QCOM) += qcom/
6obj-$(CONFIG_ARCH_TEGRA) += tegra/
diff --git a/drivers/soc/tegra/Makefile b/drivers/soc/tegra/Makefile
new file mode 100644
index 000000000000..236600f91bb3
--- /dev/null
+++ b/drivers/soc/tegra/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_ARCH_TEGRA) += fuse/
diff --git a/drivers/soc/tegra/fuse/Makefile b/drivers/soc/tegra/fuse/Makefile
new file mode 100644
index 000000000000..3af357da91f3
--- /dev/null
+++ b/drivers/soc/tegra/fuse/Makefile
@@ -0,0 +1,8 @@
1obj-y += fuse-tegra.o
2obj-y += fuse-tegra30.o
3obj-y += tegra-apbmisc.o
4obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += fuse-tegra20.o
5obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += speedo-tegra20.o
6obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += speedo-tegra30.o
7obj-$(CONFIG_ARCH_TEGRA_114_SOC) += speedo-tegra114.o
8obj-$(CONFIG_ARCH_TEGRA_124_SOC) += speedo-tegra124.o
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
new file mode 100644
index 000000000000..03742edcfe83
--- /dev/null
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -0,0 +1,156 @@
1/*
2 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#include <linux/device.h>
19#include <linux/kobject.h>
20#include <linux/kernel.h>
21#include <linux/platform_device.h>
22#include <linux/of.h>
23#include <linux/of_address.h>
24#include <linux/io.h>
25
26#include <soc/tegra/fuse.h>
27
28#include "fuse.h"
29
30static u32 (*fuse_readl)(const unsigned int offset);
31static int fuse_size;
32struct tegra_sku_info tegra_sku_info;
33
34static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
35 [TEGRA_REVISION_UNKNOWN] = "unknown",
36 [TEGRA_REVISION_A01] = "A01",
37 [TEGRA_REVISION_A02] = "A02",
38 [TEGRA_REVISION_A03] = "A03",
39 [TEGRA_REVISION_A03p] = "A03 prime",
40 [TEGRA_REVISION_A04] = "A04",
41};
42
43static u8 fuse_readb(const unsigned int offset)
44{
45 u32 val;
46
47 val = fuse_readl(round_down(offset, 4));
48 val >>= (offset % 4) * 8;
49 val &= 0xff;
50
51 return val;
52}
53
54static ssize_t fuse_read(struct file *fd, struct kobject *kobj,
55 struct bin_attribute *attr, char *buf,
56 loff_t pos, size_t size)
57{
58 int i;
59
60 if (pos < 0 || pos >= fuse_size)
61 return 0;
62
63 if (size > fuse_size - pos)
64 size = fuse_size - pos;
65
66 for (i = 0; i < size; i++)
67 buf[i] = fuse_readb(pos + i);
68
69 return i;
70}
71
72static struct bin_attribute fuse_bin_attr = {
73 .attr = { .name = "fuse", .mode = S_IRUGO, },
74 .read = fuse_read,
75};
76
77static const struct of_device_id car_match[] __initconst = {
78 { .compatible = "nvidia,tegra20-car", },
79 { .compatible = "nvidia,tegra30-car", },
80 { .compatible = "nvidia,tegra114-car", },
81 { .compatible = "nvidia,tegra124-car", },
82 {},
83};
84
85static void tegra_enable_fuse_clk(void __iomem *base)
86{
87 u32 reg;
88
89 reg = readl_relaxed(base + 0x48);
90 reg |= 1 << 28;
91 writel(reg, base + 0x48);
92
93 /*
94 * Enable FUSE clock. This needs to be hardcoded because the clock
95 * subsystem is not active during early boot.
96 */
97 reg = readl(base + 0x14);
98 reg |= 1 << 7;
99 writel(reg, base + 0x14);
100}
101
102int tegra_fuse_readl(unsigned long offset, u32 *value)
103{
104 if (!fuse_readl)
105 return -EPROBE_DEFER;
106
107 *value = fuse_readl(offset);
108
109 return 0;
110}
111EXPORT_SYMBOL(tegra_fuse_readl);
112
113int tegra_fuse_create_sysfs(struct device *dev, int size,
114 u32 (*readl)(const unsigned int offset))
115{
116 if (fuse_size)
117 return -ENODEV;
118
119 fuse_bin_attr.size = size;
120 fuse_bin_attr.read = fuse_read;
121
122 fuse_size = size;
123 fuse_readl = readl;
124
125 return device_create_bin_file(dev, &fuse_bin_attr);
126}
127
128void __init tegra_init_fuse(void)
129{
130 struct device_node *np;
131 void __iomem *car_base;
132
133 tegra_init_apbmisc();
134
135 np = of_find_matching_node(NULL, car_match);
136 car_base = of_iomap(np, 0);
137 if (car_base) {
138 tegra_enable_fuse_clk(car_base);
139 iounmap(car_base);
140 } else {
141 pr_err("Could not enable fuse clk. ioremap tegra car failed.\n");
142 return;
143 }
144
145 if (tegra_get_chip_id() == TEGRA20)
146 tegra20_init_fuse_early();
147 else
148 tegra30_init_fuse_early();
149
150 pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
151 tegra_revision_name[tegra_sku_info.revision],
152 tegra_sku_info.sku_id, tegra_sku_info.cpu_process_id,
153 tegra_sku_info.core_process_id);
154 pr_debug("Tegra CPU Speedo ID %d, Soc Speedo ID %d\n",
155 tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
156}
diff --git a/drivers/soc/tegra/fuse/fuse-tegra20.c b/drivers/soc/tegra/fuse/fuse-tegra20.c
new file mode 100644
index 000000000000..7cb63ab6aac2
--- /dev/null
+++ b/drivers/soc/tegra/fuse/fuse-tegra20.c
@@ -0,0 +1,215 @@
1/*
2 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Based on drivers/misc/eeprom/sunxi_sid.c
17 */
18
19#include <linux/device.h>
20#include <linux/clk.h>
21#include <linux/completion.h>
22#include <linux/dmaengine.h>
23#include <linux/dma-mapping.h>
24#include <linux/err.h>
25#include <linux/io.h>
26#include <linux/kernel.h>
27#include <linux/kobject.h>
28#include <linux/of_device.h>
29#include <linux/platform_device.h>
30#include <linux/random.h>
31
32#include <soc/tegra/fuse.h>
33
34#include "fuse.h"
35
36#define FUSE_BEGIN 0x100
37#define FUSE_SIZE 0x1f8
38#define FUSE_UID_LOW 0x08
39#define FUSE_UID_HIGH 0x0c
40
41static phys_addr_t fuse_phys;
42static struct clk *fuse_clk;
43static void __iomem __initdata *fuse_base;
44
45static DEFINE_MUTEX(apb_dma_lock);
46static DECLARE_COMPLETION(apb_dma_wait);
47static struct dma_chan *apb_dma_chan;
48static struct dma_slave_config dma_sconfig;
49static u32 *apb_buffer;
50static dma_addr_t apb_buffer_phys;
51
52static void apb_dma_complete(void *args)
53{
54 complete(&apb_dma_wait);
55}
56
57static u32 tegra20_fuse_readl(const unsigned int offset)
58{
59 int ret;
60 u32 val = 0;
61 struct dma_async_tx_descriptor *dma_desc;
62
63 mutex_lock(&apb_dma_lock);
64
65 dma_sconfig.src_addr = fuse_phys + FUSE_BEGIN + offset;
66 ret = dmaengine_slave_config(apb_dma_chan, &dma_sconfig);
67 if (ret)
68 goto out;
69
70 dma_desc = dmaengine_prep_slave_single(apb_dma_chan, apb_buffer_phys,
71 sizeof(u32), DMA_DEV_TO_MEM,
72 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
73 if (!dma_desc)
74 goto out;
75
76 dma_desc->callback = apb_dma_complete;
77 dma_desc->callback_param = NULL;
78
79 reinit_completion(&apb_dma_wait);
80
81 clk_prepare_enable(fuse_clk);
82
83 dmaengine_submit(dma_desc);
84 dma_async_issue_pending(apb_dma_chan);
85 ret = wait_for_completion_timeout(&apb_dma_wait, msecs_to_jiffies(50));
86
87 if (WARN(ret == 0, "apb read dma timed out"))
88 dmaengine_terminate_all(apb_dma_chan);
89 else
90 val = *apb_buffer;
91
92 clk_disable_unprepare(fuse_clk);
93out:
94 mutex_unlock(&apb_dma_lock);
95
96 return val;
97}
98
99static const struct of_device_id tegra20_fuse_of_match[] = {
100 { .compatible = "nvidia,tegra20-efuse" },
101 {},
102};
103
104static int apb_dma_init(void)
105{
106 dma_cap_mask_t mask;
107
108 dma_cap_zero(mask);
109 dma_cap_set(DMA_SLAVE, mask);
110 apb_dma_chan = dma_request_channel(mask, NULL, NULL);
111 if (!apb_dma_chan)
112 return -EPROBE_DEFER;
113
114 apb_buffer = dma_alloc_coherent(NULL, sizeof(u32), &apb_buffer_phys,
115 GFP_KERNEL);
116 if (!apb_buffer) {
117 dma_release_channel(apb_dma_chan);
118 return -ENOMEM;
119 }
120
121 dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
122 dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
123 dma_sconfig.src_maxburst = 1;
124 dma_sconfig.dst_maxburst = 1;
125
126 return 0;
127}
128
129static int tegra20_fuse_probe(struct platform_device *pdev)
130{
131 struct resource *res;
132 int err;
133
134 fuse_clk = devm_clk_get(&pdev->dev, NULL);
135 if (IS_ERR(fuse_clk)) {
136 dev_err(&pdev->dev, "missing clock");
137 return PTR_ERR(fuse_clk);
138 }
139
140 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
141 if (!res)
142 return -EINVAL;
143 fuse_phys = res->start;
144
145 err = apb_dma_init();
146 if (err)
147 return err;
148
149 if (tegra_fuse_create_sysfs(&pdev->dev, FUSE_SIZE, tegra20_fuse_readl))
150 return -ENODEV;
151
152 dev_dbg(&pdev->dev, "loaded\n");
153
154 return 0;
155}
156
157static struct platform_driver tegra20_fuse_driver = {
158 .probe = tegra20_fuse_probe,
159 .driver = {
160 .name = "tegra20_fuse",
161 .owner = THIS_MODULE,
162 .of_match_table = tegra20_fuse_of_match,
163 }
164};
165
166static int __init tegra20_fuse_init(void)
167{
168 return platform_driver_register(&tegra20_fuse_driver);
169}
170postcore_initcall(tegra20_fuse_init);
171
172/* Early boot code. This code is called before the devices are created */
173
174u32 __init tegra20_fuse_early(const unsigned int offset)
175{
176 return readl_relaxed(fuse_base + FUSE_BEGIN + offset);
177}
178
179bool __init tegra20_spare_fuse_early(int spare_bit)
180{
181 u32 offset = spare_bit * 4;
182 bool value;
183
184 value = tegra20_fuse_early(offset + 0x100);
185
186 return value;
187}
188
189static void __init tegra20_fuse_add_randomness(void)
190{
191 u32 randomness[7];
192
193 randomness[0] = tegra_sku_info.sku_id;
194 randomness[1] = tegra_read_straps();
195 randomness[2] = tegra_read_chipid();
196 randomness[3] = tegra_sku_info.cpu_process_id << 16;
197 randomness[3] |= tegra_sku_info.core_process_id;
198 randomness[4] = tegra_sku_info.cpu_speedo_id << 16;
199 randomness[4] |= tegra_sku_info.soc_speedo_id;
200 randomness[5] = tegra20_fuse_early(FUSE_UID_LOW);
201 randomness[6] = tegra20_fuse_early(FUSE_UID_HIGH);
202
203 add_device_randomness(randomness, sizeof(randomness));
204}
205
206void __init tegra20_init_fuse_early(void)
207{
208 fuse_base = ioremap(TEGRA_FUSE_BASE, TEGRA_FUSE_SIZE);
209
210 tegra_init_revision();
211 tegra20_init_speedo_data(&tegra_sku_info);
212 tegra20_fuse_add_randomness();
213
214 iounmap(fuse_base);
215}
diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c
new file mode 100644
index 000000000000..5999cf34ab70
--- /dev/null
+++ b/drivers/soc/tegra/fuse/fuse-tegra30.c
@@ -0,0 +1,224 @@
1/*
2 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#include <linux/device.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/io.h>
22#include <linux/kernel.h>
23#include <linux/of_device.h>
24#include <linux/of_address.h>
25#include <linux/platform_device.h>
26#include <linux/random.h>
27
28#include <soc/tegra/fuse.h>
29
30#include "fuse.h"
31
32#define FUSE_BEGIN 0x100
33
34/* Tegra30 and later */
35#define FUSE_VENDOR_CODE 0x100
36#define FUSE_FAB_CODE 0x104
37#define FUSE_LOT_CODE_0 0x108
38#define FUSE_LOT_CODE_1 0x10c
39#define FUSE_WAFER_ID 0x110
40#define FUSE_X_COORDINATE 0x114
41#define FUSE_Y_COORDINATE 0x118
42
43#define FUSE_HAS_REVISION_INFO BIT(0)
44
45enum speedo_idx {
46 SPEEDO_TEGRA30 = 0,
47 SPEEDO_TEGRA114,
48 SPEEDO_TEGRA124,
49};
50
51struct tegra_fuse_info {
52 int size;
53 int spare_bit;
54 enum speedo_idx speedo_idx;
55};
56
57static void __iomem *fuse_base;
58static struct clk *fuse_clk;
59static struct tegra_fuse_info *fuse_info;
60
61u32 tegra30_fuse_readl(const unsigned int offset)
62{
63 u32 val;
64
65 /*
66 * early in the boot, the fuse clock will be enabled by
67 * tegra_init_fuse()
68 */
69
70 if (fuse_clk)
71 clk_prepare_enable(fuse_clk);
72
73 val = readl_relaxed(fuse_base + FUSE_BEGIN + offset);
74
75 if (fuse_clk)
76 clk_disable_unprepare(fuse_clk);
77
78 return val;
79}
80
81static struct tegra_fuse_info tegra30_info = {
82 .size = 0x2a4,
83 .spare_bit = 0x144,
84 .speedo_idx = SPEEDO_TEGRA30,
85};
86
87static struct tegra_fuse_info tegra114_info = {
88 .size = 0x2a0,
89 .speedo_idx = SPEEDO_TEGRA114,
90};
91
92static struct tegra_fuse_info tegra124_info = {
93 .size = 0x300,
94 .speedo_idx = SPEEDO_TEGRA124,
95};
96
97static const struct of_device_id tegra30_fuse_of_match[] = {
98 { .compatible = "nvidia,tegra30-efuse", .data = &tegra30_info },
99 { .compatible = "nvidia,tegra114-efuse", .data = &tegra114_info },
100 { .compatible = "nvidia,tegra124-efuse", .data = &tegra124_info },
101 {},
102};
103
104static int tegra30_fuse_probe(struct platform_device *pdev)
105{
106 const struct of_device_id *of_dev_id;
107
108 of_dev_id = of_match_device(tegra30_fuse_of_match, &pdev->dev);
109 if (!of_dev_id)
110 return -ENODEV;
111
112 fuse_clk = devm_clk_get(&pdev->dev, NULL);
113 if (IS_ERR(fuse_clk)) {
114 dev_err(&pdev->dev, "missing clock");
115 return PTR_ERR(fuse_clk);
116 }
117
118 platform_set_drvdata(pdev, NULL);
119
120 if (tegra_fuse_create_sysfs(&pdev->dev, fuse_info->size,
121 tegra30_fuse_readl))
122 return -ENODEV;
123
124 dev_dbg(&pdev->dev, "loaded\n");
125
126 return 0;
127}
128
129static struct platform_driver tegra30_fuse_driver = {
130 .probe = tegra30_fuse_probe,
131 .driver = {
132 .name = "tegra_fuse",
133 .owner = THIS_MODULE,
134 .of_match_table = tegra30_fuse_of_match,
135 }
136};
137
138static int __init tegra30_fuse_init(void)
139{
140 return platform_driver_register(&tegra30_fuse_driver);
141}
142postcore_initcall(tegra30_fuse_init);
143
144/* Early boot code. This code is called before the devices are created */
145
146typedef void (*speedo_f)(struct tegra_sku_info *sku_info);
147
148static speedo_f __initdata speedo_tbl[] = {
149 [SPEEDO_TEGRA30] = tegra30_init_speedo_data,
150 [SPEEDO_TEGRA114] = tegra114_init_speedo_data,
151 [SPEEDO_TEGRA124] = tegra124_init_speedo_data,
152};
153
154static void __init tegra30_fuse_add_randomness(void)
155{
156 u32 randomness[12];
157
158 randomness[0] = tegra_sku_info.sku_id;
159 randomness[1] = tegra_read_straps();
160 randomness[2] = tegra_read_chipid();
161 randomness[3] = tegra_sku_info.cpu_process_id << 16;
162 randomness[3] |= tegra_sku_info.core_process_id;
163 randomness[4] = tegra_sku_info.cpu_speedo_id << 16;
164 randomness[4] |= tegra_sku_info.soc_speedo_id;
165 randomness[5] = tegra30_fuse_readl(FUSE_VENDOR_CODE);
166 randomness[6] = tegra30_fuse_readl(FUSE_FAB_CODE);
167 randomness[7] = tegra30_fuse_readl(FUSE_LOT_CODE_0);
168 randomness[8] = tegra30_fuse_readl(FUSE_LOT_CODE_1);
169 randomness[9] = tegra30_fuse_readl(FUSE_WAFER_ID);
170 randomness[10] = tegra30_fuse_readl(FUSE_X_COORDINATE);
171 randomness[11] = tegra30_fuse_readl(FUSE_Y_COORDINATE);
172
173 add_device_randomness(randomness, sizeof(randomness));
174}
175
176static void __init legacy_fuse_init(void)
177{
178 switch (tegra_get_chip_id()) {
179 case TEGRA30:
180 fuse_info = &tegra30_info;
181 break;
182 case TEGRA114:
183 fuse_info = &tegra114_info;
184 break;
185 case TEGRA124:
186 fuse_info = &tegra124_info;
187 break;
188 default:
189 return;
190 }
191
192 fuse_base = ioremap(TEGRA_FUSE_BASE, TEGRA_FUSE_SIZE);
193}
194
195bool __init tegra30_spare_fuse(int spare_bit)
196{
197 u32 offset = fuse_info->spare_bit + spare_bit * 4;
198
199 return tegra30_fuse_readl(offset) & 1;
200}
201
202void __init tegra30_init_fuse_early(void)
203{
204 struct device_node *np;
205 const struct of_device_id *of_match;
206
207 np = of_find_matching_node_and_match(NULL, tegra30_fuse_of_match,
208 &of_match);
209 if (np) {
210 fuse_base = of_iomap(np, 0);
211 fuse_info = (struct tegra_fuse_info *)of_match->data;
212 } else
213 legacy_fuse_init();
214
215 if (!fuse_base) {
216 pr_warn("fuse DT node missing and unknown chip id: 0x%02x\n",
217 tegra_get_chip_id());
218 return;
219 }
220
221 tegra_init_revision();
222 speedo_tbl[fuse_info->speedo_idx](&tegra_sku_info);
223 tegra30_fuse_add_randomness();
224}
diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h
new file mode 100644
index 000000000000..3a398bf3572c
--- /dev/null
+++ b/drivers/soc/tegra/fuse/fuse.h
@@ -0,0 +1,71 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
4 *
5 * Author:
6 * Colin Cross <ccross@android.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#ifndef __DRIVERS_MISC_TEGRA_FUSE_H
20#define __DRIVERS_MISC_TEGRA_FUSE_H
21
22#define TEGRA_FUSE_BASE 0x7000f800
23#define TEGRA_FUSE_SIZE 0x400
24
25int tegra_fuse_create_sysfs(struct device *dev, int size,
26 u32 (*readl)(const unsigned int offset));
27
28bool tegra30_spare_fuse(int bit);
29u32 tegra30_fuse_readl(const unsigned int offset);
30void tegra30_init_fuse_early(void);
31void tegra_init_revision(void);
32void tegra_init_apbmisc(void);
33
34#ifdef CONFIG_ARCH_TEGRA_2x_SOC
35void tegra20_init_speedo_data(struct tegra_sku_info *sku_info);
36bool tegra20_spare_fuse_early(int spare_bit);
37void tegra20_init_fuse_early(void);
38u32 tegra20_fuse_early(const unsigned int offset);
39#else
40static inline void tegra20_init_speedo_data(struct tegra_sku_info *sku_info) {}
41static inline bool tegra20_spare_fuse_early(int spare_bit)
42{
43 return false;
44}
45static inline void tegra20_init_fuse_early(void) {}
46static inline u32 tegra20_fuse_early(const unsigned int offset)
47{
48 return 0;
49}
50#endif
51
52
53#ifdef CONFIG_ARCH_TEGRA_3x_SOC
54void tegra30_init_speedo_data(struct tegra_sku_info *sku_info);
55#else
56static inline void tegra30_init_speedo_data(struct tegra_sku_info *sku_info) {}
57#endif
58
59#ifdef CONFIG_ARCH_TEGRA_114_SOC
60void tegra114_init_speedo_data(struct tegra_sku_info *sku_info);
61#else
62static inline void tegra114_init_speedo_data(struct tegra_sku_info *sku_info) {}
63#endif
64
65#ifdef CONFIG_ARCH_TEGRA_124_SOC
66void tegra124_init_speedo_data(struct tegra_sku_info *sku_info);
67#else
68static inline void tegra124_init_speedo_data(struct tegra_sku_info *sku_info) {}
69#endif
70
71#endif
diff --git a/arch/arm/mach-tegra/tegra114_speedo.c b/drivers/soc/tegra/fuse/speedo-tegra114.c
index 5218d4853cd3..2a6ca036f09f 100644
--- a/arch/arm/mach-tegra/tegra114_speedo.c
+++ b/drivers/soc/tegra/fuse/speedo-tegra114.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -14,13 +14,16 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/kernel.h>
18#include <linux/bug.h> 17#include <linux/bug.h>
18#include <linux/device.h>
19#include <linux/kernel.h>
20
21#include <soc/tegra/fuse.h>
19 22
20#include "fuse.h" 23#include "fuse.h"
21 24
22#define CORE_PROCESS_CORNERS_NUM 2 25#define CORE_PROCESS_CORNERS 2
23#define CPU_PROCESS_CORNERS_NUM 2 26#define CPU_PROCESS_CORNERS 2
24 27
25enum { 28enum {
26 THRESHOLD_INDEX_0, 29 THRESHOLD_INDEX_0,
@@ -28,54 +31,57 @@ enum {
28 THRESHOLD_INDEX_COUNT, 31 THRESHOLD_INDEX_COUNT,
29}; 32};
30 33
31static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = { 34static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = {
32 {1123, UINT_MAX}, 35 {1123, UINT_MAX},
33 {0, UINT_MAX}, 36 {0, UINT_MAX},
34}; 37};
35 38
36static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = { 39static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
37 {1695, UINT_MAX}, 40 {1695, UINT_MAX},
38 {0, UINT_MAX}, 41 {0, UINT_MAX},
39}; 42};
40 43
41static void rev_sku_to_speedo_ids(int rev, int sku, int *threshold) 44static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
45 int *threshold)
42{ 46{
43 u32 tmp; 47 u32 tmp;
48 u32 sku = sku_info->sku_id;
49 enum tegra_revision rev = sku_info->revision;
44 50
45 switch (sku) { 51 switch (sku) {
46 case 0x00: 52 case 0x00:
47 case 0x10: 53 case 0x10:
48 case 0x05: 54 case 0x05:
49 case 0x06: 55 case 0x06:
50 tegra_cpu_speedo_id = 1; 56 sku_info->cpu_speedo_id = 1;
51 tegra_soc_speedo_id = 0; 57 sku_info->soc_speedo_id = 0;
52 *threshold = THRESHOLD_INDEX_0; 58 *threshold = THRESHOLD_INDEX_0;
53 break; 59 break;
54 60
55 case 0x03: 61 case 0x03:
56 case 0x04: 62 case 0x04:
57 tegra_cpu_speedo_id = 2; 63 sku_info->cpu_speedo_id = 2;
58 tegra_soc_speedo_id = 1; 64 sku_info->soc_speedo_id = 1;
59 *threshold = THRESHOLD_INDEX_1; 65 *threshold = THRESHOLD_INDEX_1;
60 break; 66 break;
61 67
62 default: 68 default:
63 pr_err("Tegra114 Unknown SKU %d\n", sku); 69 pr_err("Tegra Unknown SKU %d\n", sku);
64 tegra_cpu_speedo_id = 0; 70 sku_info->cpu_speedo_id = 0;
65 tegra_soc_speedo_id = 0; 71 sku_info->soc_speedo_id = 0;
66 *threshold = THRESHOLD_INDEX_0; 72 *threshold = THRESHOLD_INDEX_0;
67 break; 73 break;
68 } 74 }
69 75
70 if (rev == TEGRA_REVISION_A01) { 76 if (rev == TEGRA_REVISION_A01) {
71 tmp = tegra_fuse_readl(0x270) << 1; 77 tmp = tegra30_fuse_readl(0x270) << 1;
72 tmp |= tegra_fuse_readl(0x26c); 78 tmp |= tegra30_fuse_readl(0x26c);
73 if (!tmp) 79 if (!tmp)
74 tegra_cpu_speedo_id = 0; 80 sku_info->cpu_speedo_id = 0;
75 } 81 }
76} 82}
77 83
78void tegra114_init_speedo_data(void) 84void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
79{ 85{
80 u32 cpu_speedo_val; 86 u32 cpu_speedo_val;
81 u32 core_speedo_val; 87 u32 core_speedo_val;
@@ -87,18 +93,18 @@ void tegra114_init_speedo_data(void)
87 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != 93 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
88 THRESHOLD_INDEX_COUNT); 94 THRESHOLD_INDEX_COUNT);
89 95
90 rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id, &threshold); 96 rev_sku_to_speedo_ids(sku_info, &threshold);
91 97
92 cpu_speedo_val = tegra_fuse_readl(0x12c) + 1024; 98 cpu_speedo_val = tegra30_fuse_readl(0x12c) + 1024;
93 core_speedo_val = tegra_fuse_readl(0x134); 99 core_speedo_val = tegra30_fuse_readl(0x134);
94 100
95 for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) 101 for (i = 0; i < CPU_PROCESS_CORNERS; i++)
96 if (cpu_speedo_val < cpu_process_speedos[threshold][i]) 102 if (cpu_speedo_val < cpu_process_speedos[threshold][i])
97 break; 103 break;
98 tegra_cpu_process_id = i; 104 sku_info->cpu_process_id = i;
99 105
100 for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) 106 for (i = 0; i < CORE_PROCESS_CORNERS; i++)
101 if (core_speedo_val < core_process_speedos[threshold][i]) 107 if (core_speedo_val < core_process_speedos[threshold][i])
102 break; 108 break;
103 tegra_core_process_id = i; 109 sku_info->core_process_id = i;
104} 110}
diff --git a/drivers/soc/tegra/fuse/speedo-tegra124.c b/drivers/soc/tegra/fuse/speedo-tegra124.c
new file mode 100644
index 000000000000..46362387d974
--- /dev/null
+++ b/drivers/soc/tegra/fuse/speedo-tegra124.c
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/device.h>
18#include <linux/kernel.h>
19#include <linux/bug.h>
20
21#include <soc/tegra/fuse.h>
22
23#include "fuse.h"
24
25#define CPU_PROCESS_CORNERS 2
26#define GPU_PROCESS_CORNERS 2
27#define CORE_PROCESS_CORNERS 2
28
29#define FUSE_CPU_SPEEDO_0 0x14
30#define FUSE_CPU_SPEEDO_1 0x2c
31#define FUSE_CPU_SPEEDO_2 0x30
32#define FUSE_SOC_SPEEDO_0 0x34
33#define FUSE_SOC_SPEEDO_1 0x38
34#define FUSE_SOC_SPEEDO_2 0x3c
35#define FUSE_CPU_IDDQ 0x18
36#define FUSE_SOC_IDDQ 0x40
37#define FUSE_GPU_IDDQ 0x128
38#define FUSE_FT_REV 0x28
39
40enum {
41 THRESHOLD_INDEX_0,
42 THRESHOLD_INDEX_1,
43 THRESHOLD_INDEX_COUNT,
44};
45
46static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
47 {2190, UINT_MAX},
48 {0, UINT_MAX},
49};
50
51static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = {
52 {1965, UINT_MAX},
53 {0, UINT_MAX},
54};
55
56static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = {
57 {2101, UINT_MAX},
58 {0, UINT_MAX},
59};
60
61static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
62 int *threshold)
63{
64 int sku = sku_info->sku_id;
65
66 /* Assign to default */
67 sku_info->cpu_speedo_id = 0;
68 sku_info->soc_speedo_id = 0;
69 sku_info->gpu_speedo_id = 0;
70 *threshold = THRESHOLD_INDEX_0;
71
72 switch (sku) {
73 case 0x00: /* Eng sku */
74 case 0x0F:
75 case 0x23:
76 /* Using the default */
77 break;
78 case 0x83:
79 sku_info->cpu_speedo_id = 2;
80 break;
81
82 case 0x1F:
83 case 0x87:
84 case 0x27:
85 sku_info->cpu_speedo_id = 2;
86 sku_info->soc_speedo_id = 0;
87 sku_info->gpu_speedo_id = 1;
88 *threshold = THRESHOLD_INDEX_0;
89 break;
90 case 0x81:
91 case 0x21:
92 case 0x07:
93 sku_info->cpu_speedo_id = 1;
94 sku_info->soc_speedo_id = 1;
95 sku_info->gpu_speedo_id = 1;
96 *threshold = THRESHOLD_INDEX_1;
97 break;
98 case 0x49:
99 case 0x4A:
100 case 0x48:
101 sku_info->cpu_speedo_id = 4;
102 sku_info->soc_speedo_id = 2;
103 sku_info->gpu_speedo_id = 3;
104 *threshold = THRESHOLD_INDEX_1;
105 break;
106 default:
107 pr_err("Tegra Unknown SKU %d\n", sku);
108 /* Using the default for the error case */
109 break;
110 }
111}
112
113void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)
114{
115 int i, threshold, cpu_speedo_0_value, soc_speedo_0_value;
116 int cpu_iddq_value, gpu_iddq_value, soc_iddq_value;
117
118 BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
119 THRESHOLD_INDEX_COUNT);
120 BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=
121 THRESHOLD_INDEX_COUNT);
122 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
123 THRESHOLD_INDEX_COUNT);
124
125 cpu_speedo_0_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_0);
126
127 /* GPU Speedo is stored in CPU_SPEEDO_2 */
128 sku_info->gpu_speedo_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_2);
129
130 soc_speedo_0_value = tegra30_fuse_readl(FUSE_SOC_SPEEDO_0);
131
132 cpu_iddq_value = tegra30_fuse_readl(FUSE_CPU_IDDQ);
133 soc_iddq_value = tegra30_fuse_readl(FUSE_SOC_IDDQ);
134 gpu_iddq_value = tegra30_fuse_readl(FUSE_GPU_IDDQ);
135
136 sku_info->cpu_speedo_value = cpu_speedo_0_value;
137
138 if (sku_info->cpu_speedo_value == 0) {
139 pr_warn("Tegra Warning: Speedo value not fused.\n");
140 WARN_ON(1);
141 return;
142 }
143
144 rev_sku_to_speedo_ids(sku_info, &threshold);
145
146 sku_info->cpu_iddq_value = tegra30_fuse_readl(FUSE_CPU_IDDQ);
147
148 for (i = 0; i < GPU_PROCESS_CORNERS; i++)
149 if (sku_info->gpu_speedo_value <
150 gpu_process_speedos[threshold][i])
151 break;
152 sku_info->gpu_process_id = i;
153
154 for (i = 0; i < CPU_PROCESS_CORNERS; i++)
155 if (sku_info->cpu_speedo_value <
156 cpu_process_speedos[threshold][i])
157 break;
158 sku_info->cpu_process_id = i;
159
160 for (i = 0; i < CORE_PROCESS_CORNERS; i++)
161 if (soc_speedo_0_value <
162 core_process_speedos[threshold][i])
163 break;
164 sku_info->core_process_id = i;
165
166 pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",
167 sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
168}
diff --git a/arch/arm/mach-tegra/tegra20_speedo.c b/drivers/soc/tegra/fuse/speedo-tegra20.c
index fa6eb570623f..eff1b63f330d 100644
--- a/arch/arm/mach-tegra/tegra20_speedo.c
+++ b/drivers/soc/tegra/fuse/speedo-tegra20.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -14,8 +14,11 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/kernel.h>
18#include <linux/bug.h> 17#include <linux/bug.h>
18#include <linux/device.h>
19#include <linux/kernel.h>
20
21#include <soc/tegra/fuse.h>
19 22
20#include "fuse.h" 23#include "fuse.h"
21 24
@@ -47,19 +50,19 @@ enum {
47 SPEEDO_ID_COUNT, 50 SPEEDO_ID_COUNT,
48}; 51};
49 52
50static const u32 cpu_process_speedos[][PROCESS_CORNERS_NUM] = { 53static const u32 __initconst cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
51 {315, 366, 420, UINT_MAX}, 54 {315, 366, 420, UINT_MAX},
52 {303, 368, 419, UINT_MAX}, 55 {303, 368, 419, UINT_MAX},
53 {316, 331, 383, UINT_MAX}, 56 {316, 331, 383, UINT_MAX},
54}; 57};
55 58
56static const u32 core_process_speedos[][PROCESS_CORNERS_NUM] = { 59static const u32 __initconst core_process_speedos[][PROCESS_CORNERS_NUM] = {
57 {165, 195, 224, UINT_MAX}, 60 {165, 195, 224, UINT_MAX},
58 {165, 195, 224, UINT_MAX}, 61 {165, 195, 224, UINT_MAX},
59 {165, 195, 224, UINT_MAX}, 62 {165, 195, 224, UINT_MAX},
60}; 63};
61 64
62void tegra20_init_speedo_data(void) 65void __init tegra20_init_speedo_data(struct tegra_sku_info *sku_info)
63{ 66{
64 u32 reg; 67 u32 reg;
65 u32 val; 68 u32 val;
@@ -68,42 +71,40 @@ void tegra20_init_speedo_data(void)
68 BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT); 71 BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT);
69 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT); 72 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT);
70 73
71 if (SPEEDO_ID_SELECT_0(tegra_revision)) 74 if (SPEEDO_ID_SELECT_0(sku_info->revision))
72 tegra_soc_speedo_id = SPEEDO_ID_0; 75 sku_info->soc_speedo_id = SPEEDO_ID_0;
73 else if (SPEEDO_ID_SELECT_1(tegra_sku_id)) 76 else if (SPEEDO_ID_SELECT_1(sku_info->sku_id))
74 tegra_soc_speedo_id = SPEEDO_ID_1; 77 sku_info->soc_speedo_id = SPEEDO_ID_1;
75 else 78 else
76 tegra_soc_speedo_id = SPEEDO_ID_2; 79 sku_info->soc_speedo_id = SPEEDO_ID_2;
77 80
78 val = 0; 81 val = 0;
79 for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) { 82 for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) {
80 reg = tegra_spare_fuse(i) | 83 reg = tegra20_spare_fuse_early(i) |
81 tegra_spare_fuse(i + CPU_SPEEDO_REDUND_OFFS); 84 tegra20_spare_fuse_early(i + CPU_SPEEDO_REDUND_OFFS);
82 val = (val << 1) | (reg & 0x1); 85 val = (val << 1) | (reg & 0x1);
83 } 86 }
84 val = val * SPEEDO_MULT; 87 val = val * SPEEDO_MULT;
85 pr_debug("%s CPU speedo value %u\n", __func__, val); 88 pr_debug("Tegra CPU speedo value %u\n", val);
86 89
87 for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) { 90 for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
88 if (val <= cpu_process_speedos[tegra_soc_speedo_id][i]) 91 if (val <= cpu_process_speedos[sku_info->soc_speedo_id][i])
89 break; 92 break;
90 } 93 }
91 tegra_cpu_process_id = i; 94 sku_info->cpu_process_id = i;
92 95
93 val = 0; 96 val = 0;
94 for (i = CORE_SPEEDO_MSBIT; i >= CORE_SPEEDO_LSBIT; i--) { 97 for (i = CORE_SPEEDO_MSBIT; i >= CORE_SPEEDO_LSBIT; i--) {
95 reg = tegra_spare_fuse(i) | 98 reg = tegra20_spare_fuse_early(i) |
96 tegra_spare_fuse(i + CORE_SPEEDO_REDUND_OFFS); 99 tegra20_spare_fuse_early(i + CORE_SPEEDO_REDUND_OFFS);
97 val = (val << 1) | (reg & 0x1); 100 val = (val << 1) | (reg & 0x1);
98 } 101 }
99 val = val * SPEEDO_MULT; 102 val = val * SPEEDO_MULT;
100 pr_debug("%s Core speedo value %u\n", __func__, val); 103 pr_debug("Core speedo value %u\n", val);
101 104
102 for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) { 105 for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
103 if (val <= core_process_speedos[tegra_soc_speedo_id][i]) 106 if (val <= core_process_speedos[sku_info->soc_speedo_id][i])
104 break; 107 break;
105 } 108 }
106 tegra_core_process_id = i; 109 sku_info->core_process_id = i;
107
108 pr_info("Tegra20 Soc Speedo ID %d", tegra_soc_speedo_id);
109} 110}
diff --git a/arch/arm/mach-tegra/tegra30_speedo.c b/drivers/soc/tegra/fuse/speedo-tegra30.c
index 125cb16424a6..b17f0dcdfebe 100644
--- a/arch/arm/mach-tegra/tegra30_speedo.c
+++ b/drivers/soc/tegra/fuse/speedo-tegra30.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -14,17 +14,20 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/kernel.h>
18#include <linux/bug.h> 17#include <linux/bug.h>
18#include <linux/device.h>
19#include <linux/kernel.h>
20
21#include <soc/tegra/fuse.h>
19 22
20#include "fuse.h" 23#include "fuse.h"
21 24
22#define CORE_PROCESS_CORNERS_NUM 1 25#define CORE_PROCESS_CORNERS 1
23#define CPU_PROCESS_CORNERS_NUM 6 26#define CPU_PROCESS_CORNERS 6
24 27
25#define FUSE_SPEEDO_CALIB_0 0x114 28#define FUSE_SPEEDO_CALIB_0 0x14
26#define FUSE_PACKAGE_INFO 0X1FC 29#define FUSE_PACKAGE_INFO 0XFC
27#define FUSE_TEST_PROG_VER 0X128 30#define FUSE_TEST_PROG_VER 0X28
28 31
29#define G_SPEEDO_BIT_MINUS1 58 32#define G_SPEEDO_BIT_MINUS1 58
30#define G_SPEEDO_BIT_MINUS1_R 59 33#define G_SPEEDO_BIT_MINUS1_R 59
@@ -51,7 +54,7 @@ enum {
51 THRESHOLD_INDEX_COUNT, 54 THRESHOLD_INDEX_COUNT,
52}; 55};
53 56
54static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = { 57static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = {
55 {180}, 58 {180},
56 {170}, 59 {170},
57 {195}, 60 {195},
@@ -66,7 +69,7 @@ static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
66 {180}, 69 {180},
67}; 70};
68 71
69static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = { 72static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
70 {306, 338, 360, 376, UINT_MAX}, 73 {306, 338, 360, 376, UINT_MAX},
71 {295, 336, 358, 375, UINT_MAX}, 74 {295, 336, 358, 375, UINT_MAX},
72 {325, 325, 358, 375, UINT_MAX}, 75 {325, 325, 358, 375, UINT_MAX},
@@ -81,35 +84,34 @@ static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
81 {295, 336, 358, 375, 391, UINT_MAX}, 84 {295, 336, 358, 375, 391, UINT_MAX},
82}; 85};
83 86
84static int threshold_index; 87static int threshold_index __initdata;
85static int package_id;
86 88
87static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp) 89static void __init fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
88{ 90{
89 u32 reg; 91 u32 reg;
90 int ate_ver; 92 int ate_ver;
91 int bit_minus1; 93 int bit_minus1;
92 int bit_minus2; 94 int bit_minus2;
93 95
94 reg = tegra_fuse_readl(FUSE_SPEEDO_CALIB_0); 96 reg = tegra30_fuse_readl(FUSE_SPEEDO_CALIB_0);
95 97
96 *speedo_lp = (reg & 0xFFFF) * 4; 98 *speedo_lp = (reg & 0xFFFF) * 4;
97 *speedo_g = ((reg >> 16) & 0xFFFF) * 4; 99 *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
98 100
99 ate_ver = tegra_fuse_readl(FUSE_TEST_PROG_VER); 101 ate_ver = tegra30_fuse_readl(FUSE_TEST_PROG_VER);
100 pr_info("%s: ATE prog ver %d.%d\n", __func__, ate_ver/10, ate_ver%10); 102 pr_debug("Tegra ATE prog ver %d.%d\n", ate_ver/10, ate_ver%10);
101 103
102 if (ate_ver >= 26) { 104 if (ate_ver >= 26) {
103 bit_minus1 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1); 105 bit_minus1 = tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS1);
104 bit_minus1 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1_R); 106 bit_minus1 |= tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS1_R);
105 bit_minus2 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2); 107 bit_minus2 = tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS2);
106 bit_minus2 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2_R); 108 bit_minus2 |= tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS2_R);
107 *speedo_lp |= (bit_minus1 << 1) | bit_minus2; 109 *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
108 110
109 bit_minus1 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS1); 111 bit_minus1 = tegra30_spare_fuse(G_SPEEDO_BIT_MINUS1);
110 bit_minus1 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS1_R); 112 bit_minus1 |= tegra30_spare_fuse(G_SPEEDO_BIT_MINUS1_R);
111 bit_minus2 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS2); 113 bit_minus2 = tegra30_spare_fuse(G_SPEEDO_BIT_MINUS2);
112 bit_minus2 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS2_R); 114 bit_minus2 |= tegra30_spare_fuse(G_SPEEDO_BIT_MINUS2_R);
113 *speedo_g |= (bit_minus1 << 1) | bit_minus2; 115 *speedo_g |= (bit_minus1 << 1) | bit_minus2;
114 } else { 116 } else {
115 *speedo_lp |= 0x3; 117 *speedo_lp |= 0x3;
@@ -117,133 +119,131 @@ static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
117 } 119 }
118} 120}
119 121
120static void rev_sku_to_speedo_ids(int rev, int sku) 122static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info)
121{ 123{
122 switch (rev) { 124 int package_id = tegra30_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
125
126 switch (sku_info->revision) {
123 case TEGRA_REVISION_A01: 127 case TEGRA_REVISION_A01:
124 tegra_cpu_speedo_id = 0; 128 sku_info->cpu_speedo_id = 0;
125 tegra_soc_speedo_id = 0; 129 sku_info->soc_speedo_id = 0;
126 threshold_index = THRESHOLD_INDEX_0; 130 threshold_index = THRESHOLD_INDEX_0;
127 break; 131 break;
128 case TEGRA_REVISION_A02: 132 case TEGRA_REVISION_A02:
129 case TEGRA_REVISION_A03: 133 case TEGRA_REVISION_A03:
130 switch (sku) { 134 switch (sku_info->sku_id) {
131 case 0x87: 135 case 0x87:
132 case 0x82: 136 case 0x82:
133 tegra_cpu_speedo_id = 1; 137 sku_info->cpu_speedo_id = 1;
134 tegra_soc_speedo_id = 1; 138 sku_info->soc_speedo_id = 1;
135 threshold_index = THRESHOLD_INDEX_1; 139 threshold_index = THRESHOLD_INDEX_1;
136 break; 140 break;
137 case 0x81: 141 case 0x81:
138 switch (package_id) { 142 switch (package_id) {
139 case 1: 143 case 1:
140 tegra_cpu_speedo_id = 2; 144 sku_info->cpu_speedo_id = 2;
141 tegra_soc_speedo_id = 2; 145 sku_info->soc_speedo_id = 2;
142 threshold_index = THRESHOLD_INDEX_2; 146 threshold_index = THRESHOLD_INDEX_2;
143 break; 147 break;
144 case 2: 148 case 2:
145 tegra_cpu_speedo_id = 4; 149 sku_info->cpu_speedo_id = 4;
146 tegra_soc_speedo_id = 1; 150 sku_info->soc_speedo_id = 1;
147 threshold_index = THRESHOLD_INDEX_7; 151 threshold_index = THRESHOLD_INDEX_7;
148 break; 152 break;
149 default: 153 default:
150 pr_err("Tegra30: Unknown pkg %d\n", package_id); 154 pr_err("Tegra Unknown pkg %d\n", package_id);
151 BUG();
152 break; 155 break;
153 } 156 }
154 break; 157 break;
155 case 0x80: 158 case 0x80:
156 switch (package_id) { 159 switch (package_id) {
157 case 1: 160 case 1:
158 tegra_cpu_speedo_id = 5; 161 sku_info->cpu_speedo_id = 5;
159 tegra_soc_speedo_id = 2; 162 sku_info->soc_speedo_id = 2;
160 threshold_index = THRESHOLD_INDEX_8; 163 threshold_index = THRESHOLD_INDEX_8;
161 break; 164 break;
162 case 2: 165 case 2:
163 tegra_cpu_speedo_id = 6; 166 sku_info->cpu_speedo_id = 6;
164 tegra_soc_speedo_id = 2; 167 sku_info->soc_speedo_id = 2;
165 threshold_index = THRESHOLD_INDEX_9; 168 threshold_index = THRESHOLD_INDEX_9;
166 break; 169 break;
167 default: 170 default:
168 pr_err("Tegra30: Unknown pkg %d\n", package_id); 171 pr_err("Tegra Unknown pkg %d\n", package_id);
169 BUG();
170 break; 172 break;
171 } 173 }
172 break; 174 break;
173 case 0x83: 175 case 0x83:
174 switch (package_id) { 176 switch (package_id) {
175 case 1: 177 case 1:
176 tegra_cpu_speedo_id = 7; 178 sku_info->cpu_speedo_id = 7;
177 tegra_soc_speedo_id = 1; 179 sku_info->soc_speedo_id = 1;
178 threshold_index = THRESHOLD_INDEX_10; 180 threshold_index = THRESHOLD_INDEX_10;
179 break; 181 break;
180 case 2: 182 case 2:
181 tegra_cpu_speedo_id = 3; 183 sku_info->cpu_speedo_id = 3;
182 tegra_soc_speedo_id = 2; 184 sku_info->soc_speedo_id = 2;
183 threshold_index = THRESHOLD_INDEX_3; 185 threshold_index = THRESHOLD_INDEX_3;
184 break; 186 break;
185 default: 187 default:
186 pr_err("Tegra30: Unknown pkg %d\n", package_id); 188 pr_err("Tegra Unknown pkg %d\n", package_id);
187 BUG();
188 break; 189 break;
189 } 190 }
190 break; 191 break;
191 case 0x8F: 192 case 0x8F:
192 tegra_cpu_speedo_id = 8; 193 sku_info->cpu_speedo_id = 8;
193 tegra_soc_speedo_id = 1; 194 sku_info->soc_speedo_id = 1;
194 threshold_index = THRESHOLD_INDEX_11; 195 threshold_index = THRESHOLD_INDEX_11;
195 break; 196 break;
196 case 0x08: 197 case 0x08:
197 tegra_cpu_speedo_id = 1; 198 sku_info->cpu_speedo_id = 1;
198 tegra_soc_speedo_id = 1; 199 sku_info->soc_speedo_id = 1;
199 threshold_index = THRESHOLD_INDEX_4; 200 threshold_index = THRESHOLD_INDEX_4;
200 break; 201 break;
201 case 0x02: 202 case 0x02:
202 tegra_cpu_speedo_id = 2; 203 sku_info->cpu_speedo_id = 2;
203 tegra_soc_speedo_id = 2; 204 sku_info->soc_speedo_id = 2;
204 threshold_index = THRESHOLD_INDEX_5; 205 threshold_index = THRESHOLD_INDEX_5;
205 break; 206 break;
206 case 0x04: 207 case 0x04:
207 tegra_cpu_speedo_id = 3; 208 sku_info->cpu_speedo_id = 3;
208 tegra_soc_speedo_id = 2; 209 sku_info->soc_speedo_id = 2;
209 threshold_index = THRESHOLD_INDEX_6; 210 threshold_index = THRESHOLD_INDEX_6;
210 break; 211 break;
211 case 0: 212 case 0:
212 switch (package_id) { 213 switch (package_id) {
213 case 1: 214 case 1:
214 tegra_cpu_speedo_id = 2; 215 sku_info->cpu_speedo_id = 2;
215 tegra_soc_speedo_id = 2; 216 sku_info->soc_speedo_id = 2;
216 threshold_index = THRESHOLD_INDEX_2; 217 threshold_index = THRESHOLD_INDEX_2;
217 break; 218 break;
218 case 2: 219 case 2:
219 tegra_cpu_speedo_id = 3; 220 sku_info->cpu_speedo_id = 3;
220 tegra_soc_speedo_id = 2; 221 sku_info->soc_speedo_id = 2;
221 threshold_index = THRESHOLD_INDEX_3; 222 threshold_index = THRESHOLD_INDEX_3;
222 break; 223 break;
223 default: 224 default:
224 pr_err("Tegra30: Unknown pkg %d\n", package_id); 225 pr_err("Tegra Unknown pkg %d\n", package_id);
225 BUG();
226 break; 226 break;
227 } 227 }
228 break; 228 break;
229 default: 229 default:
230 pr_warn("Tegra30: Unknown SKU %d\n", sku); 230 pr_warn("Tegra Unknown SKU %d\n", sku_info->sku_id);
231 tegra_cpu_speedo_id = 0; 231 sku_info->cpu_speedo_id = 0;
232 tegra_soc_speedo_id = 0; 232 sku_info->soc_speedo_id = 0;
233 threshold_index = THRESHOLD_INDEX_0; 233 threshold_index = THRESHOLD_INDEX_0;
234 break; 234 break;
235 } 235 }
236 break; 236 break;
237 default: 237 default:
238 pr_warn("Tegra30: Unknown chip rev %d\n", rev); 238 pr_warn("Tegra Unknown chip rev %d\n", sku_info->revision);
239 tegra_cpu_speedo_id = 0; 239 sku_info->cpu_speedo_id = 0;
240 tegra_soc_speedo_id = 0; 240 sku_info->soc_speedo_id = 0;
241 threshold_index = THRESHOLD_INDEX_0; 241 threshold_index = THRESHOLD_INDEX_0;
242 break; 242 break;
243 } 243 }
244} 244}
245 245
246void tegra30_init_speedo_data(void) 246void __init tegra30_init_speedo_data(struct tegra_sku_info *sku_info)
247{ 247{
248 u32 cpu_speedo_val; 248 u32 cpu_speedo_val;
249 u32 core_speedo_val; 249 u32 core_speedo_val;
@@ -254,39 +254,35 @@ void tegra30_init_speedo_data(void)
254 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != 254 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
255 THRESHOLD_INDEX_COUNT); 255 THRESHOLD_INDEX_COUNT);
256 256
257 package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
258 257
259 rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id); 258 rev_sku_to_speedo_ids(sku_info);
260 fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val); 259 fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);
261 pr_debug("%s CPU speedo value %u\n", __func__, cpu_speedo_val); 260 pr_debug("Tegra CPU speedo value %u\n", cpu_speedo_val);
262 pr_debug("%s Core speedo value %u\n", __func__, core_speedo_val); 261 pr_debug("Tegra Core speedo value %u\n", core_speedo_val);
263 262
264 for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) { 263 for (i = 0; i < CPU_PROCESS_CORNERS; i++) {
265 if (cpu_speedo_val < cpu_process_speedos[threshold_index][i]) 264 if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
266 break; 265 break;
267 } 266 }
268 tegra_cpu_process_id = i - 1; 267 sku_info->cpu_process_id = i - 1;
269 268
270 if (tegra_cpu_process_id == -1) { 269 if (sku_info->cpu_process_id == -1) {
271 pr_warn("Tegra30: CPU speedo value %3d out of range", 270 pr_warn("Tegra CPU speedo value %3d out of range",
272 cpu_speedo_val); 271 cpu_speedo_val);
273 tegra_cpu_process_id = 0; 272 sku_info->cpu_process_id = 0;
274 tegra_cpu_speedo_id = 1; 273 sku_info->cpu_speedo_id = 1;
275 } 274 }
276 275
277 for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) { 276 for (i = 0; i < CORE_PROCESS_CORNERS; i++) {
278 if (core_speedo_val < core_process_speedos[threshold_index][i]) 277 if (core_speedo_val < core_process_speedos[threshold_index][i])
279 break; 278 break;
280 } 279 }
281 tegra_core_process_id = i - 1; 280 sku_info->core_process_id = i - 1;
282 281
283 if (tegra_core_process_id == -1) { 282 if (sku_info->core_process_id == -1) {
284 pr_warn("Tegra30: CORE speedo value %3d out of range", 283 pr_warn("Tegra CORE speedo value %3d out of range",
285 core_speedo_val); 284 core_speedo_val);
286 tegra_core_process_id = 0; 285 sku_info->core_process_id = 0;
287 tegra_soc_speedo_id = 1; 286 sku_info->soc_speedo_id = 1;
288 } 287 }
289
290 pr_info("Tegra30: CPU Speedo ID %d, Soc Speedo ID %d",
291 tegra_cpu_speedo_id, tegra_soc_speedo_id);
292} 288}
diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c
new file mode 100644
index 000000000000..bfc1d54ac4ad
--- /dev/null
+++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
21#include <linux/io.h>
22
23#include <soc/tegra/fuse.h>
24
25#include "fuse.h"
26
27#define APBMISC_BASE 0x70000800
28#define APBMISC_SIZE 0x64
29#define FUSE_SKU_INFO 0x10
30
31static void __iomem *apbmisc_base;
32static void __iomem *strapping_base;
33
34u32 tegra_read_chipid(void)
35{
36 return readl_relaxed(apbmisc_base + 4);
37}
38
39u8 tegra_get_chip_id(void)
40{
41 u32 id = tegra_read_chipid();
42
43 return (id >> 8) & 0xff;
44}
45
46u32 tegra_read_straps(void)
47{
48 if (strapping_base)
49 return readl_relaxed(strapping_base);
50 else
51 return 0;
52}
53
54static const struct of_device_id apbmisc_match[] __initconst = {
55 { .compatible = "nvidia,tegra20-apbmisc", },
56 {},
57};
58
59void __init tegra_init_revision(void)
60{
61 u32 id, chip_id, minor_rev;
62 int rev;
63
64 id = tegra_read_chipid();
65 chip_id = (id >> 8) & 0xff;
66 minor_rev = (id >> 16) & 0xf;
67
68 switch (minor_rev) {
69 case 1:
70 rev = TEGRA_REVISION_A01;
71 break;
72 case 2:
73 rev = TEGRA_REVISION_A02;
74 break;
75 case 3:
76 if (chip_id == TEGRA20 && (tegra20_spare_fuse_early(18) ||
77 tegra20_spare_fuse_early(19)))
78 rev = TEGRA_REVISION_A03p;
79 else
80 rev = TEGRA_REVISION_A03;
81 break;
82 case 4:
83 rev = TEGRA_REVISION_A04;
84 break;
85 default:
86 rev = TEGRA_REVISION_UNKNOWN;
87 }
88
89 tegra_sku_info.revision = rev;
90
91 if (chip_id == TEGRA20)
92 tegra_sku_info.sku_id = tegra20_fuse_early(FUSE_SKU_INFO);
93 else
94 tegra_sku_info.sku_id = tegra30_fuse_readl(FUSE_SKU_INFO);
95}
96
97void __init tegra_init_apbmisc(void)
98{
99 struct device_node *np;
100
101 np = of_find_matching_node(NULL, apbmisc_match);
102 apbmisc_base = of_iomap(np, 0);
103 if (!apbmisc_base) {
104 pr_warn("ioremap tegra apbmisc failed. using %08x instead\n",
105 APBMISC_BASE);
106 apbmisc_base = ioremap(APBMISC_BASE, APBMISC_SIZE);
107 }
108
109 strapping_base = of_iomap(np, 1);
110 if (!strapping_base)
111 pr_err("ioremap tegra strapping_base failed\n");
112}
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
deleted file mode 100644
index 95f611d78f3a..000000000000
--- a/include/linux/tegra-soc.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __LINUX_TEGRA_SOC_H_
18#define __LINUX_TEGRA_SOC_H_
19
20u32 tegra_read_chipid(void);
21
22#endif /* __LINUX_TEGRA_SOC_H_ */
diff --git a/include/linux/tegra-ahb.h b/include/soc/tegra/ahb.h
index f1cd075ceee1..504eb6f957e5 100644
--- a/include/linux/tegra-ahb.h
+++ b/include/soc/tegra/ahb.h
@@ -11,9 +11,9 @@
11 * more details. 11 * more details.
12 */ 12 */
13 13
14#ifndef __LINUX_AHB_H__ 14#ifndef __SOC_TEGRA_AHB_H__
15#define __LINUX_AHB_H__ 15#define __SOC_TEGRA_AHB_H__
16 16
17extern int tegra_ahb_enable_smmu(struct device_node *ahb); 17extern int tegra_ahb_enable_smmu(struct device_node *ahb);
18 18
19#endif /* __LINUX_AHB_H__ */ 19#endif /* __SOC_TEGRA_AHB_H__ */
diff --git a/include/linux/tegra-cpuidle.h b/include/soc/tegra/cpuidle.h
index 9c6286bbf662..ea04f4225638 100644
--- a/include/linux/tegra-cpuidle.h
+++ b/include/soc/tegra/cpuidle.h
@@ -11,8 +11,8 @@
11 * more details. 11 * more details.
12 */ 12 */
13 13
14#ifndef __LINUX_TEGRA_CPUIDLE_H__ 14#ifndef __SOC_TEGRA_CPUIDLE_H__
15#define __LINUX_TEGRA_CPUIDLE_H__ 15#define __SOC_TEGRA_CPUIDLE_H__
16 16
17#ifdef CONFIG_CPU_IDLE 17#ifdef CONFIG_CPU_IDLE
18void tegra_cpuidle_pcie_irqs_in_use(void); 18void tegra_cpuidle_pcie_irqs_in_use(void);
@@ -22,4 +22,4 @@ static inline void tegra_cpuidle_pcie_irqs_in_use(void)
22} 22}
23#endif 23#endif
24 24
25#endif 25#endif /* __SOC_TEGRA_CPUIDLE_H__ */
diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h
new file mode 100644
index 000000000000..738712d75cfe
--- /dev/null
+++ b/include/soc/tegra/fuse.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __SOC_TEGRA_FUSE_H__
18#define __SOC_TEGRA_FUSE_H__
19
20#define TEGRA20 0x20
21#define TEGRA30 0x30
22#define TEGRA114 0x35
23#define TEGRA124 0x40
24
25#define TEGRA_FUSE_SKU_CALIB_0 0xf0
26#define TEGRA30_FUSE_SATA_CALIB 0x124
27
28#ifndef __ASSEMBLY__
29
30u32 tegra_read_chipid(void);
31u8 tegra_get_chip_id(void);
32
33enum tegra_revision {
34 TEGRA_REVISION_UNKNOWN = 0,
35 TEGRA_REVISION_A01,
36 TEGRA_REVISION_A02,
37 TEGRA_REVISION_A03,
38 TEGRA_REVISION_A03p,
39 TEGRA_REVISION_A04,
40 TEGRA_REVISION_MAX,
41};
42
43struct tegra_sku_info {
44 int sku_id;
45 int cpu_process_id;
46 int cpu_speedo_id;
47 int cpu_speedo_value;
48 int cpu_iddq_value;
49 int core_process_id;
50 int soc_speedo_id;
51 int gpu_speedo_id;
52 int gpu_process_id;
53 int gpu_speedo_value;
54 enum tegra_revision revision;
55};
56
57u32 tegra_read_straps(void);
58u32 tegra_read_chipid(void);
59void tegra_init_fuse(void);
60int tegra_fuse_readl(unsigned long offset, u32 *value);
61
62extern struct tegra_sku_info tegra_sku_info;
63
64#endif /* __ASSEMBLY__ */
65
66#endif /* __SOC_TEGRA_FUSE_H__ */
diff --git a/include/linux/tegra-powergate.h b/include/soc/tegra/powergate.h
index 46f0a07812b4..c16912ed1a8d 100644
--- a/include/linux/tegra-powergate.h
+++ b/include/soc/tegra/powergate.h
@@ -15,8 +15,8 @@
15 * 15 *
16 */ 16 */
17 17
18#ifndef _MACH_TEGRA_POWERGATE_H_ 18#ifndef __SOC_TEGRA_POWERGATE_H__
19#define _MACH_TEGRA_POWERGATE_H_ 19#define __SOC_TEGRA_POWERGATE_H__
20 20
21struct clk; 21struct clk;
22struct reset_control; 22struct reset_control;
@@ -131,4 +131,4 @@ static inline int tegra_io_rail_power_off(int id)
131} 131}
132#endif 132#endif
133 133
134#endif /* _MACH_TEGRA_POWERGATE_H_ */ 134#endif /* __SOC_TEGRA_POWERGATE_H__ */