Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+1442 -854
+11
Documentation/ABI/testing/sysfs-driver-tegra-fuse
··· 1 + What: /sys/devices/*/<our-device>/fuse 2 + Date: February 2014 3 + Contact: Peter De Schrijver <pdeschrijver@nvidia.com> 4 + Description: 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. 10 + Users: any user space application which wants to read the efuses on 11 + Tegra SoC's
+40
Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt
··· 1 + NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse block. 2 + 3 + Required 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 + 28 + Example: 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 +
+13
Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt
··· 1 + NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block 2 + 3 + Required 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 +
+15
arch/arm/boot/dts/tegra114.dtsi
··· 220 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 229 pinmux: pinmux@70000868 { 224 230 compatible = "nvidia,tegra114-pinmux"; 225 231 reg = <0x70000868 0x148 /* Pad control registers */ ··· 489 483 reg = <0x7000e400 0x400>; 490 484 clocks = <&tegra_car TEGRA114_CLK_PCLK>, <&clk32k_in>; 491 485 clock-names = "pclk", "clk32k_in"; 486 + }; 487 + 488 + fuse@7000f800 { 489 + compatible = "nvidia,tegra114-efuse"; 490 + reg = <0x7000f800 0x400>; 491 + clocks = <&tegra_car TEGRA114_CLK_FUSE>; 492 + clock-names = "fuse"; 493 + resets = <&tegra_car 39>; 494 + reset-names = "fuse"; 492 495 }; 493 496 494 497 iommu@70019010 {
+15
arch/arm/boot/dts/tegra124.dtsi
··· 179 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 188 pinmux: pinmux@0,70000868 { 183 189 compatible = "nvidia,tegra124-pinmux"; 184 190 reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */ ··· 453 447 reg = <0x0 0x7000e400 0x0 0x400>; 454 448 clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>; 455 449 clock-names = "pclk", "clk32k_in"; 450 + }; 451 + 452 + fuse@0,7000f800 { 453 + compatible = "nvidia,tegra124-efuse"; 454 + reg = <0x0 0x7000f800 0x0 0x400>; 455 + clocks = <&tegra_car TEGRA124_CLK_FUSE>; 456 + clock-names = "fuse"; 457 + resets = <&tegra_car 39>; 458 + reset-names = "fuse"; 456 459 }; 457 460 458 461 sdhci@0,700b0000 {
+15
arch/arm/boot/dts/tegra20.dtsi
··· 236 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 245 pinmux: pinmux@70000014 { 240 246 compatible = "nvidia,tegra20-pinmux"; 241 247 reg = <0x70000014 0x10 /* Tri-state registers */ ··· 549 543 reg = <0x7000f400 0x200>; 550 544 #address-cells = <1>; 551 545 #size-cells = <0>; 546 + }; 547 + 548 + fuse@7000f800 { 549 + compatible = "nvidia,tegra20-efuse"; 550 + reg = <0x7000F800 0x400>; 551 + clocks = <&tegra_car TEGRA20_CLK_FUSE>; 552 + clock-names = "fuse"; 553 + resets = <&tegra_car 39>; 554 + reset-names = "fuse"; 552 555 }; 553 556 554 557 pcie-controller@80003000 {
+15
arch/arm/boot/dts/tegra30.dtsi
··· 335 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 344 pinmux: pinmux@70000868 { 339 345 compatible = "nvidia,tegra30-pinmux"; 340 346 reg = <0x70000868 0xd4 /* Pad control registers */ ··· 635 629 nvidia,#asids = <4>; /* # of ASIDs */ 636 630 dma-window = <0 0x40000000>; /* IOVA start & length */ 637 631 nvidia,ahb = <&ahb>; 632 + }; 633 + 634 + fuse@7000f800 { 635 + compatible = "nvidia,tegra30-efuse"; 636 + reg = <0x7000f800 0x400>; 637 + clocks = <&tegra_car TEGRA30_CLK_FUSE>; 638 + clock-names = "fuse"; 639 + resets = <&tegra_car 39>; 640 + reset-names = "fuse"; 638 641 }; 639 642 640 643 ahub@70080000 {
-5
arch/arm/mach-tegra/Makefile
··· 2 2 3 3 obj-y += io.o 4 4 obj-y += irq.o 5 - obj-y += fuse.o 6 5 obj-y += pmc.o 7 6 obj-y += flowctrl.o 8 7 obj-y += powergate.o 9 - obj-y += apbio.o 10 8 obj-y += pm.o 11 9 obj-y += reset.o 12 10 obj-y += reset-handler.o 13 11 obj-y += sleep.o 14 12 obj-y += tegra.o 15 13 obj-$(CONFIG_CPU_IDLE) += cpuidle.o 16 - obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o 17 14 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o 18 15 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o 19 16 ifeq ($(CONFIG_CPU_IDLE),y) 20 17 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o 21 18 endif 22 - obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o 23 19 obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o 24 20 obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o 25 21 ifeq ($(CONFIG_CPU_IDLE),y) ··· 24 28 obj-$(CONFIG_SMP) += platsmp.o headsmp.o 25 29 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 26 30 27 - obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o 28 31 obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o 29 32 obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o 30 33 ifeq ($(CONFIG_CPU_IDLE),y)
-206
arch/arm/mach-tegra/apbio.c
··· 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) 30 - static DEFINE_MUTEX(tegra_apb_dma_lock); 31 - static u32 *tegra_apb_bb; 32 - static dma_addr_t tegra_apb_bb_phys; 33 - static DECLARE_COMPLETION(tegra_apb_wait); 34 - 35 - static u32 tegra_apb_readl_direct(unsigned long offset); 36 - static void tegra_apb_writel_direct(u32 value, unsigned long offset); 37 - 38 - static struct dma_chan *tegra_apb_dma_chan; 39 - static struct dma_slave_config dma_sconfig; 40 - 41 - static 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 - 75 - skip_init: 76 - mutex_unlock(&tegra_apb_dma_lock); 77 - return true; 78 - 79 - err_buff_alloc: 80 - dma_release_channel(tegra_apb_dma_chan); 81 - tegra_apb_dma_chan = NULL; 82 - 83 - err_dma_alloc: 84 - mutex_unlock(&tegra_apb_dma_lock); 85 - return false; 86 - } 87 - 88 - static void apb_dma_complete(void *args) 89 - { 90 - complete(&tegra_apb_wait); 91 - } 92 - 93 - static 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 - 131 - static 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 - 148 - static 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 - 169 - typedef u32 (*apbio_read_fptr)(unsigned long offset); 170 - typedef void (*apbio_write_fptr)(u32 value, unsigned long offset); 171 - 172 - static apbio_read_fptr apbio_read; 173 - static apbio_write_fptr apbio_write; 174 - 175 - static u32 tegra_apb_readl_direct(unsigned long offset) 176 - { 177 - return readl(IO_ADDRESS(offset)); 178 - } 179 - 180 - static void tegra_apb_writel_direct(u32 value, unsigned long offset) 181 - { 182 - writel(value, IO_ADDRESS(offset)); 183 - } 184 - 185 - void 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 - 198 - u32 tegra_apb_readl(unsigned long offset) 199 - { 200 - return apbio_read(offset); 201 - } 202 - 203 - void tegra_apb_writel(u32 value, unsigned long offset) 204 - { 205 - apbio_write(value, offset); 206 - }
-22
arch/arm/mach-tegra/apbio.h
··· 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 - 19 - void tegra_apb_io_init(void); 20 - u32 tegra_apb_readl(unsigned long offset); 21 - void tegra_apb_writel(u32 value, unsigned long offset); 22 - #endif
+2 -1
arch/arm/mach-tegra/board-paz00.c
··· 17 17 * 18 18 */ 19 19 20 - #include <linux/platform_device.h> 21 20 #include <linux/gpio/driver.h> 21 + #include <linux/platform_device.h> 22 22 #include <linux/rfkill-gpio.h> 23 + 23 24 #include "board.h" 24 25 25 26 static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = {
+5 -5
arch/arm/mach-tegra/cpuidle-tegra114.c
··· 14 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/module.h> 17 + #include <asm/firmware.h> 18 + #include <linux/clockchips.h> 19 19 #include <linux/cpuidle.h> 20 20 #include <linux/cpu_pm.h> 21 - #include <linux/clockchips.h> 22 - #include <asm/firmware.h> 21 + #include <linux/kernel.h> 22 + #include <linux/module.h> 23 23 24 24 #include <asm/cpuidle.h> 25 - #include <asm/suspend.h> 26 25 #include <asm/smp_plat.h> 26 + #include <asm/suspend.h> 27 27 28 28 #include "pm.h" 29 29 #include "sleep.h"
+8 -8
arch/arm/mach-tegra/cpuidle-tegra20.c
··· 19 19 * more details. 20 20 */ 21 21 22 - #include <linux/kernel.h> 23 - #include <linux/module.h> 22 + #include <linux/clk/tegra.h> 23 + #include <linux/clockchips.h> 24 24 #include <linux/cpuidle.h> 25 25 #include <linux/cpu_pm.h> 26 - #include <linux/clockchips.h> 27 - #include <linux/clk/tegra.h> 26 + #include <linux/kernel.h> 27 + #include <linux/module.h> 28 28 29 29 #include <asm/cpuidle.h> 30 30 #include <asm/proc-fns.h> 31 - #include <asm/suspend.h> 32 31 #include <asm/smp_plat.h> 32 + #include <asm/suspend.h> 33 33 34 - #include "pm.h" 35 - #include "sleep.h" 34 + #include "flowctrl.h" 36 35 #include "iomap.h" 37 36 #include "irq.h" 38 - #include "flowctrl.h" 37 + #include "pm.h" 38 + #include "sleep.h" 39 39 40 40 #ifdef CONFIG_PM_SLEEP 41 41 static bool abort_flag;
+5 -5
arch/arm/mach-tegra/cpuidle-tegra30.c
··· 19 19 * more details. 20 20 */ 21 21 22 - #include <linux/kernel.h> 23 - #include <linux/module.h> 22 + #include <linux/clk/tegra.h> 23 + #include <linux/clockchips.h> 24 24 #include <linux/cpuidle.h> 25 25 #include <linux/cpu_pm.h> 26 - #include <linux/clockchips.h> 27 - #include <linux/clk/tegra.h> 26 + #include <linux/kernel.h> 27 + #include <linux/module.h> 28 28 29 29 #include <asm/cpuidle.h> 30 30 #include <asm/proc-fns.h> 31 - #include <asm/suspend.h> 32 31 #include <asm/smp_plat.h> 32 + #include <asm/suspend.h> 33 33 34 34 #include "pm.h" 35 35 #include "sleep.h"
+4 -3
arch/arm/mach-tegra/cpuidle.c
··· 24 24 #include <linux/kernel.h> 25 25 #include <linux/module.h> 26 26 27 - #include "fuse.h" 27 + #include <soc/tegra/fuse.h> 28 + 28 29 #include "cpuidle.h" 29 30 30 31 void __init tegra_cpuidle_init(void) 31 32 { 32 - switch (tegra_chip_id) { 33 + switch (tegra_get_chip_id()) { 33 34 case TEGRA20: 34 35 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 35 36 tegra20_cpuidle_init(); ··· 50 49 51 50 void tegra_cpuidle_pcie_irqs_in_use(void) 52 51 { 53 - switch (tegra_chip_id) { 52 + switch (tegra_get_chip_id()) { 54 53 case TEGRA20: 55 54 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 56 55 tegra20_cpuidle_pcie_irqs_in_use();
+7 -6
arch/arm/mach-tegra/flowctrl.c
··· 18 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 19 */ 20 20 21 - #include <linux/init.h> 22 - #include <linux/kernel.h> 23 - #include <linux/io.h> 24 21 #include <linux/cpumask.h> 22 + #include <linux/init.h> 23 + #include <linux/io.h> 24 + #include <linux/kernel.h> 25 + 26 + #include <soc/tegra/fuse.h> 25 27 26 28 #include "flowctrl.h" 27 29 #include "iomap.h" 28 - #include "fuse.h" 29 30 30 31 static u8 flowctrl_offset_halt_cpu[] = { 31 32 FLOW_CTRL_HALT_CPU0_EVENTS, ··· 77 76 int i; 78 77 79 78 reg = flowctrl_read_cpu_csr(cpuid); 80 - switch (tegra_chip_id) { 79 + switch (tegra_get_chip_id()) { 81 80 case TEGRA20: 82 81 /* clear wfe bitmap */ 83 82 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP; ··· 118 117 119 118 /* Disable powergating via flow controller for CPU0 */ 120 119 reg = flowctrl_read_cpu_csr(cpuid); 121 - switch (tegra_chip_id) { 120 + switch (tegra_get_chip_id()) { 122 121 case TEGRA20: 123 122 /* clear wfe bitmap */ 124 123 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
-252
arch/arm/mach-tegra/fuse.c
··· 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 - 50 - int tegra_sku_id; 51 - int tegra_cpu_process_id; 52 - int tegra_core_process_id; 53 - int tegra_chip_id; 54 - int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */ 55 - int tegra_soc_speedo_id; 56 - enum tegra_revision tegra_revision; 57 - 58 - static struct clk *fuse_clk; 59 - static int tegra_fuse_spare_bit; 60 - static 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 - */ 65 - int 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 - 73 - static 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 - 82 - static 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 - 91 - static void tegra_fuse_disable_clk(void) 92 - { 93 - if (IS_ERR(fuse_clk)) 94 - return; 95 - clk_disable_unprepare(fuse_clk); 96 - } 97 - 98 - u32 tegra_fuse_readl(unsigned long offset) 99 - { 100 - return tegra_apb_readl(TEGRA_FUSE_BASE + offset); 101 - } 102 - 103 - bool 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 - 116 - static 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 - 138 - static 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 - 152 - u32 tegra_read_chipid(void) 153 - { 154 - return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804); 155 - } 156 - 157 - static 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 */ 168 - static 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 - 183 - void __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 - }
-79
arch/arm/mach-tegra/fuse.h
··· 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__ 35 - enum 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 - 45 - extern int tegra_sku_id; 46 - extern int tegra_cpu_process_id; 47 - extern int tegra_core_process_id; 48 - extern int tegra_chip_id; 49 - extern int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */ 50 - extern int tegra_soc_speedo_id; 51 - extern enum tegra_revision tegra_revision; 52 - 53 - extern int tegra_bct_strapping; 54 - 55 - unsigned long long tegra_chip_uid(void); 56 - void tegra_init_fuse(void); 57 - bool tegra_spare_fuse(int bit); 58 - u32 tegra_fuse_readl(unsigned long offset); 59 - 60 - #ifdef CONFIG_ARCH_TEGRA_2x_SOC 61 - void tegra20_init_speedo_data(void); 62 - #else 63 - static inline void tegra20_init_speedo_data(void) {} 64 - #endif 65 - 66 - #ifdef CONFIG_ARCH_TEGRA_3x_SOC 67 - void tegra30_init_speedo_data(void); 68 - #else 69 - static inline void tegra30_init_speedo_data(void) {} 70 - #endif 71 - 72 - #ifdef CONFIG_ARCH_TEGRA_114_SOC 73 - void tegra114_init_speedo_data(void); 74 - #else 75 - static inline void tegra114_init_speedo_data(void) {} 76 - #endif 77 - #endif /* __ASSEMBLY__ */ 78 - 79 - #endif
+8 -6
arch/arm/mach-tegra/hotplug.c
··· 7 7 * it under the terms of the GNU General Public License version 2 as 8 8 * published by the Free Software Foundation. 9 9 */ 10 + 11 + #include <linux/clk/tegra.h> 10 12 #include <linux/kernel.h> 11 13 #include <linux/smp.h> 12 - #include <linux/clk/tegra.h> 14 + 15 + #include <soc/tegra/fuse.h> 13 16 14 17 #include <asm/smp_plat.h> 15 18 16 - #include "fuse.h" 17 19 #include "sleep.h" 18 20 19 21 static void (*tegra_hotplug_shutdown)(void); ··· 53 51 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) 54 52 return; 55 53 56 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) 54 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20) 57 55 tegra_hotplug_shutdown = tegra20_hotplug_shutdown; 58 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 56 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30) 59 57 tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 60 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) 58 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114) 61 59 tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 62 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124) 60 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124) 63 61 tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 64 62 }
+4 -4
arch/arm/mach-tegra/io.c
··· 18 18 * 19 19 */ 20 20 21 - #include <linux/kernel.h> 22 - #include <linux/module.h> 23 21 #include <linux/init.h> 24 - #include <linux/mm.h> 25 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 27 #include <asm/mach/map.h> 28 + #include <asm/page.h> 29 29 30 30 #include "board.h" 31 31 #include "iomap.h"
+4 -4
arch/arm/mach-tegra/irq.c
··· 17 17 * 18 18 */ 19 19 20 - #include <linux/kernel.h> 21 20 #include <linux/cpu_pm.h> 22 21 #include <linux/interrupt.h> 23 - #include <linux/irq.h> 24 22 #include <linux/io.h> 25 - #include <linux/of.h> 26 - #include <linux/of_address.h> 27 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 28 #include <linux/syscore_ops.h> 29 29 30 30 #include "board.h"
+15 -14
arch/arm/mach-tegra/platsmp.c
··· 11 11 * it under the terms of the GNU General Public License version 2 as 12 12 * published by the Free Software Foundation. 13 13 */ 14 - #include <linux/init.h> 15 - #include <linux/errno.h> 14 + 15 + #include <linux/clk/tegra.h> 16 16 #include <linux/delay.h> 17 17 #include <linux/device.h> 18 + #include <linux/errno.h> 19 + #include <linux/init.h> 20 + #include <linux/io.h> 18 21 #include <linux/jiffies.h> 19 22 #include <linux/smp.h> 20 - #include <linux/io.h> 21 - #include <linux/clk/tegra.h> 23 + 24 + #include <soc/tegra/fuse.h> 22 25 23 26 #include <asm/cacheflush.h> 24 27 #include <asm/mach-types.h> 25 - #include <asm/smp_scu.h> 26 28 #include <asm/smp_plat.h> 27 - 28 - #include "fuse.h" 29 - #include "flowctrl.h" 30 - #include "reset.h" 31 - #include "pmc.h" 29 + #include <asm/smp_scu.h> 32 30 33 31 #include "common.h" 32 + #include "flowctrl.h" 34 33 #include "iomap.h" 34 + #include "pmc.h" 35 + #include "reset.h" 35 36 36 37 static cpumask_t tegra_cpu_init_mask; 37 38 ··· 171 170 static int tegra_boot_secondary(unsigned int cpu, 172 171 struct task_struct *idle) 173 172 { 174 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) 173 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20) 175 174 return tegra20_boot_secondary(cpu, idle); 176 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 175 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30) 177 176 return tegra30_boot_secondary(cpu, idle); 178 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) 177 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114) 179 178 return tegra114_boot_secondary(cpu, idle); 180 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124) 179 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124) 181 180 return tegra114_boot_secondary(cpu, idle); 182 181 183 182 return -EINVAL;
+1
arch/arm/mach-tegra/pm-tegra20.c
··· 13 13 * You should have received a copy of the GNU General Public License 14 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 15 */ 16 + 16 17 #include <linux/kernel.h> 17 18 18 19 #include "pm.h"
+1
arch/arm/mach-tegra/pm-tegra30.c
··· 13 13 * You should have received a copy of the GNU General Public License 14 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 15 */ 16 + 16 17 #include <linux/kernel.h> 17 18 18 19 #include "pm.h"
+20 -19
arch/arm/mach-tegra/pm.c
··· 16 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 17 */ 18 18 19 - #include <linux/kernel.h> 20 - #include <linux/spinlock.h> 21 - #include <linux/io.h> 22 - #include <linux/cpumask.h> 23 - #include <linux/delay.h> 24 - #include <linux/cpu_pm.h> 25 - #include <linux/suspend.h> 26 - #include <linux/err.h> 27 - #include <linux/slab.h> 28 19 #include <linux/clk/tegra.h> 20 + #include <linux/cpumask.h> 21 + #include <linux/cpu_pm.h> 22 + #include <linux/delay.h> 23 + #include <linux/err.h> 24 + #include <linux/io.h> 25 + #include <linux/kernel.h> 26 + #include <linux/slab.h> 27 + #include <linux/spinlock.h> 28 + #include <linux/suspend.h> 29 29 30 - #include <asm/smp_plat.h> 30 + #include <soc/tegra/fuse.h> 31 + 31 32 #include <asm/cacheflush.h> 32 - #include <asm/suspend.h> 33 33 #include <asm/idmap.h> 34 34 #include <asm/proc-fns.h> 35 + #include <asm/smp_plat.h> 36 + #include <asm/suspend.h> 35 37 #include <asm/tlbflush.h> 36 38 37 - #include "iomap.h" 38 - #include "reset.h" 39 39 #include "flowctrl.h" 40 - #include "fuse.h" 41 - #include "pm.h" 40 + #include "iomap.h" 42 41 #include "pmc.h" 42 + #include "pm.h" 43 + #include "reset.h" 43 44 #include "sleep.h" 44 45 45 46 #ifdef CONFIG_PM_SLEEP ··· 54 53 55 54 static void tegra_tear_down_cpu_init(void) 56 55 { 57 - switch (tegra_chip_id) { 56 + switch (tegra_get_chip_id()) { 58 57 case TEGRA20: 59 58 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 60 59 tegra_tear_down_cpu = tegra20_tear_down_cpu; ··· 144 143 145 144 if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask)) 146 145 last_cpu = true; 147 - else if (tegra_chip_id == TEGRA20 && phy_cpu_id == 1) 146 + else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1) 148 147 tegra20_cpu_set_resettable_soon(); 149 148 150 149 spin_unlock(&tegra_lp2_lock); ··· 213 212 */ 214 213 static bool tegra_lp1_iram_hook(void) 215 214 { 216 - switch (tegra_chip_id) { 215 + switch (tegra_get_chip_id()) { 217 216 case TEGRA20: 218 217 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 219 218 tegra20_lp1_iram_hook(); ··· 243 242 244 243 static bool tegra_sleep_core_init(void) 245 244 { 246 - switch (tegra_chip_id) { 245 + switch (tegra_get_chip_id()) { 247 246 case TEGRA20: 248 247 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 249 248 tegra20_sleep_core_init();
+5 -4
arch/arm/mach-tegra/pmc.c
··· 15 15 * 16 16 */ 17 17 18 - #include <linux/kernel.h> 19 18 #include <linux/clk.h> 20 19 #include <linux/io.h> 20 + #include <linux/kernel.h> 21 21 #include <linux/of.h> 22 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 27 #include "flowctrl.h" 26 - #include "fuse.h" 27 28 #include "pm.h" 28 29 #include "pmc.h" 29 30 #include "sleep.h" ··· 252 251 reg |= TEGRA_POWER_CPU_PWRREQ_OE; 253 252 reg &= ~TEGRA_POWER_EFFECT_LP0; 254 253 255 - switch (tegra_chip_id) { 254 + switch (tegra_get_chip_id()) { 256 255 case TEGRA20: 257 256 case TEGRA30: 258 257 break;
+8 -7
arch/arm/mach-tegra/powergate.c
··· 17 17 * 18 18 */ 19 19 20 - #include <linux/kernel.h> 21 20 #include <linux/clk.h> 21 + #include <linux/clk/tegra.h> 22 22 #include <linux/debugfs.h> 23 23 #include <linux/delay.h> 24 24 #include <linux/err.h> 25 25 #include <linux/export.h> 26 26 #include <linux/init.h> 27 27 #include <linux/io.h> 28 + #include <linux/kernel.h> 28 29 #include <linux/reset.h> 29 30 #include <linux/seq_file.h> 30 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 36 #include "iomap.h" 36 37 37 38 #define DPD_SAMPLE 0x020 ··· 158 157 * The Tegra124 GPU has a separate register (with different semantics) 159 158 * to remove clamps. 160 159 */ 161 - if (tegra_chip_id == TEGRA124) { 160 + if (tegra_get_chip_id() == TEGRA124) { 162 161 if (id == TEGRA_POWERGATE_3D) { 163 162 pmc_write(0, GPU_RG_CNTRL); 164 163 return 0; ··· 228 227 229 228 int __init tegra_powergate_init(void) 230 229 { 231 - switch (tegra_chip_id) { 230 + switch (tegra_get_chip_id()) { 232 231 case TEGRA20: 233 232 tegra_num_powerdomains = 7; 234 233 break; ··· 369 368 { 370 369 struct dentry *d; 371 370 372 - switch (tegra_chip_id) { 371 + switch (tegra_get_chip_id()) { 373 372 case TEGRA20: 374 373 powergate_name = powergate_name_t20; 375 374 break;
+4 -3
arch/arm/mach-tegra/reset-handler.S
··· 14 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 15 */ 16 16 17 - #include <linux/linkage.h> 18 17 #include <linux/init.h> 18 + #include <linux/linkage.h> 19 19 20 - #include <asm/cache.h> 20 + #include <soc/tegra/fuse.h> 21 + 21 22 #include <asm/asm-offsets.h> 23 + #include <asm/cache.h> 22 24 23 25 #include "flowctrl.h" 24 - #include "fuse.h" 25 26 #include "iomap.h" 26 27 #include "reset.h" 27 28 #include "sleep.h"
+6 -5
arch/arm/mach-tegra/reset.c
··· 14 14 * 15 15 */ 16 16 17 + #include <linux/bitops.h> 18 + #include <linux/cpumask.h> 17 19 #include <linux/init.h> 18 20 #include <linux/io.h> 19 - #include <linux/cpumask.h> 20 - #include <linux/bitops.h> 21 + 22 + #include <soc/tegra/fuse.h> 21 23 22 24 #include <asm/cacheflush.h> 23 - #include <asm/hardware/cache-l2x0.h> 24 25 #include <asm/firmware.h> 26 + #include <asm/hardware/cache-l2x0.h> 25 27 26 28 #include "iomap.h" 27 29 #include "irammap.h" 28 30 #include "reset.h" 29 31 #include "sleep.h" 30 - #include "fuse.h" 31 32 32 33 #define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \ 33 34 TEGRA_IRAM_RESET_HANDLER_OFFSET) ··· 54 53 * Prevent further modifications to the physical reset vector. 55 54 * NOTE: Has no effect on chips prior to Tegra30. 56 55 */ 57 - if (tegra_chip_id != TEGRA20) { 56 + if (tegra_get_chip_id() != TEGRA20) { 58 57 reg = readl(sb_ctrl); 59 58 reg |= 2; 60 59 writel(reg, sb_ctrl);
+5 -4
arch/arm/mach-tegra/sleep-tegra30.S
··· 16 16 17 17 #include <linux/linkage.h> 18 18 19 - #include <asm/assembler.h> 19 + #include <soc/tegra/fuse.h> 20 + 20 21 #include <asm/asm-offsets.h> 22 + #include <asm/assembler.h> 21 23 #include <asm/cache.h> 22 24 23 - #include "irammap.h" 24 - #include "fuse.h" 25 - #include "sleep.h" 26 25 #include "flowctrl.h" 26 + #include "irammap.h" 27 + #include "sleep.h" 27 28 28 29 #define EMC_CFG 0xc 29 30 #define EMC_ADR_CFG 0x10
+14 -14
arch/arm/mach-tegra/tegra.c
··· 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 19 #include <linux/clk.h> 20 + #include <linux/clk/tegra.h> 24 21 #include <linux/dma-mapping.h> 22 + #include <linux/init.h> 23 + #include <linux/io.h> 24 + #include <linux/irqchip.h> 25 25 #include <linux/irqdomain.h> 26 - #include <linux/of.h> 26 + #include <linux/kernel.h> 27 27 #include <linux/of_address.h> 28 28 #include <linux/of_fdt.h> 29 + #include <linux/of.h> 29 30 #include <linux/of_platform.h> 30 31 #include <linux/pda_power.h> 31 - #include <linux/io.h> 32 + #include <linux/platform_device.h> 33 + #include <linux/serial_8250.h> 32 34 #include <linux/slab.h> 33 35 #include <linux/sys_soc.h> 34 36 #include <linux/usb/tegra_usb_phy.h> 35 - #include <linux/clk/tegra.h> 36 - #include <linux/irqchip.h> 37 + 38 + #include <soc/tegra/fuse.h> 37 39 38 40 #include <asm/hardware/cache-l2x0.h> 39 - #include <asm/mach-types.h> 40 41 #include <asm/mach/arch.h> 41 42 #include <asm/mach/time.h> 43 + #include <asm/mach-types.h> 42 44 #include <asm/setup.h> 43 45 #include <asm/trusted_foundations.h> 44 46 45 - #include "apbio.h" 46 47 #include "board.h" 47 48 #include "common.h" 48 49 #include "cpuidle.h" 49 - #include "fuse.h" 50 50 #include "iomap.h" 51 51 #include "irq.h" 52 52 #include "pmc.h" ··· 73 73 static void __init tegra_init_early(void) 74 74 { 75 75 of_register_trusted_foundations(); 76 - tegra_apb_io_init(); 77 76 tegra_init_fuse(); 78 77 tegra_cpu_reset_handler_init(); 79 78 tegra_powergate_init(); ··· 102 103 goto out; 103 104 104 105 soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra"); 105 - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_revision); 106 - soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", tegra_chip_id); 106 + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", 107 + tegra_sku_info.revision); 108 + soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id()); 107 109 108 110 soc_dev = soc_device_register(soc_dev_attr); 109 111 if (IS_ERR(soc_dev)) {
+31 -25
arch/arm/mach-tegra/tegra114_speedo.c drivers/soc/tegra/fuse/speedo-tegra114.c
··· 1 1 /* 2 - * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. 2 + * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify it 5 5 * under the terms and conditions of the GNU General Public License, ··· 14 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 15 */ 16 16 17 - #include <linux/kernel.h> 18 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 23 #include "fuse.h" 21 24 22 - #define CORE_PROCESS_CORNERS_NUM 2 23 - #define CPU_PROCESS_CORNERS_NUM 2 25 + #define CORE_PROCESS_CORNERS 2 26 + #define CPU_PROCESS_CORNERS 2 24 27 25 28 enum { 26 29 THRESHOLD_INDEX_0, ··· 31 28 THRESHOLD_INDEX_COUNT, 32 29 }; 33 30 34 - static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = { 31 + static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = { 35 32 {1123, UINT_MAX}, 36 33 {0, UINT_MAX}, 37 34 }; 38 35 39 - static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = { 36 + static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = { 40 37 {1695, UINT_MAX}, 41 38 {0, UINT_MAX}, 42 39 }; 43 40 44 - static void rev_sku_to_speedo_ids(int rev, int sku, int *threshold) 41 + static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info, 42 + int *threshold) 45 43 { 46 44 u32 tmp; 45 + u32 sku = sku_info->sku_id; 46 + enum tegra_revision rev = sku_info->revision; 47 47 48 48 switch (sku) { 49 49 case 0x00: 50 50 case 0x10: 51 51 case 0x05: 52 52 case 0x06: 53 - tegra_cpu_speedo_id = 1; 54 - tegra_soc_speedo_id = 0; 53 + sku_info->cpu_speedo_id = 1; 54 + sku_info->soc_speedo_id = 0; 55 55 *threshold = THRESHOLD_INDEX_0; 56 56 break; 57 57 58 58 case 0x03: 59 59 case 0x04: 60 - tegra_cpu_speedo_id = 2; 61 - tegra_soc_speedo_id = 1; 60 + sku_info->cpu_speedo_id = 2; 61 + sku_info->soc_speedo_id = 1; 62 62 *threshold = THRESHOLD_INDEX_1; 63 63 break; 64 64 65 65 default: 66 - pr_err("Tegra114 Unknown SKU %d\n", sku); 67 - tegra_cpu_speedo_id = 0; 68 - tegra_soc_speedo_id = 0; 66 + pr_err("Tegra Unknown SKU %d\n", sku); 67 + sku_info->cpu_speedo_id = 0; 68 + sku_info->soc_speedo_id = 0; 69 69 *threshold = THRESHOLD_INDEX_0; 70 70 break; 71 71 } 72 72 73 73 if (rev == TEGRA_REVISION_A01) { 74 - tmp = tegra_fuse_readl(0x270) << 1; 75 - tmp |= tegra_fuse_readl(0x26c); 74 + tmp = tegra30_fuse_readl(0x270) << 1; 75 + tmp |= tegra30_fuse_readl(0x26c); 76 76 if (!tmp) 77 - tegra_cpu_speedo_id = 0; 77 + sku_info->cpu_speedo_id = 0; 78 78 } 79 79 } 80 80 81 - void tegra114_init_speedo_data(void) 81 + void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info) 82 82 { 83 83 u32 cpu_speedo_val; 84 84 u32 core_speedo_val; ··· 93 87 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != 94 88 THRESHOLD_INDEX_COUNT); 95 89 96 - rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id, &threshold); 90 + rev_sku_to_speedo_ids(sku_info, &threshold); 97 91 98 - cpu_speedo_val = tegra_fuse_readl(0x12c) + 1024; 99 - core_speedo_val = tegra_fuse_readl(0x134); 92 + cpu_speedo_val = tegra30_fuse_readl(0x12c) + 1024; 93 + core_speedo_val = tegra30_fuse_readl(0x134); 100 94 101 - for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) 95 + for (i = 0; i < CPU_PROCESS_CORNERS; i++) 102 96 if (cpu_speedo_val < cpu_process_speedos[threshold][i]) 103 97 break; 104 - tegra_cpu_process_id = i; 98 + sku_info->cpu_process_id = i; 105 99 106 - for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) 100 + for (i = 0; i < CORE_PROCESS_CORNERS; i++) 107 101 if (core_speedo_val < core_process_speedos[threshold][i]) 108 102 break; 109 - tegra_core_process_id = i; 103 + sku_info->core_process_id = i; 110 104 }
+23 -22
arch/arm/mach-tegra/tegra20_speedo.c drivers/soc/tegra/fuse/speedo-tegra20.c
··· 1 1 /* 2 - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 2 + * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved. 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify it 5 5 * under the terms and conditions of the GNU General Public License, ··· 14 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 15 */ 16 16 17 - #include <linux/kernel.h> 18 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 23 #include "fuse.h" 21 24 ··· 50 47 SPEEDO_ID_COUNT, 51 48 }; 52 49 53 - static const u32 cpu_process_speedos[][PROCESS_CORNERS_NUM] = { 50 + static const u32 __initconst cpu_process_speedos[][PROCESS_CORNERS_NUM] = { 54 51 {315, 366, 420, UINT_MAX}, 55 52 {303, 368, 419, UINT_MAX}, 56 53 {316, 331, 383, UINT_MAX}, 57 54 }; 58 55 59 - static const u32 core_process_speedos[][PROCESS_CORNERS_NUM] = { 56 + static const u32 __initconst core_process_speedos[][PROCESS_CORNERS_NUM] = { 60 57 {165, 195, 224, UINT_MAX}, 61 58 {165, 195, 224, UINT_MAX}, 62 59 {165, 195, 224, UINT_MAX}, 63 60 }; 64 61 65 - void tegra20_init_speedo_data(void) 62 + void __init tegra20_init_speedo_data(struct tegra_sku_info *sku_info) 66 63 { 67 64 u32 reg; 68 65 u32 val; ··· 71 68 BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT); 72 69 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT); 73 70 74 - if (SPEEDO_ID_SELECT_0(tegra_revision)) 75 - tegra_soc_speedo_id = SPEEDO_ID_0; 76 - else if (SPEEDO_ID_SELECT_1(tegra_sku_id)) 77 - tegra_soc_speedo_id = SPEEDO_ID_1; 71 + if (SPEEDO_ID_SELECT_0(sku_info->revision)) 72 + sku_info->soc_speedo_id = SPEEDO_ID_0; 73 + else if (SPEEDO_ID_SELECT_1(sku_info->sku_id)) 74 + sku_info->soc_speedo_id = SPEEDO_ID_1; 78 75 else 79 - tegra_soc_speedo_id = SPEEDO_ID_2; 76 + sku_info->soc_speedo_id = SPEEDO_ID_2; 80 77 81 78 val = 0; 82 79 for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) { 83 - reg = tegra_spare_fuse(i) | 84 - tegra_spare_fuse(i + CPU_SPEEDO_REDUND_OFFS); 80 + reg = tegra20_spare_fuse_early(i) | 81 + tegra20_spare_fuse_early(i + CPU_SPEEDO_REDUND_OFFS); 85 82 val = (val << 1) | (reg & 0x1); 86 83 } 87 84 val = val * SPEEDO_MULT; 88 - pr_debug("%s CPU speedo value %u\n", __func__, val); 85 + pr_debug("Tegra CPU speedo value %u\n", val); 89 86 90 87 for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) { 91 - if (val <= cpu_process_speedos[tegra_soc_speedo_id][i]) 88 + if (val <= cpu_process_speedos[sku_info->soc_speedo_id][i]) 92 89 break; 93 90 } 94 - tegra_cpu_process_id = i; 91 + sku_info->cpu_process_id = i; 95 92 96 93 val = 0; 97 94 for (i = CORE_SPEEDO_MSBIT; i >= CORE_SPEEDO_LSBIT; i--) { 98 - reg = tegra_spare_fuse(i) | 99 - tegra_spare_fuse(i + CORE_SPEEDO_REDUND_OFFS); 95 + reg = tegra20_spare_fuse_early(i) | 96 + tegra20_spare_fuse_early(i + CORE_SPEEDO_REDUND_OFFS); 100 97 val = (val << 1) | (reg & 0x1); 101 98 } 102 99 val = val * SPEEDO_MULT; 103 - pr_debug("%s Core speedo value %u\n", __func__, val); 100 + pr_debug("Core speedo value %u\n", val); 104 101 105 102 for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) { 106 - if (val <= core_process_speedos[tegra_soc_speedo_id][i]) 103 + if (val <= core_process_speedos[sku_info->soc_speedo_id][i]) 107 104 break; 108 105 } 109 - tegra_core_process_id = i; 110 - 111 - pr_info("Tegra20 Soc Speedo ID %d", tegra_soc_speedo_id); 106 + sku_info->core_process_id = i; 112 107 }
+86 -90
arch/arm/mach-tegra/tegra30_speedo.c drivers/soc/tegra/fuse/speedo-tegra30.c
··· 1 1 /* 2 - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 2 + * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved. 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify it 5 5 * under the terms and conditions of the GNU General Public License, ··· 14 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 15 */ 16 16 17 - #include <linux/kernel.h> 18 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 23 #include "fuse.h" 21 24 22 - #define CORE_PROCESS_CORNERS_NUM 1 23 - #define CPU_PROCESS_CORNERS_NUM 6 25 + #define CORE_PROCESS_CORNERS 1 26 + #define CPU_PROCESS_CORNERS 6 24 27 25 - #define FUSE_SPEEDO_CALIB_0 0x114 26 - #define FUSE_PACKAGE_INFO 0X1FC 27 - #define FUSE_TEST_PROG_VER 0X128 28 + #define FUSE_SPEEDO_CALIB_0 0x14 29 + #define FUSE_PACKAGE_INFO 0XFC 30 + #define FUSE_TEST_PROG_VER 0X28 28 31 29 32 #define G_SPEEDO_BIT_MINUS1 58 30 33 #define G_SPEEDO_BIT_MINUS1_R 59 ··· 54 51 THRESHOLD_INDEX_COUNT, 55 52 }; 56 53 57 - static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = { 54 + static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = { 58 55 {180}, 59 56 {170}, 60 57 {195}, ··· 69 66 {180}, 70 67 }; 71 68 72 - static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = { 69 + static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = { 73 70 {306, 338, 360, 376, UINT_MAX}, 74 71 {295, 336, 358, 375, UINT_MAX}, 75 72 {325, 325, 358, 375, UINT_MAX}, ··· 84 81 {295, 336, 358, 375, 391, UINT_MAX}, 85 82 }; 86 83 87 - static int threshold_index; 88 - static int package_id; 84 + static int threshold_index __initdata; 89 85 90 - static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp) 86 + static void __init fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp) 91 87 { 92 88 u32 reg; 93 89 int ate_ver; 94 90 int bit_minus1; 95 91 int bit_minus2; 96 92 97 - reg = tegra_fuse_readl(FUSE_SPEEDO_CALIB_0); 93 + reg = tegra30_fuse_readl(FUSE_SPEEDO_CALIB_0); 98 94 99 95 *speedo_lp = (reg & 0xFFFF) * 4; 100 96 *speedo_g = ((reg >> 16) & 0xFFFF) * 4; 101 97 102 - ate_ver = tegra_fuse_readl(FUSE_TEST_PROG_VER); 103 - pr_info("%s: ATE prog ver %d.%d\n", __func__, ate_ver/10, ate_ver%10); 98 + ate_ver = tegra30_fuse_readl(FUSE_TEST_PROG_VER); 99 + pr_debug("Tegra ATE prog ver %d.%d\n", ate_ver/10, ate_ver%10); 104 100 105 101 if (ate_ver >= 26) { 106 - bit_minus1 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1); 107 - bit_minus1 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1_R); 108 - bit_minus2 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2); 109 - bit_minus2 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2_R); 102 + bit_minus1 = tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS1); 103 + bit_minus1 |= tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS1_R); 104 + bit_minus2 = tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS2); 105 + bit_minus2 |= tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS2_R); 110 106 *speedo_lp |= (bit_minus1 << 1) | bit_minus2; 111 107 112 - bit_minus1 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS1); 113 - bit_minus1 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS1_R); 114 - bit_minus2 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS2); 115 - bit_minus2 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS2_R); 108 + bit_minus1 = tegra30_spare_fuse(G_SPEEDO_BIT_MINUS1); 109 + bit_minus1 |= tegra30_spare_fuse(G_SPEEDO_BIT_MINUS1_R); 110 + bit_minus2 = tegra30_spare_fuse(G_SPEEDO_BIT_MINUS2); 111 + bit_minus2 |= tegra30_spare_fuse(G_SPEEDO_BIT_MINUS2_R); 116 112 *speedo_g |= (bit_minus1 << 1) | bit_minus2; 117 113 } else { 118 114 *speedo_lp |= 0x3; ··· 119 117 } 120 118 } 121 119 122 - static void rev_sku_to_speedo_ids(int rev, int sku) 120 + static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info) 123 121 { 124 - switch (rev) { 122 + int package_id = tegra30_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F; 123 + 124 + switch (sku_info->revision) { 125 125 case TEGRA_REVISION_A01: 126 - tegra_cpu_speedo_id = 0; 127 - tegra_soc_speedo_id = 0; 126 + sku_info->cpu_speedo_id = 0; 127 + sku_info->soc_speedo_id = 0; 128 128 threshold_index = THRESHOLD_INDEX_0; 129 129 break; 130 130 case TEGRA_REVISION_A02: 131 131 case TEGRA_REVISION_A03: 132 - switch (sku) { 132 + switch (sku_info->sku_id) { 133 133 case 0x87: 134 134 case 0x82: 135 - tegra_cpu_speedo_id = 1; 136 - tegra_soc_speedo_id = 1; 135 + sku_info->cpu_speedo_id = 1; 136 + sku_info->soc_speedo_id = 1; 137 137 threshold_index = THRESHOLD_INDEX_1; 138 138 break; 139 139 case 0x81: 140 140 switch (package_id) { 141 141 case 1: 142 - tegra_cpu_speedo_id = 2; 143 - tegra_soc_speedo_id = 2; 142 + sku_info->cpu_speedo_id = 2; 143 + sku_info->soc_speedo_id = 2; 144 144 threshold_index = THRESHOLD_INDEX_2; 145 145 break; 146 146 case 2: 147 - tegra_cpu_speedo_id = 4; 148 - tegra_soc_speedo_id = 1; 147 + sku_info->cpu_speedo_id = 4; 148 + sku_info->soc_speedo_id = 1; 149 149 threshold_index = THRESHOLD_INDEX_7; 150 150 break; 151 151 default: 152 - pr_err("Tegra30: Unknown pkg %d\n", package_id); 153 - BUG(); 152 + pr_err("Tegra Unknown pkg %d\n", package_id); 154 153 break; 155 154 } 156 155 break; 157 156 case 0x80: 158 157 switch (package_id) { 159 158 case 1: 160 - tegra_cpu_speedo_id = 5; 161 - tegra_soc_speedo_id = 2; 159 + sku_info->cpu_speedo_id = 5; 160 + sku_info->soc_speedo_id = 2; 162 161 threshold_index = THRESHOLD_INDEX_8; 163 162 break; 164 163 case 2: 165 - tegra_cpu_speedo_id = 6; 166 - tegra_soc_speedo_id = 2; 164 + sku_info->cpu_speedo_id = 6; 165 + sku_info->soc_speedo_id = 2; 167 166 threshold_index = THRESHOLD_INDEX_9; 168 167 break; 169 168 default: 170 - pr_err("Tegra30: Unknown pkg %d\n", package_id); 171 - BUG(); 169 + pr_err("Tegra Unknown pkg %d\n", package_id); 172 170 break; 173 171 } 174 172 break; 175 173 case 0x83: 176 174 switch (package_id) { 177 175 case 1: 178 - tegra_cpu_speedo_id = 7; 179 - tegra_soc_speedo_id = 1; 176 + sku_info->cpu_speedo_id = 7; 177 + sku_info->soc_speedo_id = 1; 180 178 threshold_index = THRESHOLD_INDEX_10; 181 179 break; 182 180 case 2: 183 - tegra_cpu_speedo_id = 3; 184 - tegra_soc_speedo_id = 2; 181 + sku_info->cpu_speedo_id = 3; 182 + sku_info->soc_speedo_id = 2; 185 183 threshold_index = THRESHOLD_INDEX_3; 186 184 break; 187 185 default: 188 - pr_err("Tegra30: Unknown pkg %d\n", package_id); 189 - BUG(); 186 + pr_err("Tegra Unknown pkg %d\n", package_id); 190 187 break; 191 188 } 192 189 break; 193 190 case 0x8F: 194 - tegra_cpu_speedo_id = 8; 195 - tegra_soc_speedo_id = 1; 191 + sku_info->cpu_speedo_id = 8; 192 + sku_info->soc_speedo_id = 1; 196 193 threshold_index = THRESHOLD_INDEX_11; 197 194 break; 198 195 case 0x08: 199 - tegra_cpu_speedo_id = 1; 200 - tegra_soc_speedo_id = 1; 196 + sku_info->cpu_speedo_id = 1; 197 + sku_info->soc_speedo_id = 1; 201 198 threshold_index = THRESHOLD_INDEX_4; 202 199 break; 203 200 case 0x02: 204 - tegra_cpu_speedo_id = 2; 205 - tegra_soc_speedo_id = 2; 201 + sku_info->cpu_speedo_id = 2; 202 + sku_info->soc_speedo_id = 2; 206 203 threshold_index = THRESHOLD_INDEX_5; 207 204 break; 208 205 case 0x04: 209 - tegra_cpu_speedo_id = 3; 210 - tegra_soc_speedo_id = 2; 206 + sku_info->cpu_speedo_id = 3; 207 + sku_info->soc_speedo_id = 2; 211 208 threshold_index = THRESHOLD_INDEX_6; 212 209 break; 213 210 case 0: 214 211 switch (package_id) { 215 212 case 1: 216 - tegra_cpu_speedo_id = 2; 217 - tegra_soc_speedo_id = 2; 213 + sku_info->cpu_speedo_id = 2; 214 + sku_info->soc_speedo_id = 2; 218 215 threshold_index = THRESHOLD_INDEX_2; 219 216 break; 220 217 case 2: 221 - tegra_cpu_speedo_id = 3; 222 - tegra_soc_speedo_id = 2; 218 + sku_info->cpu_speedo_id = 3; 219 + sku_info->soc_speedo_id = 2; 223 220 threshold_index = THRESHOLD_INDEX_3; 224 221 break; 225 222 default: 226 - pr_err("Tegra30: Unknown pkg %d\n", package_id); 227 - BUG(); 223 + pr_err("Tegra Unknown pkg %d\n", package_id); 228 224 break; 229 225 } 230 226 break; 231 227 default: 232 - pr_warn("Tegra30: Unknown SKU %d\n", sku); 233 - tegra_cpu_speedo_id = 0; 234 - tegra_soc_speedo_id = 0; 228 + pr_warn("Tegra Unknown SKU %d\n", sku_info->sku_id); 229 + sku_info->cpu_speedo_id = 0; 230 + sku_info->soc_speedo_id = 0; 235 231 threshold_index = THRESHOLD_INDEX_0; 236 232 break; 237 233 } 238 234 break; 239 235 default: 240 - pr_warn("Tegra30: Unknown chip rev %d\n", rev); 241 - tegra_cpu_speedo_id = 0; 242 - tegra_soc_speedo_id = 0; 236 + pr_warn("Tegra Unknown chip rev %d\n", sku_info->revision); 237 + sku_info->cpu_speedo_id = 0; 238 + sku_info->soc_speedo_id = 0; 243 239 threshold_index = THRESHOLD_INDEX_0; 244 240 break; 245 241 } 246 242 } 247 243 248 - void tegra30_init_speedo_data(void) 244 + void __init tegra30_init_speedo_data(struct tegra_sku_info *sku_info) 249 245 { 250 246 u32 cpu_speedo_val; 251 247 u32 core_speedo_val; ··· 254 254 BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != 255 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 259 fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val); 261 - pr_debug("%s CPU speedo value %u\n", __func__, cpu_speedo_val); 262 - pr_debug("%s Core speedo value %u\n", __func__, core_speedo_val); 260 + pr_debug("Tegra CPU speedo value %u\n", cpu_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 264 if (cpu_speedo_val < cpu_process_speedos[threshold_index][i]) 266 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) { 271 - pr_warn("Tegra30: CPU speedo value %3d out of range", 272 - cpu_speedo_val); 273 - tegra_cpu_process_id = 0; 274 - tegra_cpu_speedo_id = 1; 269 + if (sku_info->cpu_process_id == -1) { 270 + pr_warn("Tegra CPU speedo value %3d out of range", 271 + cpu_speedo_val); 272 + sku_info->cpu_process_id = 0; 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 277 if (core_speedo_val < core_process_speedos[threshold_index][i]) 279 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) { 284 - pr_warn("Tegra30: CORE speedo value %3d out of range", 285 - core_speedo_val); 286 - tegra_core_process_id = 0; 287 - tegra_soc_speedo_id = 1; 282 + if (sku_info->core_process_id == -1) { 283 + pr_warn("Tegra CORE speedo value %3d out of range", 284 + core_speedo_val); 285 + sku_info->core_process_id = 0; 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 }
+2 -1
drivers/amba/tegra-ahb.c
··· 25 25 #include <linux/module.h> 26 26 #include <linux/platform_device.h> 27 27 #include <linux/io.h> 28 - #include <linux/tegra-ahb.h> 28 + 29 + #include <soc/tegra/ahb.h> 29 30 30 31 #define DRV_NAME "tegra-ahb" 31 32
+2 -1
drivers/clk/tegra/clk-periph-gate.c
··· 20 20 #include <linux/io.h> 21 21 #include <linux/delay.h> 22 22 #include <linux/err.h> 23 - #include <linux/tegra-soc.h> 23 + 24 + #include <soc/tegra/fuse.h> 24 25 25 26 #include "clk.h" 26 27
+4 -1
drivers/clk/tegra/clk-tegra30.c
··· 22 22 #include <linux/of.h> 23 23 #include <linux/of_address.h> 24 24 #include <linux/clk/tegra.h> 25 - #include <linux/tegra-powergate.h> 25 + 26 + #include <soc/tegra/powergate.h> 27 + 26 28 #include <dt-bindings/clock/tegra30-car.h> 29 + 27 30 #include "clk.h" 28 31 #include "clk-id.h" 29 32
+2 -1
drivers/clk/tegra/clk.c
··· 19 19 #include <linux/of.h> 20 20 #include <linux/clk/tegra.h> 21 21 #include <linux/reset-controller.h> 22 - #include <linux/tegra-soc.h> 22 + 23 + #include <soc/tegra/fuse.h> 23 24 24 25 #include "clk.h" 25 26
+2 -1
drivers/gpu/drm/tegra/gr3d.c
··· 12 12 #include <linux/module.h> 13 13 #include <linux/platform_device.h> 14 14 #include <linux/reset.h> 15 - #include <linux/tegra-powergate.h> 15 + 16 + #include <soc/tegra/powergate.h> 16 17 17 18 #include "drm.h" 18 19 #include "gem.h"
+2 -1
drivers/gpu/drm/tegra/sor.c
··· 11 11 #include <linux/io.h> 12 12 #include <linux/platform_device.h> 13 13 #include <linux/reset.h> 14 - #include <linux/tegra-powergate.h> 14 + 15 + #include <soc/tegra/powergate.h> 15 16 16 17 #include <drm/drm_dp_helper.h> 17 18
+2 -1
drivers/iommu/tegra-smmu.c
··· 35 35 #include <linux/of_iommu.h> 36 36 #include <linux/debugfs.h> 37 37 #include <linux/seq_file.h> 38 - #include <linux/tegra-ahb.h> 38 + 39 + #include <soc/tegra/ahb.h> 39 40 40 41 #include <asm/page.h> 41 42 #include <asm/cacheflush.h>
+1
drivers/misc/fuse/Makefile
··· 1 + obj-$(CONFIG_ARCH_TEGRA) += tegra/
+3 -2
drivers/pci/host/pci-tegra.c
··· 41 41 #include <linux/reset.h> 42 42 #include <linux/sizes.h> 43 43 #include <linux/slab.h> 44 - #include <linux/tegra-cpuidle.h> 45 - #include <linux/tegra-powergate.h> 46 44 #include <linux/vmalloc.h> 47 45 #include <linux/regulator/consumer.h> 46 + 47 + #include <soc/tegra/cpuidle.h> 48 + #include <soc/tegra/powergate.h> 48 49 49 50 #include <asm/mach/irq.h> 50 51 #include <asm/mach/map.h>
+1
drivers/soc/Makefile
··· 3 3 # 4 4 5 5 obj-$(CONFIG_ARCH_QCOM) += qcom/ 6 + obj-$(CONFIG_ARCH_TEGRA) += tegra/
+1
drivers/soc/tegra/Makefile
··· 1 + obj-$(CONFIG_ARCH_TEGRA) += fuse/
+8
drivers/soc/tegra/fuse/Makefile
··· 1 + obj-y += fuse-tegra.o 2 + obj-y += fuse-tegra30.o 3 + obj-y += tegra-apbmisc.o 4 + obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += fuse-tegra20.o 5 + obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += speedo-tegra20.o 6 + obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += speedo-tegra30.o 7 + obj-$(CONFIG_ARCH_TEGRA_114_SOC) += speedo-tegra114.o 8 + obj-$(CONFIG_ARCH_TEGRA_124_SOC) += speedo-tegra124.o
+156
drivers/soc/tegra/fuse/fuse-tegra.c
··· 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 + 30 + static u32 (*fuse_readl)(const unsigned int offset); 31 + static int fuse_size; 32 + struct tegra_sku_info tegra_sku_info; 33 + 34 + static 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 + 43 + static 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 + 54 + static 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 + 72 + static struct bin_attribute fuse_bin_attr = { 73 + .attr = { .name = "fuse", .mode = S_IRUGO, }, 74 + .read = fuse_read, 75 + }; 76 + 77 + static 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 + 85 + static 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 + 102 + int 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 + } 111 + EXPORT_SYMBOL(tegra_fuse_readl); 112 + 113 + int 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 + 128 + void __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 + }
+215
drivers/soc/tegra/fuse/fuse-tegra20.c
··· 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 + 41 + static phys_addr_t fuse_phys; 42 + static struct clk *fuse_clk; 43 + static void __iomem __initdata *fuse_base; 44 + 45 + static DEFINE_MUTEX(apb_dma_lock); 46 + static DECLARE_COMPLETION(apb_dma_wait); 47 + static struct dma_chan *apb_dma_chan; 48 + static struct dma_slave_config dma_sconfig; 49 + static u32 *apb_buffer; 50 + static dma_addr_t apb_buffer_phys; 51 + 52 + static void apb_dma_complete(void *args) 53 + { 54 + complete(&apb_dma_wait); 55 + } 56 + 57 + static 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); 93 + out: 94 + mutex_unlock(&apb_dma_lock); 95 + 96 + return val; 97 + } 98 + 99 + static const struct of_device_id tegra20_fuse_of_match[] = { 100 + { .compatible = "nvidia,tegra20-efuse" }, 101 + {}, 102 + }; 103 + 104 + static 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 + 129 + static 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 + 157 + static 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 + 166 + static int __init tegra20_fuse_init(void) 167 + { 168 + return platform_driver_register(&tegra20_fuse_driver); 169 + } 170 + postcore_initcall(tegra20_fuse_init); 171 + 172 + /* Early boot code. This code is called before the devices are created */ 173 + 174 + u32 __init tegra20_fuse_early(const unsigned int offset) 175 + { 176 + return readl_relaxed(fuse_base + FUSE_BEGIN + offset); 177 + } 178 + 179 + bool __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 + 189 + static 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 + 206 + void __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 + }
+224
drivers/soc/tegra/fuse/fuse-tegra30.c
··· 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 + 45 + enum speedo_idx { 46 + SPEEDO_TEGRA30 = 0, 47 + SPEEDO_TEGRA114, 48 + SPEEDO_TEGRA124, 49 + }; 50 + 51 + struct tegra_fuse_info { 52 + int size; 53 + int spare_bit; 54 + enum speedo_idx speedo_idx; 55 + }; 56 + 57 + static void __iomem *fuse_base; 58 + static struct clk *fuse_clk; 59 + static struct tegra_fuse_info *fuse_info; 60 + 61 + u32 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 + 81 + static struct tegra_fuse_info tegra30_info = { 82 + .size = 0x2a4, 83 + .spare_bit = 0x144, 84 + .speedo_idx = SPEEDO_TEGRA30, 85 + }; 86 + 87 + static struct tegra_fuse_info tegra114_info = { 88 + .size = 0x2a0, 89 + .speedo_idx = SPEEDO_TEGRA114, 90 + }; 91 + 92 + static struct tegra_fuse_info tegra124_info = { 93 + .size = 0x300, 94 + .speedo_idx = SPEEDO_TEGRA124, 95 + }; 96 + 97 + static 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 + 104 + static 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 + 129 + static 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 + 138 + static int __init tegra30_fuse_init(void) 139 + { 140 + return platform_driver_register(&tegra30_fuse_driver); 141 + } 142 + postcore_initcall(tegra30_fuse_init); 143 + 144 + /* Early boot code. This code is called before the devices are created */ 145 + 146 + typedef void (*speedo_f)(struct tegra_sku_info *sku_info); 147 + 148 + static 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 + 154 + static 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 + 176 + static 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 + 195 + bool __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 + 202 + void __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 + }
+71
drivers/soc/tegra/fuse/fuse.h
··· 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 + 25 + int tegra_fuse_create_sysfs(struct device *dev, int size, 26 + u32 (*readl)(const unsigned int offset)); 27 + 28 + bool tegra30_spare_fuse(int bit); 29 + u32 tegra30_fuse_readl(const unsigned int offset); 30 + void tegra30_init_fuse_early(void); 31 + void tegra_init_revision(void); 32 + void tegra_init_apbmisc(void); 33 + 34 + #ifdef CONFIG_ARCH_TEGRA_2x_SOC 35 + void tegra20_init_speedo_data(struct tegra_sku_info *sku_info); 36 + bool tegra20_spare_fuse_early(int spare_bit); 37 + void tegra20_init_fuse_early(void); 38 + u32 tegra20_fuse_early(const unsigned int offset); 39 + #else 40 + static inline void tegra20_init_speedo_data(struct tegra_sku_info *sku_info) {} 41 + static inline bool tegra20_spare_fuse_early(int spare_bit) 42 + { 43 + return false; 44 + } 45 + static inline void tegra20_init_fuse_early(void) {} 46 + static 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 54 + void tegra30_init_speedo_data(struct tegra_sku_info *sku_info); 55 + #else 56 + static inline void tegra30_init_speedo_data(struct tegra_sku_info *sku_info) {} 57 + #endif 58 + 59 + #ifdef CONFIG_ARCH_TEGRA_114_SOC 60 + void tegra114_init_speedo_data(struct tegra_sku_info *sku_info); 61 + #else 62 + static inline void tegra114_init_speedo_data(struct tegra_sku_info *sku_info) {} 63 + #endif 64 + 65 + #ifdef CONFIG_ARCH_TEGRA_124_SOC 66 + void tegra124_init_speedo_data(struct tegra_sku_info *sku_info); 67 + #else 68 + static inline void tegra124_init_speedo_data(struct tegra_sku_info *sku_info) {} 69 + #endif 70 + 71 + #endif
+168
drivers/soc/tegra/fuse/speedo-tegra124.c
··· 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 + 40 + enum { 41 + THRESHOLD_INDEX_0, 42 + THRESHOLD_INDEX_1, 43 + THRESHOLD_INDEX_COUNT, 44 + }; 45 + 46 + static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = { 47 + {2190, UINT_MAX}, 48 + {0, UINT_MAX}, 49 + }; 50 + 51 + static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = { 52 + {1965, UINT_MAX}, 53 + {0, UINT_MAX}, 54 + }; 55 + 56 + static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = { 57 + {2101, UINT_MAX}, 58 + {0, UINT_MAX}, 59 + }; 60 + 61 + static 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 + 113 + void __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 + }
+112
drivers/soc/tegra/fuse/tegra-apbmisc.c
··· 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 + 31 + static void __iomem *apbmisc_base; 32 + static void __iomem *strapping_base; 33 + 34 + u32 tegra_read_chipid(void) 35 + { 36 + return readl_relaxed(apbmisc_base + 4); 37 + } 38 + 39 + u8 tegra_get_chip_id(void) 40 + { 41 + u32 id = tegra_read_chipid(); 42 + 43 + return (id >> 8) & 0xff; 44 + } 45 + 46 + u32 tegra_read_straps(void) 47 + { 48 + if (strapping_base) 49 + return readl_relaxed(strapping_base); 50 + else 51 + return 0; 52 + } 53 + 54 + static const struct of_device_id apbmisc_match[] __initconst = { 55 + { .compatible = "nvidia,tegra20-apbmisc", }, 56 + {}, 57 + }; 58 + 59 + void __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 + 97 + void __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 + }
-19
include/linux/tegra-ahb.h
··· 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 - 14 - #ifndef __LINUX_AHB_H__ 15 - #define __LINUX_AHB_H__ 16 - 17 - extern int tegra_ahb_enable_smmu(struct device_node *ahb); 18 - 19 - #endif /* __LINUX_AHB_H__ */
+3 -3
include/linux/tegra-cpuidle.h include/soc/tegra/cpuidle.h
··· 11 11 * more details. 12 12 */ 13 13 14 - #ifndef __LINUX_TEGRA_CPUIDLE_H__ 15 - #define __LINUX_TEGRA_CPUIDLE_H__ 14 + #ifndef __SOC_TEGRA_CPUIDLE_H__ 15 + #define __SOC_TEGRA_CPUIDLE_H__ 16 16 17 17 #ifdef CONFIG_CPU_IDLE 18 18 void tegra_cpuidle_pcie_irqs_in_use(void); ··· 22 22 } 23 23 #endif 24 24 25 - #endif 25 + #endif /* __SOC_TEGRA_CPUIDLE_H__ */
+3 -3
include/linux/tegra-powergate.h include/soc/tegra/powergate.h
··· 15 15 * 16 16 */ 17 17 18 - #ifndef _MACH_TEGRA_POWERGATE_H_ 19 - #define _MACH_TEGRA_POWERGATE_H_ 18 + #ifndef __SOC_TEGRA_POWERGATE_H__ 19 + #define __SOC_TEGRA_POWERGATE_H__ 20 20 21 21 struct clk; 22 22 struct reset_control; ··· 131 131 } 132 132 #endif 133 133 134 - #endif /* _MACH_TEGRA_POWERGATE_H_ */ 134 + #endif /* __SOC_TEGRA_POWERGATE_H__ */
+4 -7
include/linux/tegra-soc.h include/soc/tegra/ahb.h
··· 9 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 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 12 */ 16 13 17 - #ifndef __LINUX_TEGRA_SOC_H_ 18 - #define __LINUX_TEGRA_SOC_H_ 14 + #ifndef __SOC_TEGRA_AHB_H__ 15 + #define __SOC_TEGRA_AHB_H__ 19 16 20 - u32 tegra_read_chipid(void); 17 + extern int tegra_ahb_enable_smmu(struct device_node *ahb); 21 18 22 - #endif /* __LINUX_TEGRA_SOC_H_ */ 19 + #endif /* __SOC_TEGRA_AHB_H__ */
+66
include/soc/tegra/fuse.h
··· 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 + 30 + u32 tegra_read_chipid(void); 31 + u8 tegra_get_chip_id(void); 32 + 33 + enum 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 + 43 + struct 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 + 57 + u32 tegra_read_straps(void); 58 + u32 tegra_read_chipid(void); 59 + void tegra_init_fuse(void); 60 + int tegra_fuse_readl(unsigned long offset, u32 *value); 61 + 62 + extern struct tegra_sku_info tegra_sku_info; 63 + 64 + #endif /* __ASSEMBLY__ */ 65 + 66 + #endif /* __SOC_TEGRA_FUSE_H__ */