···11+What: /sys/devices/*/<our-device>/fuse22+Date: February 201433+Contact: Peter De Schrijver <pdeschrijver@nvidia.com>44+Description: read-only access to the efuses on Tegra20, Tegra30, Tegra11455+ and Tegra124 SoC's from NVIDIA. The efuses contain write once66+ data programmed at the factory. The data is layed out in 32bit77+ words in LSB first format. Each bit represents a single value88+ as decoded from the fuse registers. Bits order/assignment99+ exactly matches the HW registers, including any unused bits.1010+Users: any user space application which wants to read the efuses on1111+ Tegra SoC's
···11+NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse block.22+33+Required properties:44+- compatible : should be:55+ "nvidia,tegra20-efuse"66+ "nvidia,tegra30-efuse"77+ "nvidia,tegra114-efuse"88+ "nvidia,tegra124-efuse"99+ Details:1010+ nvidia,tegra20-efuse: Tegra20 requires using APB DMA to read the fuse data1111+ due to a hardware bug. Tegra20 also lacks certain information which is1212+ available in later generations such as fab code, lot code, wafer id,..1313+ nvidia,tegra30-efuse, nvidia,tegra114-efuse and nvidia,tegra124-efuse:1414+ The differences between these SoCs are the size of the efuse array,1515+ the location of the spare (OEM programmable) bits and the location of1616+ the speedo data.1717+- reg: Should contain 1 entry: the entry gives the physical address and length1818+ of the fuse registers.1919+- clocks: Must contain an entry for each entry in clock-names.2020+ See ../clocks/clock-bindings.txt for details.2121+- clock-names: Must include the following entries:2222+ - fuse2323+- resets: Must contain an entry for each entry in reset-names.2424+ See ../reset/reset.txt for details.2525+- reset-names: Must include the following entries:2626+ - fuse2727+2828+Example:2929+3030+ fuse@7000f800 {3131+ compatible = "nvidia,tegra20-efuse";3232+ reg = <0x7000F800 0x400>,3333+ <0x70000000 0x400>;3434+ clocks = <&tegra_car TEGRA20_CLK_FUSE>;3535+ clock-names = "fuse";3636+ resets = <&tegra_car 39>;3737+ reset-names = "fuse";3838+ };3939+4040+
···11+NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block22+33+Required properties:44+- compatible : should be:55+ "nvidia,tegra20-apbmisc"66+ "nvidia,tegra30-apbmisc"77+ "nvidia,tegra114-apbmisc"88+ "nvidia,tegra124-apbmisc"99+- reg: Should contain 2 entries: the first entry gives the physical address1010+ and length of the registers which contain revision and debug features.1111+ The second entry gives the physical address and length of the1212+ registers indicating the strapping options.1313+
···11-/*22- * Copyright (C) 2010 NVIDIA Corporation.33- * Copyright (C) 2010 Google, Inc.44- *55- * This software is licensed under the terms of the GNU General Public66- * License version 2, as published by the Free Software Foundation, and77- * may be copied, distributed, and modified under those terms.88- *99- * This program is distributed in the hope that it will be useful,1010- * but WITHOUT ANY WARRANTY; without even the implied warranty of1111- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1212- * GNU General Public License for more details.1313- *1414- */1515-1616-#include <linux/kernel.h>1717-#include <linux/io.h>1818-#include <linux/of.h>1919-#include <linux/dmaengine.h>2020-#include <linux/dma-mapping.h>2121-#include <linux/spinlock.h>2222-#include <linux/completion.h>2323-#include <linux/sched.h>2424-#include <linux/mutex.h>2525-2626-#include "apbio.h"2727-#include "iomap.h"2828-2929-#if defined(CONFIG_TEGRA20_APB_DMA)3030-static DEFINE_MUTEX(tegra_apb_dma_lock);3131-static u32 *tegra_apb_bb;3232-static dma_addr_t tegra_apb_bb_phys;3333-static DECLARE_COMPLETION(tegra_apb_wait);3434-3535-static u32 tegra_apb_readl_direct(unsigned long offset);3636-static void tegra_apb_writel_direct(u32 value, unsigned long offset);3737-3838-static struct dma_chan *tegra_apb_dma_chan;3939-static struct dma_slave_config dma_sconfig;4040-4141-static bool tegra_apb_dma_init(void)4242-{4343- dma_cap_mask_t mask;4444-4545- mutex_lock(&tegra_apb_dma_lock);4646-4747- /* Check to see if we raced to setup */4848- if (tegra_apb_dma_chan)4949- goto skip_init;5050-5151- dma_cap_zero(mask);5252- dma_cap_set(DMA_SLAVE, mask);5353- tegra_apb_dma_chan = dma_request_channel(mask, NULL, NULL);5454- if (!tegra_apb_dma_chan) {5555- /*5656- * This is common until the device is probed, so don't5757- * shout about it.5858- */5959- pr_debug("%s: can not allocate dma channel\n", __func__);6060- goto err_dma_alloc;6161- }6262-6363- tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),6464- &tegra_apb_bb_phys, GFP_KERNEL);6565- if (!tegra_apb_bb) {6666- pr_err("%s: can not allocate bounce buffer\n", __func__);6767- goto err_buff_alloc;6868- }6969-7070- dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;7171- dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;7272- dma_sconfig.src_maxburst = 1;7373- dma_sconfig.dst_maxburst = 1;7474-7575-skip_init:7676- mutex_unlock(&tegra_apb_dma_lock);7777- return true;7878-7979-err_buff_alloc:8080- dma_release_channel(tegra_apb_dma_chan);8181- tegra_apb_dma_chan = NULL;8282-8383-err_dma_alloc:8484- mutex_unlock(&tegra_apb_dma_lock);8585- return false;8686-}8787-8888-static void apb_dma_complete(void *args)8989-{9090- complete(&tegra_apb_wait);9191-}9292-9393-static int do_dma_transfer(unsigned long apb_add,9494- enum dma_transfer_direction dir)9595-{9696- struct dma_async_tx_descriptor *dma_desc;9797- int ret;9898-9999- if (dir == DMA_DEV_TO_MEM)100100- dma_sconfig.src_addr = apb_add;101101- else102102- dma_sconfig.dst_addr = apb_add;103103-104104- ret = dmaengine_slave_config(tegra_apb_dma_chan, &dma_sconfig);105105- if (ret)106106- return ret;107107-108108- dma_desc = dmaengine_prep_slave_single(tegra_apb_dma_chan,109109- tegra_apb_bb_phys, sizeof(u32), dir,110110- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);111111- if (!dma_desc)112112- return -EINVAL;113113-114114- dma_desc->callback = apb_dma_complete;115115- dma_desc->callback_param = NULL;116116-117117- reinit_completion(&tegra_apb_wait);118118-119119- dmaengine_submit(dma_desc);120120- dma_async_issue_pending(tegra_apb_dma_chan);121121- ret = wait_for_completion_timeout(&tegra_apb_wait,122122- msecs_to_jiffies(50));123123-124124- if (WARN(ret == 0, "apb read dma timed out")) {125125- dmaengine_terminate_all(tegra_apb_dma_chan);126126- return -EFAULT;127127- }128128- return 0;129129-}130130-131131-static u32 tegra_apb_readl_using_dma(unsigned long offset)132132-{133133- int ret;134134-135135- if (!tegra_apb_dma_chan && !tegra_apb_dma_init())136136- return tegra_apb_readl_direct(offset);137137-138138- mutex_lock(&tegra_apb_dma_lock);139139- ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);140140- if (ret < 0) {141141- pr_err("error in reading offset 0x%08lx using dma\n", offset);142142- *(u32 *)tegra_apb_bb = 0;143143- }144144- mutex_unlock(&tegra_apb_dma_lock);145145- return *((u32 *)tegra_apb_bb);146146-}147147-148148-static void tegra_apb_writel_using_dma(u32 value, unsigned long offset)149149-{150150- int ret;151151-152152- if (!tegra_apb_dma_chan && !tegra_apb_dma_init()) {153153- tegra_apb_writel_direct(value, offset);154154- return;155155- }156156-157157- mutex_lock(&tegra_apb_dma_lock);158158- *((u32 *)tegra_apb_bb) = value;159159- ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);160160- if (ret < 0)161161- pr_err("error in writing offset 0x%08lx using dma\n", offset);162162- mutex_unlock(&tegra_apb_dma_lock);163163-}164164-#else165165-#define tegra_apb_readl_using_dma tegra_apb_readl_direct166166-#define tegra_apb_writel_using_dma tegra_apb_writel_direct167167-#endif168168-169169-typedef u32 (*apbio_read_fptr)(unsigned long offset);170170-typedef void (*apbio_write_fptr)(u32 value, unsigned long offset);171171-172172-static apbio_read_fptr apbio_read;173173-static apbio_write_fptr apbio_write;174174-175175-static u32 tegra_apb_readl_direct(unsigned long offset)176176-{177177- return readl(IO_ADDRESS(offset));178178-}179179-180180-static void tegra_apb_writel_direct(u32 value, unsigned long offset)181181-{182182- writel(value, IO_ADDRESS(offset));183183-}184184-185185-void tegra_apb_io_init(void)186186-{187187- /* Need to use dma only when it is Tegra20 based platform */188188- if (of_machine_is_compatible("nvidia,tegra20") ||189189- !of_have_populated_dt()) {190190- apbio_read = tegra_apb_readl_using_dma;191191- apbio_write = tegra_apb_writel_using_dma;192192- } else {193193- apbio_read = tegra_apb_readl_direct;194194- apbio_write = tegra_apb_writel_direct;195195- }196196-}197197-198198-u32 tegra_apb_readl(unsigned long offset)199199-{200200- return apbio_read(offset);201201-}202202-203203-void tegra_apb_writel(u32 value, unsigned long offset)204204-{205205- apbio_write(value, offset);206206-}
-22
arch/arm/mach-tegra/apbio.h
···11-/*22- * Copyright (C) 2010 NVIDIA Corporation.33- * Copyright (C) 2010 Google, Inc.44- *55- * This software is licensed under the terms of the GNU General Public66- * License version 2, as published by the Free Software Foundation, and77- * may be copied, distributed, and modified under those terms.88- *99- * This program is distributed in the hope that it will be useful,1010- * but WITHOUT ANY WARRANTY; without even the implied warranty of1111- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1212- * GNU General Public License for more details.1313- *1414- */1515-1616-#ifndef __MACH_TEGRA_APBIO_H1717-#define __MACH_TEGRA_APBIO_H1818-1919-void tegra_apb_io_init(void);2020-u32 tegra_apb_readl(unsigned long offset);2121-void tegra_apb_writel(u32 value, unsigned long offset);2222-#endif
···2424#include <linux/kernel.h>2525#include <linux/module.h>26262727-#include "fuse.h"2727+#include <soc/tegra/fuse.h>2828+2829#include "cpuidle.h"29303031void __init tegra_cpuidle_init(void)3132{3232- switch (tegra_chip_id) {3333+ switch (tegra_get_chip_id()) {3334 case TEGRA20:3435 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))3536 tegra20_cpuidle_init();···50495150void tegra_cpuidle_pcie_irqs_in_use(void)5251{5353- switch (tegra_chip_id) {5252+ switch (tegra_get_chip_id()) {5453 case TEGRA20:5554 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))5655 tegra20_cpuidle_pcie_irqs_in_use();
+7-6
arch/arm/mach-tegra/flowctrl.c
···1818 * along with this program. If not, see <http://www.gnu.org/licenses/>.1919 */20202121-#include <linux/init.h>2222-#include <linux/kernel.h>2323-#include <linux/io.h>2421#include <linux/cpumask.h>2222+#include <linux/init.h>2323+#include <linux/io.h>2424+#include <linux/kernel.h>2525+2626+#include <soc/tegra/fuse.h>25272628#include "flowctrl.h"2729#include "iomap.h"2828-#include "fuse.h"29303031static u8 flowctrl_offset_halt_cpu[] = {3132 FLOW_CTRL_HALT_CPU0_EVENTS,···7776 int i;78777978 reg = flowctrl_read_cpu_csr(cpuid);8080- switch (tegra_chip_id) {7979+ switch (tegra_get_chip_id()) {8180 case TEGRA20:8281 /* clear wfe bitmap */8382 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;···118117119118 /* Disable powergating via flow controller for CPU0 */120119 reg = flowctrl_read_cpu_csr(cpuid);121121- switch (tegra_chip_id) {120120+ switch (tegra_get_chip_id()) {122121 case TEGRA20:123122 /* clear wfe bitmap */124123 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
-252
arch/arm/mach-tegra/fuse.c
···11-/*22- * arch/arm/mach-tegra/fuse.c33- *44- * Copyright (C) 2010 Google, Inc.55- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.66- *77- * Author:88- * Colin Cross <ccross@android.com>99- *1010- * This software is licensed under the terms of the GNU General Public1111- * License version 2, as published by the Free Software Foundation, and1212- * may be copied, distributed, and modified under those terms.1313- *1414- * This program is distributed in the hope that it will be useful,1515- * but WITHOUT ANY WARRANTY; without even the implied warranty of1616- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1717- * GNU General Public License for more details.1818- *1919- */2020-2121-#include <linux/kernel.h>2222-#include <linux/io.h>2323-#include <linux/export.h>2424-#include <linux/random.h>2525-#include <linux/clk.h>2626-#include <linux/tegra-soc.h>2727-2828-#include "fuse.h"2929-#include "iomap.h"3030-#include "apbio.h"3131-3232-/* Tegra20 only */3333-#define FUSE_UID_LOW 0x1083434-#define FUSE_UID_HIGH 0x10c3535-3636-/* Tegra30 and later */3737-#define FUSE_VENDOR_CODE 0x2003838-#define FUSE_FAB_CODE 0x2043939-#define FUSE_LOT_CODE_0 0x2084040-#define FUSE_LOT_CODE_1 0x20c4141-#define FUSE_WAFER_ID 0x2104242-#define FUSE_X_COORDINATE 0x2144343-#define FUSE_Y_COORDINATE 0x2184444-4545-#define FUSE_SKU_INFO 0x1104646-4747-#define TEGRA20_FUSE_SPARE_BIT 0x2004848-#define TEGRA30_FUSE_SPARE_BIT 0x2444949-5050-int tegra_sku_id;5151-int tegra_cpu_process_id;5252-int tegra_core_process_id;5353-int tegra_chip_id;5454-int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */5555-int tegra_soc_speedo_id;5656-enum tegra_revision tegra_revision;5757-5858-static struct clk *fuse_clk;5959-static int tegra_fuse_spare_bit;6060-static void (*tegra_init_speedo_data)(void);6161-6262-/* The BCT to use at boot is specified by board straps that can be read6363- * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.6464- */6565-int tegra_bct_strapping;6666-6767-#define STRAP_OPT 0x0086868-#define GMI_AD0 (1 << 4)6969-#define GMI_AD1 (1 << 5)7070-#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)7171-#define RAM_CODE_SHIFT 47272-7373-static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {7474- [TEGRA_REVISION_UNKNOWN] = "unknown",7575- [TEGRA_REVISION_A01] = "A01",7676- [TEGRA_REVISION_A02] = "A02",7777- [TEGRA_REVISION_A03] = "A03",7878- [TEGRA_REVISION_A03p] = "A03 prime",7979- [TEGRA_REVISION_A04] = "A04",8080-};8181-8282-static void tegra_fuse_enable_clk(void)8383-{8484- if (IS_ERR(fuse_clk))8585- fuse_clk = clk_get_sys(NULL, "fuse");8686- if (IS_ERR(fuse_clk))8787- return;8888- clk_prepare_enable(fuse_clk);8989-}9090-9191-static void tegra_fuse_disable_clk(void)9292-{9393- if (IS_ERR(fuse_clk))9494- return;9595- clk_disable_unprepare(fuse_clk);9696-}9797-9898-u32 tegra_fuse_readl(unsigned long offset)9999-{100100- return tegra_apb_readl(TEGRA_FUSE_BASE + offset);101101-}102102-103103-bool tegra_spare_fuse(int bit)104104-{105105- bool ret;106106-107107- tegra_fuse_enable_clk();108108-109109- ret = tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);110110-111111- tegra_fuse_disable_clk();112112-113113- return ret;114114-}115115-116116-static enum tegra_revision tegra_get_revision(u32 id)117117-{118118- u32 minor_rev = (id >> 16) & 0xf;119119-120120- switch (minor_rev) {121121- case 1:122122- return TEGRA_REVISION_A01;123123- case 2:124124- return TEGRA_REVISION_A02;125125- case 3:126126- if (tegra_chip_id == TEGRA20 &&127127- (tegra_spare_fuse(18) || tegra_spare_fuse(19)))128128- return TEGRA_REVISION_A03p;129129- else130130- return TEGRA_REVISION_A03;131131- case 4:132132- return TEGRA_REVISION_A04;133133- default:134134- return TEGRA_REVISION_UNKNOWN;135135- }136136-}137137-138138-static void tegra_get_process_id(void)139139-{140140- u32 reg;141141-142142- tegra_fuse_enable_clk();143143-144144- reg = tegra_fuse_readl(tegra_fuse_spare_bit);145145- tegra_cpu_process_id = (reg >> 6) & 3;146146- reg = tegra_fuse_readl(tegra_fuse_spare_bit);147147- tegra_core_process_id = (reg >> 12) & 3;148148-149149- tegra_fuse_disable_clk();150150-}151151-152152-u32 tegra_read_chipid(void)153153-{154154- return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);155155-}156156-157157-static void __init tegra20_fuse_init_randomness(void)158158-{159159- u32 randomness[2];160160-161161- randomness[0] = tegra_fuse_readl(FUSE_UID_LOW);162162- randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH);163163-164164- add_device_randomness(randomness, sizeof(randomness));165165-}166166-167167-/* Applies to Tegra30 or later */168168-static void __init tegra30_fuse_init_randomness(void)169169-{170170- u32 randomness[7];171171-172172- randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE);173173- randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE);174174- randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0);175175- randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1);176176- randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID);177177- randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE);178178- randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE);179179-180180- add_device_randomness(randomness, sizeof(randomness));181181-}182182-183183-void __init tegra_init_fuse(void)184184-{185185- u32 id;186186- u32 randomness[5];187187-188188- u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));189189- reg |= 1 << 28;190190- writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));191191-192192- /*193193- * Enable FUSE clock. This needs to be hardcoded because the clock194194- * subsystem is not active during early boot.195195- */196196- reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));197197- reg |= 1 << 7;198198- writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));199199- fuse_clk = ERR_PTR(-EINVAL);200200-201201- reg = tegra_fuse_readl(FUSE_SKU_INFO);202202- randomness[0] = reg;203203- tegra_sku_id = reg & 0xFF;204204-205205- reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);206206- randomness[1] = reg;207207- tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;208208-209209- id = tegra_read_chipid();210210- randomness[2] = id;211211- tegra_chip_id = (id >> 8) & 0xff;212212-213213- switch (tegra_chip_id) {214214- case TEGRA20:215215- tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;216216- tegra_init_speedo_data = &tegra20_init_speedo_data;217217- break;218218- case TEGRA30:219219- tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;220220- tegra_init_speedo_data = &tegra30_init_speedo_data;221221- break;222222- case TEGRA114:223223- tegra_init_speedo_data = &tegra114_init_speedo_data;224224- break;225225- default:226226- pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);227227- tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;228228- tegra_init_speedo_data = &tegra_get_process_id;229229- }230230-231231- tegra_revision = tegra_get_revision(id);232232- tegra_init_speedo_data();233233- randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id;234234- randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id;235235-236236- add_device_randomness(randomness, sizeof(randomness));237237- switch (tegra_chip_id) {238238- case TEGRA20:239239- tegra20_fuse_init_randomness();240240- break;241241- case TEGRA30:242242- case TEGRA114:243243- default:244244- tegra30_fuse_init_randomness();245245- break;246246- }247247-248248- pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",249249- tegra_revision_name[tegra_revision],250250- tegra_sku_id, tegra_cpu_process_id,251251- tegra_core_process_id);252252-}
-79
arch/arm/mach-tegra/fuse.h
···11-/*22- * Copyright (C) 2010 Google, Inc.33- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.44- *55- * Author:66- * Colin Cross <ccross@android.com>77- *88- * This software is licensed under the terms of the GNU General Public99- * License version 2, as published by the Free Software Foundation, and1010- * may be copied, distributed, and modified under those terms.1111- *1212- * This program is distributed in the hope that it will be useful,1313- * but WITHOUT ANY WARRANTY; without even the implied warranty of1414- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515- * GNU General Public License for more details.1616- *1717- */1818-1919-#ifndef __MACH_TEGRA_FUSE_H2020-#define __MACH_TEGRA_FUSE_H2121-2222-#define SKU_ID_T20 82323-#define SKU_ID_T25SE 202424-#define SKU_ID_AP25 232525-#define SKU_ID_T25 242626-#define SKU_ID_AP25E 272727-#define SKU_ID_T25E 282828-2929-#define TEGRA20 0x203030-#define TEGRA30 0x303131-#define TEGRA114 0x353232-#define TEGRA124 0x403333-3434-#ifndef __ASSEMBLY__3535-enum tegra_revision {3636- TEGRA_REVISION_UNKNOWN = 0,3737- TEGRA_REVISION_A01,3838- TEGRA_REVISION_A02,3939- TEGRA_REVISION_A03,4040- TEGRA_REVISION_A03p,4141- TEGRA_REVISION_A04,4242- TEGRA_REVISION_MAX,4343-};4444-4545-extern int tegra_sku_id;4646-extern int tegra_cpu_process_id;4747-extern int tegra_core_process_id;4848-extern int tegra_chip_id;4949-extern int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */5050-extern int tegra_soc_speedo_id;5151-extern enum tegra_revision tegra_revision;5252-5353-extern int tegra_bct_strapping;5454-5555-unsigned long long tegra_chip_uid(void);5656-void tegra_init_fuse(void);5757-bool tegra_spare_fuse(int bit);5858-u32 tegra_fuse_readl(unsigned long offset);5959-6060-#ifdef CONFIG_ARCH_TEGRA_2x_SOC6161-void tegra20_init_speedo_data(void);6262-#else6363-static inline void tegra20_init_speedo_data(void) {}6464-#endif6565-6666-#ifdef CONFIG_ARCH_TEGRA_3x_SOC6767-void tegra30_init_speedo_data(void);6868-#else6969-static inline void tegra30_init_speedo_data(void) {}7070-#endif7171-7272-#ifdef CONFIG_ARCH_TEGRA_114_SOC7373-void tegra114_init_speedo_data(void);7474-#else7575-static inline void tegra114_init_speedo_data(void) {}7676-#endif7777-#endif /* __ASSEMBLY__ */7878-7979-#endif
+8-6
arch/arm/mach-tegra/hotplug.c
···77 * it under the terms of the GNU General Public License version 2 as88 * published by the Free Software Foundation.99 */1010+1111+#include <linux/clk/tegra.h>1012#include <linux/kernel.h>1113#include <linux/smp.h>1212-#include <linux/clk/tegra.h>1414+1515+#include <soc/tegra/fuse.h>13161417#include <asm/smp_plat.h>15181616-#include "fuse.h"1719#include "sleep.h"18201921static void (*tegra_hotplug_shutdown)(void);···5351 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))5452 return;55535656- if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)5454+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)5755 tegra_hotplug_shutdown = tegra20_hotplug_shutdown;5858- if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)5656+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)5957 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;6060- if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)5858+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)6159 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;6262- if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124)6060+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)6361 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;6462}
···1111 * it under the terms of the GNU General Public License version 2 as1212 * published by the Free Software Foundation.1313 */1414-#include <linux/init.h>1515-#include <linux/errno.h>1414+1515+#include <linux/clk/tegra.h>1616#include <linux/delay.h>1717#include <linux/device.h>1818+#include <linux/errno.h>1919+#include <linux/init.h>2020+#include <linux/io.h>1821#include <linux/jiffies.h>1922#include <linux/smp.h>2020-#include <linux/io.h>2121-#include <linux/clk/tegra.h>2323+2424+#include <soc/tegra/fuse.h>22252326#include <asm/cacheflush.h>2427#include <asm/mach-types.h>2525-#include <asm/smp_scu.h>2628#include <asm/smp_plat.h>2727-2828-#include "fuse.h"2929-#include "flowctrl.h"3030-#include "reset.h"3131-#include "pmc.h"2929+#include <asm/smp_scu.h>32303331#include "common.h"3232+#include "flowctrl.h"3433#include "iomap.h"3434+#include "pmc.h"3535+#include "reset.h"35363637static cpumask_t tegra_cpu_init_mask;3738···171170static int tegra_boot_secondary(unsigned int cpu,172171 struct task_struct *idle)173172{174174- if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)173173+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)175174 return tegra20_boot_secondary(cpu, idle);176176- if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)175175+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)177176 return tegra30_boot_secondary(cpu, idle);178178- if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)177177+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)179178 return tegra114_boot_secondary(cpu, idle);180180- if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124)179179+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)181180 return tegra114_boot_secondary(cpu, idle);182181183182 return -EINVAL;
+1
arch/arm/mach-tegra/pm-tegra20.c
···1313 * You should have received a copy of the GNU General Public License1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.1515 */1616+1617#include <linux/kernel.h>17181819#include "pm.h"
+1
arch/arm/mach-tegra/pm-tegra30.c
···1313 * You should have received a copy of the GNU General Public License1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.1515 */1616+1617#include <linux/kernel.h>17181819#include "pm.h"
+20-19
arch/arm/mach-tegra/pm.c
···1616 * along with this program. If not, see <http://www.gnu.org/licenses/>.1717 */18181919-#include <linux/kernel.h>2020-#include <linux/spinlock.h>2121-#include <linux/io.h>2222-#include <linux/cpumask.h>2323-#include <linux/delay.h>2424-#include <linux/cpu_pm.h>2525-#include <linux/suspend.h>2626-#include <linux/err.h>2727-#include <linux/slab.h>2819#include <linux/clk/tegra.h>2020+#include <linux/cpumask.h>2121+#include <linux/cpu_pm.h>2222+#include <linux/delay.h>2323+#include <linux/err.h>2424+#include <linux/io.h>2525+#include <linux/kernel.h>2626+#include <linux/slab.h>2727+#include <linux/spinlock.h>2828+#include <linux/suspend.h>29293030-#include <asm/smp_plat.h>3030+#include <soc/tegra/fuse.h>3131+3132#include <asm/cacheflush.h>3232-#include <asm/suspend.h>3333#include <asm/idmap.h>3434#include <asm/proc-fns.h>3535+#include <asm/smp_plat.h>3636+#include <asm/suspend.h>3537#include <asm/tlbflush.h>36383737-#include "iomap.h"3838-#include "reset.h"3939#include "flowctrl.h"4040-#include "fuse.h"4141-#include "pm.h"4040+#include "iomap.h"4241#include "pmc.h"4242+#include "pm.h"4343+#include "reset.h"4344#include "sleep.h"44454546#ifdef CONFIG_PM_SLEEP···54535554static void tegra_tear_down_cpu_init(void)5655{5757- switch (tegra_chip_id) {5656+ switch (tegra_get_chip_id()) {5857 case TEGRA20:5958 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))6059 tegra_tear_down_cpu = tegra20_tear_down_cpu;···144143145144 if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))146145 last_cpu = true;147147- else if (tegra_chip_id == TEGRA20 && phy_cpu_id == 1)146146+ else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1)148147 tegra20_cpu_set_resettable_soon();149148150149 spin_unlock(&tegra_lp2_lock);···213212 */214213static bool tegra_lp1_iram_hook(void)215214{216216- switch (tegra_chip_id) {215215+ switch (tegra_get_chip_id()) {217216 case TEGRA20:218217 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))219218 tegra20_lp1_iram_hook();···243242244243static bool tegra_sleep_core_init(void)245244{246246- switch (tegra_chip_id) {245245+ switch (tegra_get_chip_id()) {247246 case TEGRA20:248247 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))249248 tegra20_sleep_core_init();
···1717 *1818 */19192020-#include <linux/kernel.h>2120#include <linux/clk.h>2121+#include <linux/clk/tegra.h>2222#include <linux/debugfs.h>2323#include <linux/delay.h>2424#include <linux/err.h>2525#include <linux/export.h>2626#include <linux/init.h>2727#include <linux/io.h>2828+#include <linux/kernel.h>2829#include <linux/reset.h>2930#include <linux/seq_file.h>3031#include <linux/spinlock.h>3131-#include <linux/clk/tegra.h>3232-#include <linux/tegra-powergate.h>33323434-#include "fuse.h"3333+#include <soc/tegra/fuse.h>3434+#include <soc/tegra/powergate.h>3535+3536#include "iomap.h"36373738#define DPD_SAMPLE 0x020···158157 * The Tegra124 GPU has a separate register (with different semantics)159158 * to remove clamps.160159 */161161- if (tegra_chip_id == TEGRA124) {160160+ if (tegra_get_chip_id() == TEGRA124) {162161 if (id == TEGRA_POWERGATE_3D) {163162 pmc_write(0, GPU_RG_CNTRL);164163 return 0;···228227229228int __init tegra_powergate_init(void)230229{231231- switch (tegra_chip_id) {230230+ switch (tegra_get_chip_id()) {232231 case TEGRA20:233232 tegra_num_powerdomains = 7;234233 break;···369368{370369 struct dentry *d;371370372372- switch (tegra_chip_id) {371371+ switch (tegra_get_chip_id()) {373372 case TEGRA20:374373 powergate_name = powergate_name_t20;375374 break;
+4-3
arch/arm/mach-tegra/reset-handler.S
···1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.1515 */16161717-#include <linux/linkage.h>1817#include <linux/init.h>1818+#include <linux/linkage.h>19192020-#include <asm/cache.h>2020+#include <soc/tegra/fuse.h>2121+2122#include <asm/asm-offsets.h>2323+#include <asm/cache.h>22242325#include "flowctrl.h"2424-#include "fuse.h"2526#include "iomap.h"2627#include "reset.h"2728#include "sleep.h"
+6-5
arch/arm/mach-tegra/reset.c
···1414 *1515 */16161717+#include <linux/bitops.h>1818+#include <linux/cpumask.h>1719#include <linux/init.h>1820#include <linux/io.h>1919-#include <linux/cpumask.h>2020-#include <linux/bitops.h>2121+2222+#include <soc/tegra/fuse.h>21232224#include <asm/cacheflush.h>2323-#include <asm/hardware/cache-l2x0.h>2425#include <asm/firmware.h>2626+#include <asm/hardware/cache-l2x0.h>25272628#include "iomap.h"2729#include "irammap.h"2830#include "reset.h"2931#include "sleep.h"3030-#include "fuse.h"31323233#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \3334 TEGRA_IRAM_RESET_HANDLER_OFFSET)···5453 * Prevent further modifications to the physical reset vector.5554 * NOTE: Has no effect on chips prior to Tegra30.5655 */5757- if (tegra_chip_id != TEGRA20) {5656+ if (tegra_get_chip_id() != TEGRA20) {5857 reg = readl(sb_ctrl);5958 reg |= 2;6059 writel(reg, sb_ctrl);
···11+/*22+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.33+ *44+ * This program is free software; you can redistribute it and/or modify it55+ * under the terms and conditions of the GNU General Public License,66+ * version 2, as published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope it will be useful, but WITHOUT99+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1010+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1111+ * more details.1212+ *1313+ * You should have received a copy of the GNU General Public License1414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.1515+ *1616+ */1717+1818+#include <linux/device.h>1919+#include <linux/kobject.h>2020+#include <linux/kernel.h>2121+#include <linux/platform_device.h>2222+#include <linux/of.h>2323+#include <linux/of_address.h>2424+#include <linux/io.h>2525+2626+#include <soc/tegra/fuse.h>2727+2828+#include "fuse.h"2929+3030+static u32 (*fuse_readl)(const unsigned int offset);3131+static int fuse_size;3232+struct tegra_sku_info tegra_sku_info;3333+3434+static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {3535+ [TEGRA_REVISION_UNKNOWN] = "unknown",3636+ [TEGRA_REVISION_A01] = "A01",3737+ [TEGRA_REVISION_A02] = "A02",3838+ [TEGRA_REVISION_A03] = "A03",3939+ [TEGRA_REVISION_A03p] = "A03 prime",4040+ [TEGRA_REVISION_A04] = "A04",4141+};4242+4343+static u8 fuse_readb(const unsigned int offset)4444+{4545+ u32 val;4646+4747+ val = fuse_readl(round_down(offset, 4));4848+ val >>= (offset % 4) * 8;4949+ val &= 0xff;5050+5151+ return val;5252+}5353+5454+static ssize_t fuse_read(struct file *fd, struct kobject *kobj,5555+ struct bin_attribute *attr, char *buf,5656+ loff_t pos, size_t size)5757+{5858+ int i;5959+6060+ if (pos < 0 || pos >= fuse_size)6161+ return 0;6262+6363+ if (size > fuse_size - pos)6464+ size = fuse_size - pos;6565+6666+ for (i = 0; i < size; i++)6767+ buf[i] = fuse_readb(pos + i);6868+6969+ return i;7070+}7171+7272+static struct bin_attribute fuse_bin_attr = {7373+ .attr = { .name = "fuse", .mode = S_IRUGO, },7474+ .read = fuse_read,7575+};7676+7777+static const struct of_device_id car_match[] __initconst = {7878+ { .compatible = "nvidia,tegra20-car", },7979+ { .compatible = "nvidia,tegra30-car", },8080+ { .compatible = "nvidia,tegra114-car", },8181+ { .compatible = "nvidia,tegra124-car", },8282+ {},8383+};8484+8585+static void tegra_enable_fuse_clk(void __iomem *base)8686+{8787+ u32 reg;8888+8989+ reg = readl_relaxed(base + 0x48);9090+ reg |= 1 << 28;9191+ writel(reg, base + 0x48);9292+9393+ /*9494+ * Enable FUSE clock. This needs to be hardcoded because the clock9595+ * subsystem is not active during early boot.9696+ */9797+ reg = readl(base + 0x14);9898+ reg |= 1 << 7;9999+ writel(reg, base + 0x14);100100+}101101+102102+int tegra_fuse_readl(unsigned long offset, u32 *value)103103+{104104+ if (!fuse_readl)105105+ return -EPROBE_DEFER;106106+107107+ *value = fuse_readl(offset);108108+109109+ return 0;110110+}111111+EXPORT_SYMBOL(tegra_fuse_readl);112112+113113+int tegra_fuse_create_sysfs(struct device *dev, int size,114114+ u32 (*readl)(const unsigned int offset))115115+{116116+ if (fuse_size)117117+ return -ENODEV;118118+119119+ fuse_bin_attr.size = size;120120+ fuse_bin_attr.read = fuse_read;121121+122122+ fuse_size = size;123123+ fuse_readl = readl;124124+125125+ return device_create_bin_file(dev, &fuse_bin_attr);126126+}127127+128128+void __init tegra_init_fuse(void)129129+{130130+ struct device_node *np;131131+ void __iomem *car_base;132132+133133+ tegra_init_apbmisc();134134+135135+ np = of_find_matching_node(NULL, car_match);136136+ car_base = of_iomap(np, 0);137137+ if (car_base) {138138+ tegra_enable_fuse_clk(car_base);139139+ iounmap(car_base);140140+ } else {141141+ pr_err("Could not enable fuse clk. ioremap tegra car failed.\n");142142+ return;143143+ }144144+145145+ if (tegra_get_chip_id() == TEGRA20)146146+ tegra20_init_fuse_early();147147+ else148148+ tegra30_init_fuse_early();149149+150150+ pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",151151+ tegra_revision_name[tegra_sku_info.revision],152152+ tegra_sku_info.sku_id, tegra_sku_info.cpu_process_id,153153+ tegra_sku_info.core_process_id);154154+ pr_debug("Tegra CPU Speedo ID %d, Soc Speedo ID %d\n",155155+ tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);156156+}
+215
drivers/soc/tegra/fuse/fuse-tegra20.c
···11+/*22+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.33+ *44+ * This program is free software; you can redistribute it and/or modify it55+ * under the terms and conditions of the GNU General Public License,66+ * version 2, as published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope it will be useful, but WITHOUT99+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1010+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1111+ * more details.1212+ *1313+ * You should have received a copy of the GNU General Public License1414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.1515+ *1616+ * Based on drivers/misc/eeprom/sunxi_sid.c1717+ */1818+1919+#include <linux/device.h>2020+#include <linux/clk.h>2121+#include <linux/completion.h>2222+#include <linux/dmaengine.h>2323+#include <linux/dma-mapping.h>2424+#include <linux/err.h>2525+#include <linux/io.h>2626+#include <linux/kernel.h>2727+#include <linux/kobject.h>2828+#include <linux/of_device.h>2929+#include <linux/platform_device.h>3030+#include <linux/random.h>3131+3232+#include <soc/tegra/fuse.h>3333+3434+#include "fuse.h"3535+3636+#define FUSE_BEGIN 0x1003737+#define FUSE_SIZE 0x1f83838+#define FUSE_UID_LOW 0x083939+#define FUSE_UID_HIGH 0x0c4040+4141+static phys_addr_t fuse_phys;4242+static struct clk *fuse_clk;4343+static void __iomem __initdata *fuse_base;4444+4545+static DEFINE_MUTEX(apb_dma_lock);4646+static DECLARE_COMPLETION(apb_dma_wait);4747+static struct dma_chan *apb_dma_chan;4848+static struct dma_slave_config dma_sconfig;4949+static u32 *apb_buffer;5050+static dma_addr_t apb_buffer_phys;5151+5252+static void apb_dma_complete(void *args)5353+{5454+ complete(&apb_dma_wait);5555+}5656+5757+static u32 tegra20_fuse_readl(const unsigned int offset)5858+{5959+ int ret;6060+ u32 val = 0;6161+ struct dma_async_tx_descriptor *dma_desc;6262+6363+ mutex_lock(&apb_dma_lock);6464+6565+ dma_sconfig.src_addr = fuse_phys + FUSE_BEGIN + offset;6666+ ret = dmaengine_slave_config(apb_dma_chan, &dma_sconfig);6767+ if (ret)6868+ goto out;6969+7070+ dma_desc = dmaengine_prep_slave_single(apb_dma_chan, apb_buffer_phys,7171+ sizeof(u32), DMA_DEV_TO_MEM,7272+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);7373+ if (!dma_desc)7474+ goto out;7575+7676+ dma_desc->callback = apb_dma_complete;7777+ dma_desc->callback_param = NULL;7878+7979+ reinit_completion(&apb_dma_wait);8080+8181+ clk_prepare_enable(fuse_clk);8282+8383+ dmaengine_submit(dma_desc);8484+ dma_async_issue_pending(apb_dma_chan);8585+ ret = wait_for_completion_timeout(&apb_dma_wait, msecs_to_jiffies(50));8686+8787+ if (WARN(ret == 0, "apb read dma timed out"))8888+ dmaengine_terminate_all(apb_dma_chan);8989+ else9090+ val = *apb_buffer;9191+9292+ clk_disable_unprepare(fuse_clk);9393+out:9494+ mutex_unlock(&apb_dma_lock);9595+9696+ return val;9797+}9898+9999+static const struct of_device_id tegra20_fuse_of_match[] = {100100+ { .compatible = "nvidia,tegra20-efuse" },101101+ {},102102+};103103+104104+static int apb_dma_init(void)105105+{106106+ dma_cap_mask_t mask;107107+108108+ dma_cap_zero(mask);109109+ dma_cap_set(DMA_SLAVE, mask);110110+ apb_dma_chan = dma_request_channel(mask, NULL, NULL);111111+ if (!apb_dma_chan)112112+ return -EPROBE_DEFER;113113+114114+ apb_buffer = dma_alloc_coherent(NULL, sizeof(u32), &apb_buffer_phys,115115+ GFP_KERNEL);116116+ if (!apb_buffer) {117117+ dma_release_channel(apb_dma_chan);118118+ return -ENOMEM;119119+ }120120+121121+ dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;122122+ dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;123123+ dma_sconfig.src_maxburst = 1;124124+ dma_sconfig.dst_maxburst = 1;125125+126126+ return 0;127127+}128128+129129+static int tegra20_fuse_probe(struct platform_device *pdev)130130+{131131+ struct resource *res;132132+ int err;133133+134134+ fuse_clk = devm_clk_get(&pdev->dev, NULL);135135+ if (IS_ERR(fuse_clk)) {136136+ dev_err(&pdev->dev, "missing clock");137137+ return PTR_ERR(fuse_clk);138138+ }139139+140140+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);141141+ if (!res)142142+ return -EINVAL;143143+ fuse_phys = res->start;144144+145145+ err = apb_dma_init();146146+ if (err)147147+ return err;148148+149149+ if (tegra_fuse_create_sysfs(&pdev->dev, FUSE_SIZE, tegra20_fuse_readl))150150+ return -ENODEV;151151+152152+ dev_dbg(&pdev->dev, "loaded\n");153153+154154+ return 0;155155+}156156+157157+static struct platform_driver tegra20_fuse_driver = {158158+ .probe = tegra20_fuse_probe,159159+ .driver = {160160+ .name = "tegra20_fuse",161161+ .owner = THIS_MODULE,162162+ .of_match_table = tegra20_fuse_of_match,163163+ }164164+};165165+166166+static int __init tegra20_fuse_init(void)167167+{168168+ return platform_driver_register(&tegra20_fuse_driver);169169+}170170+postcore_initcall(tegra20_fuse_init);171171+172172+/* Early boot code. This code is called before the devices are created */173173+174174+u32 __init tegra20_fuse_early(const unsigned int offset)175175+{176176+ return readl_relaxed(fuse_base + FUSE_BEGIN + offset);177177+}178178+179179+bool __init tegra20_spare_fuse_early(int spare_bit)180180+{181181+ u32 offset = spare_bit * 4;182182+ bool value;183183+184184+ value = tegra20_fuse_early(offset + 0x100);185185+186186+ return value;187187+}188188+189189+static void __init tegra20_fuse_add_randomness(void)190190+{191191+ u32 randomness[7];192192+193193+ randomness[0] = tegra_sku_info.sku_id;194194+ randomness[1] = tegra_read_straps();195195+ randomness[2] = tegra_read_chipid();196196+ randomness[3] = tegra_sku_info.cpu_process_id << 16;197197+ randomness[3] |= tegra_sku_info.core_process_id;198198+ randomness[4] = tegra_sku_info.cpu_speedo_id << 16;199199+ randomness[4] |= tegra_sku_info.soc_speedo_id;200200+ randomness[5] = tegra20_fuse_early(FUSE_UID_LOW);201201+ randomness[6] = tegra20_fuse_early(FUSE_UID_HIGH);202202+203203+ add_device_randomness(randomness, sizeof(randomness));204204+}205205+206206+void __init tegra20_init_fuse_early(void)207207+{208208+ fuse_base = ioremap(TEGRA_FUSE_BASE, TEGRA_FUSE_SIZE);209209+210210+ tegra_init_revision();211211+ tegra20_init_speedo_data(&tegra_sku_info);212212+ tegra20_fuse_add_randomness();213213+214214+ iounmap(fuse_base);215215+}
+224
drivers/soc/tegra/fuse/fuse-tegra30.c
···11+/*22+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.33+ *44+ * This program is free software; you can redistribute it and/or modify it55+ * under the terms and conditions of the GNU General Public License,66+ * version 2, as published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope it will be useful, but WITHOUT99+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1010+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1111+ * more details.1212+ *1313+ * You should have received a copy of the GNU General Public License1414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.1515+ *1616+ */1717+1818+#include <linux/device.h>1919+#include <linux/clk.h>2020+#include <linux/err.h>2121+#include <linux/io.h>2222+#include <linux/kernel.h>2323+#include <linux/of_device.h>2424+#include <linux/of_address.h>2525+#include <linux/platform_device.h>2626+#include <linux/random.h>2727+2828+#include <soc/tegra/fuse.h>2929+3030+#include "fuse.h"3131+3232+#define FUSE_BEGIN 0x1003333+3434+/* Tegra30 and later */3535+#define FUSE_VENDOR_CODE 0x1003636+#define FUSE_FAB_CODE 0x1043737+#define FUSE_LOT_CODE_0 0x1083838+#define FUSE_LOT_CODE_1 0x10c3939+#define FUSE_WAFER_ID 0x1104040+#define FUSE_X_COORDINATE 0x1144141+#define FUSE_Y_COORDINATE 0x1184242+4343+#define FUSE_HAS_REVISION_INFO BIT(0)4444+4545+enum speedo_idx {4646+ SPEEDO_TEGRA30 = 0,4747+ SPEEDO_TEGRA114,4848+ SPEEDO_TEGRA124,4949+};5050+5151+struct tegra_fuse_info {5252+ int size;5353+ int spare_bit;5454+ enum speedo_idx speedo_idx;5555+};5656+5757+static void __iomem *fuse_base;5858+static struct clk *fuse_clk;5959+static struct tegra_fuse_info *fuse_info;6060+6161+u32 tegra30_fuse_readl(const unsigned int offset)6262+{6363+ u32 val;6464+6565+ /*6666+ * early in the boot, the fuse clock will be enabled by6767+ * tegra_init_fuse()6868+ */6969+7070+ if (fuse_clk)7171+ clk_prepare_enable(fuse_clk);7272+7373+ val = readl_relaxed(fuse_base + FUSE_BEGIN + offset);7474+7575+ if (fuse_clk)7676+ clk_disable_unprepare(fuse_clk);7777+7878+ return val;7979+}8080+8181+static struct tegra_fuse_info tegra30_info = {8282+ .size = 0x2a4,8383+ .spare_bit = 0x144,8484+ .speedo_idx = SPEEDO_TEGRA30,8585+};8686+8787+static struct tegra_fuse_info tegra114_info = {8888+ .size = 0x2a0,8989+ .speedo_idx = SPEEDO_TEGRA114,9090+};9191+9292+static struct tegra_fuse_info tegra124_info = {9393+ .size = 0x300,9494+ .speedo_idx = SPEEDO_TEGRA124,9595+};9696+9797+static const struct of_device_id tegra30_fuse_of_match[] = {9898+ { .compatible = "nvidia,tegra30-efuse", .data = &tegra30_info },9999+ { .compatible = "nvidia,tegra114-efuse", .data = &tegra114_info },100100+ { .compatible = "nvidia,tegra124-efuse", .data = &tegra124_info },101101+ {},102102+};103103+104104+static int tegra30_fuse_probe(struct platform_device *pdev)105105+{106106+ const struct of_device_id *of_dev_id;107107+108108+ of_dev_id = of_match_device(tegra30_fuse_of_match, &pdev->dev);109109+ if (!of_dev_id)110110+ return -ENODEV;111111+112112+ fuse_clk = devm_clk_get(&pdev->dev, NULL);113113+ if (IS_ERR(fuse_clk)) {114114+ dev_err(&pdev->dev, "missing clock");115115+ return PTR_ERR(fuse_clk);116116+ }117117+118118+ platform_set_drvdata(pdev, NULL);119119+120120+ if (tegra_fuse_create_sysfs(&pdev->dev, fuse_info->size,121121+ tegra30_fuse_readl))122122+ return -ENODEV;123123+124124+ dev_dbg(&pdev->dev, "loaded\n");125125+126126+ return 0;127127+}128128+129129+static struct platform_driver tegra30_fuse_driver = {130130+ .probe = tegra30_fuse_probe,131131+ .driver = {132132+ .name = "tegra_fuse",133133+ .owner = THIS_MODULE,134134+ .of_match_table = tegra30_fuse_of_match,135135+ }136136+};137137+138138+static int __init tegra30_fuse_init(void)139139+{140140+ return platform_driver_register(&tegra30_fuse_driver);141141+}142142+postcore_initcall(tegra30_fuse_init);143143+144144+/* Early boot code. This code is called before the devices are created */145145+146146+typedef void (*speedo_f)(struct tegra_sku_info *sku_info);147147+148148+static speedo_f __initdata speedo_tbl[] = {149149+ [SPEEDO_TEGRA30] = tegra30_init_speedo_data,150150+ [SPEEDO_TEGRA114] = tegra114_init_speedo_data,151151+ [SPEEDO_TEGRA124] = tegra124_init_speedo_data,152152+};153153+154154+static void __init tegra30_fuse_add_randomness(void)155155+{156156+ u32 randomness[12];157157+158158+ randomness[0] = tegra_sku_info.sku_id;159159+ randomness[1] = tegra_read_straps();160160+ randomness[2] = tegra_read_chipid();161161+ randomness[3] = tegra_sku_info.cpu_process_id << 16;162162+ randomness[3] |= tegra_sku_info.core_process_id;163163+ randomness[4] = tegra_sku_info.cpu_speedo_id << 16;164164+ randomness[4] |= tegra_sku_info.soc_speedo_id;165165+ randomness[5] = tegra30_fuse_readl(FUSE_VENDOR_CODE);166166+ randomness[6] = tegra30_fuse_readl(FUSE_FAB_CODE);167167+ randomness[7] = tegra30_fuse_readl(FUSE_LOT_CODE_0);168168+ randomness[8] = tegra30_fuse_readl(FUSE_LOT_CODE_1);169169+ randomness[9] = tegra30_fuse_readl(FUSE_WAFER_ID);170170+ randomness[10] = tegra30_fuse_readl(FUSE_X_COORDINATE);171171+ randomness[11] = tegra30_fuse_readl(FUSE_Y_COORDINATE);172172+173173+ add_device_randomness(randomness, sizeof(randomness));174174+}175175+176176+static void __init legacy_fuse_init(void)177177+{178178+ switch (tegra_get_chip_id()) {179179+ case TEGRA30:180180+ fuse_info = &tegra30_info;181181+ break;182182+ case TEGRA114:183183+ fuse_info = &tegra114_info;184184+ break;185185+ case TEGRA124:186186+ fuse_info = &tegra124_info;187187+ break;188188+ default:189189+ return;190190+ }191191+192192+ fuse_base = ioremap(TEGRA_FUSE_BASE, TEGRA_FUSE_SIZE);193193+}194194+195195+bool __init tegra30_spare_fuse(int spare_bit)196196+{197197+ u32 offset = fuse_info->spare_bit + spare_bit * 4;198198+199199+ return tegra30_fuse_readl(offset) & 1;200200+}201201+202202+void __init tegra30_init_fuse_early(void)203203+{204204+ struct device_node *np;205205+ const struct of_device_id *of_match;206206+207207+ np = of_find_matching_node_and_match(NULL, tegra30_fuse_of_match,208208+ &of_match);209209+ if (np) {210210+ fuse_base = of_iomap(np, 0);211211+ fuse_info = (struct tegra_fuse_info *)of_match->data;212212+ } else213213+ legacy_fuse_init();214214+215215+ if (!fuse_base) {216216+ pr_warn("fuse DT node missing and unknown chip id: 0x%02x\n",217217+ tegra_get_chip_id());218218+ return;219219+ }220220+221221+ tegra_init_revision();222222+ speedo_tbl[fuse_info->speedo_idx](&tegra_sku_info);223223+ tegra30_fuse_add_randomness();224224+}
+71
drivers/soc/tegra/fuse/fuse.h
···11+/*22+ * Copyright (C) 2010 Google, Inc.33+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.44+ *55+ * Author:66+ * Colin Cross <ccross@android.com>77+ *88+ * This software is licensed under the terms of the GNU General Public99+ * License version 2, as published by the Free Software Foundation, and1010+ * may be copied, distributed, and modified under those terms.1111+ *1212+ * This program is distributed in the hope that it will be useful,1313+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515+ * GNU General Public License for more details.1616+ *1717+ */1818+1919+#ifndef __DRIVERS_MISC_TEGRA_FUSE_H2020+#define __DRIVERS_MISC_TEGRA_FUSE_H2121+2222+#define TEGRA_FUSE_BASE 0x7000f8002323+#define TEGRA_FUSE_SIZE 0x4002424+2525+int tegra_fuse_create_sysfs(struct device *dev, int size,2626+ u32 (*readl)(const unsigned int offset));2727+2828+bool tegra30_spare_fuse(int bit);2929+u32 tegra30_fuse_readl(const unsigned int offset);3030+void tegra30_init_fuse_early(void);3131+void tegra_init_revision(void);3232+void tegra_init_apbmisc(void);3333+3434+#ifdef CONFIG_ARCH_TEGRA_2x_SOC3535+void tegra20_init_speedo_data(struct tegra_sku_info *sku_info);3636+bool tegra20_spare_fuse_early(int spare_bit);3737+void tegra20_init_fuse_early(void);3838+u32 tegra20_fuse_early(const unsigned int offset);3939+#else4040+static inline void tegra20_init_speedo_data(struct tegra_sku_info *sku_info) {}4141+static inline bool tegra20_spare_fuse_early(int spare_bit)4242+{4343+ return false;4444+}4545+static inline void tegra20_init_fuse_early(void) {}4646+static inline u32 tegra20_fuse_early(const unsigned int offset)4747+{4848+ return 0;4949+}5050+#endif5151+5252+5353+#ifdef CONFIG_ARCH_TEGRA_3x_SOC5454+void tegra30_init_speedo_data(struct tegra_sku_info *sku_info);5555+#else5656+static inline void tegra30_init_speedo_data(struct tegra_sku_info *sku_info) {}5757+#endif5858+5959+#ifdef CONFIG_ARCH_TEGRA_114_SOC6060+void tegra114_init_speedo_data(struct tegra_sku_info *sku_info);6161+#else6262+static inline void tegra114_init_speedo_data(struct tegra_sku_info *sku_info) {}6363+#endif6464+6565+#ifdef CONFIG_ARCH_TEGRA_124_SOC6666+void tegra124_init_speedo_data(struct tegra_sku_info *sku_info);6767+#else6868+static inline void tegra124_init_speedo_data(struct tegra_sku_info *sku_info) {}6969+#endif7070+7171+#endif
+168
drivers/soc/tegra/fuse/speedo-tegra124.c
···11+/*22+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.33+ *44+ * This program is free software; you can redistribute it and/or modify it55+ * under the terms and conditions of the GNU General Public License,66+ * version 2, as published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope it will be useful, but WITHOUT99+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1010+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1111+ * more details.1212+ *1313+ * You should have received a copy of the GNU General Public License1414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.1515+ */1616+1717+#include <linux/device.h>1818+#include <linux/kernel.h>1919+#include <linux/bug.h>2020+2121+#include <soc/tegra/fuse.h>2222+2323+#include "fuse.h"2424+2525+#define CPU_PROCESS_CORNERS 22626+#define GPU_PROCESS_CORNERS 22727+#define CORE_PROCESS_CORNERS 22828+2929+#define FUSE_CPU_SPEEDO_0 0x143030+#define FUSE_CPU_SPEEDO_1 0x2c3131+#define FUSE_CPU_SPEEDO_2 0x303232+#define FUSE_SOC_SPEEDO_0 0x343333+#define FUSE_SOC_SPEEDO_1 0x383434+#define FUSE_SOC_SPEEDO_2 0x3c3535+#define FUSE_CPU_IDDQ 0x183636+#define FUSE_SOC_IDDQ 0x403737+#define FUSE_GPU_IDDQ 0x1283838+#define FUSE_FT_REV 0x283939+4040+enum {4141+ THRESHOLD_INDEX_0,4242+ THRESHOLD_INDEX_1,4343+ THRESHOLD_INDEX_COUNT,4444+};4545+4646+static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {4747+ {2190, UINT_MAX},4848+ {0, UINT_MAX},4949+};5050+5151+static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = {5252+ {1965, UINT_MAX},5353+ {0, UINT_MAX},5454+};5555+5656+static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = {5757+ {2101, UINT_MAX},5858+ {0, UINT_MAX},5959+};6060+6161+static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,6262+ int *threshold)6363+{6464+ int sku = sku_info->sku_id;6565+6666+ /* Assign to default */6767+ sku_info->cpu_speedo_id = 0;6868+ sku_info->soc_speedo_id = 0;6969+ sku_info->gpu_speedo_id = 0;7070+ *threshold = THRESHOLD_INDEX_0;7171+7272+ switch (sku) {7373+ case 0x00: /* Eng sku */7474+ case 0x0F:7575+ case 0x23:7676+ /* Using the default */7777+ break;7878+ case 0x83:7979+ sku_info->cpu_speedo_id = 2;8080+ break;8181+8282+ case 0x1F:8383+ case 0x87:8484+ case 0x27:8585+ sku_info->cpu_speedo_id = 2;8686+ sku_info->soc_speedo_id = 0;8787+ sku_info->gpu_speedo_id = 1;8888+ *threshold = THRESHOLD_INDEX_0;8989+ break;9090+ case 0x81:9191+ case 0x21:9292+ case 0x07:9393+ sku_info->cpu_speedo_id = 1;9494+ sku_info->soc_speedo_id = 1;9595+ sku_info->gpu_speedo_id = 1;9696+ *threshold = THRESHOLD_INDEX_1;9797+ break;9898+ case 0x49:9999+ case 0x4A:100100+ case 0x48:101101+ sku_info->cpu_speedo_id = 4;102102+ sku_info->soc_speedo_id = 2;103103+ sku_info->gpu_speedo_id = 3;104104+ *threshold = THRESHOLD_INDEX_1;105105+ break;106106+ default:107107+ pr_err("Tegra Unknown SKU %d\n", sku);108108+ /* Using the default for the error case */109109+ break;110110+ }111111+}112112+113113+void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)114114+{115115+ int i, threshold, cpu_speedo_0_value, soc_speedo_0_value;116116+ int cpu_iddq_value, gpu_iddq_value, soc_iddq_value;117117+118118+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=119119+ THRESHOLD_INDEX_COUNT);120120+ BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=121121+ THRESHOLD_INDEX_COUNT);122122+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=123123+ THRESHOLD_INDEX_COUNT);124124+125125+ cpu_speedo_0_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_0);126126+127127+ /* GPU Speedo is stored in CPU_SPEEDO_2 */128128+ sku_info->gpu_speedo_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_2);129129+130130+ soc_speedo_0_value = tegra30_fuse_readl(FUSE_SOC_SPEEDO_0);131131+132132+ cpu_iddq_value = tegra30_fuse_readl(FUSE_CPU_IDDQ);133133+ soc_iddq_value = tegra30_fuse_readl(FUSE_SOC_IDDQ);134134+ gpu_iddq_value = tegra30_fuse_readl(FUSE_GPU_IDDQ);135135+136136+ sku_info->cpu_speedo_value = cpu_speedo_0_value;137137+138138+ if (sku_info->cpu_speedo_value == 0) {139139+ pr_warn("Tegra Warning: Speedo value not fused.\n");140140+ WARN_ON(1);141141+ return;142142+ }143143+144144+ rev_sku_to_speedo_ids(sku_info, &threshold);145145+146146+ sku_info->cpu_iddq_value = tegra30_fuse_readl(FUSE_CPU_IDDQ);147147+148148+ for (i = 0; i < GPU_PROCESS_CORNERS; i++)149149+ if (sku_info->gpu_speedo_value <150150+ gpu_process_speedos[threshold][i])151151+ break;152152+ sku_info->gpu_process_id = i;153153+154154+ for (i = 0; i < CPU_PROCESS_CORNERS; i++)155155+ if (sku_info->cpu_speedo_value <156156+ cpu_process_speedos[threshold][i])157157+ break;158158+ sku_info->cpu_process_id = i;159159+160160+ for (i = 0; i < CORE_PROCESS_CORNERS; i++)161161+ if (soc_speedo_0_value <162162+ core_process_speedos[threshold][i])163163+ break;164164+ sku_info->core_process_id = i;165165+166166+ pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",167167+ sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);168168+}
+112
drivers/soc/tegra/fuse/tegra-apbmisc.c
···11+/*22+ * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.33+ *44+ * This program is free software; you can redistribute it and/or modify it55+ * under the terms and conditions of the GNU General Public License,66+ * version 2, as published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope it will be useful, but WITHOUT99+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1010+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1111+ * more details.1212+ *1313+ * You should have received a copy of the GNU General Public License1414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.1515+ *1616+ */1717+1818+#include <linux/kernel.h>1919+#include <linux/of.h>2020+#include <linux/of_address.h>2121+#include <linux/io.h>2222+2323+#include <soc/tegra/fuse.h>2424+2525+#include "fuse.h"2626+2727+#define APBMISC_BASE 0x700008002828+#define APBMISC_SIZE 0x642929+#define FUSE_SKU_INFO 0x103030+3131+static void __iomem *apbmisc_base;3232+static void __iomem *strapping_base;3333+3434+u32 tegra_read_chipid(void)3535+{3636+ return readl_relaxed(apbmisc_base + 4);3737+}3838+3939+u8 tegra_get_chip_id(void)4040+{4141+ u32 id = tegra_read_chipid();4242+4343+ return (id >> 8) & 0xff;4444+}4545+4646+u32 tegra_read_straps(void)4747+{4848+ if (strapping_base)4949+ return readl_relaxed(strapping_base);5050+ else5151+ return 0;5252+}5353+5454+static const struct of_device_id apbmisc_match[] __initconst = {5555+ { .compatible = "nvidia,tegra20-apbmisc", },5656+ {},5757+};5858+5959+void __init tegra_init_revision(void)6060+{6161+ u32 id, chip_id, minor_rev;6262+ int rev;6363+6464+ id = tegra_read_chipid();6565+ chip_id = (id >> 8) & 0xff;6666+ minor_rev = (id >> 16) & 0xf;6767+6868+ switch (minor_rev) {6969+ case 1:7070+ rev = TEGRA_REVISION_A01;7171+ break;7272+ case 2:7373+ rev = TEGRA_REVISION_A02;7474+ break;7575+ case 3:7676+ if (chip_id == TEGRA20 && (tegra20_spare_fuse_early(18) ||7777+ tegra20_spare_fuse_early(19)))7878+ rev = TEGRA_REVISION_A03p;7979+ else8080+ rev = TEGRA_REVISION_A03;8181+ break;8282+ case 4:8383+ rev = TEGRA_REVISION_A04;8484+ break;8585+ default:8686+ rev = TEGRA_REVISION_UNKNOWN;8787+ }8888+8989+ tegra_sku_info.revision = rev;9090+9191+ if (chip_id == TEGRA20)9292+ tegra_sku_info.sku_id = tegra20_fuse_early(FUSE_SKU_INFO);9393+ else9494+ tegra_sku_info.sku_id = tegra30_fuse_readl(FUSE_SKU_INFO);9595+}9696+9797+void __init tegra_init_apbmisc(void)9898+{9999+ struct device_node *np;100100+101101+ np = of_find_matching_node(NULL, apbmisc_match);102102+ apbmisc_base = of_iomap(np, 0);103103+ if (!apbmisc_base) {104104+ pr_warn("ioremap tegra apbmisc failed. using %08x instead\n",105105+ APBMISC_BASE);106106+ apbmisc_base = ioremap(APBMISC_BASE, APBMISC_SIZE);107107+ }108108+109109+ strapping_base = of_iomap(np, 1);110110+ if (!strapping_base)111111+ pr_err("ioremap tegra strapping_base failed\n");112112+}
-19
include/linux/tegra-ahb.h
···11-/*22- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.33- *44- * This program is free software; you can redistribute it and/or modify it55- * under the terms and conditions of the GNU General Public License,66- * version 2, as published by the Free Software Foundation.77- *88- * This program is distributed in the hope it will be useful, but WITHOUT99- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1010- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1111- * more details.1212- */1313-1414-#ifndef __LINUX_AHB_H__1515-#define __LINUX_AHB_H__1616-1717-extern int tegra_ahb_enable_smmu(struct device_node *ahb);1818-1919-#endif /* __LINUX_AHB_H__ */
···99 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1010 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1111 * more details.1212- *1313- * You should have received a copy of the GNU General Public License1414- * along with this program. If not, see <http://www.gnu.org/licenses/>.1512 */16131717-#ifndef __LINUX_TEGRA_SOC_H_1818-#define __LINUX_TEGRA_SOC_H_1414+#ifndef __SOC_TEGRA_AHB_H__1515+#define __SOC_TEGRA_AHB_H__19162020-u32 tegra_read_chipid(void);1717+extern int tegra_ahb_enable_smmu(struct device_node *ahb);21182222-#endif /* __LINUX_TEGRA_SOC_H_ */1919+#endif /* __SOC_TEGRA_AHB_H__ */
+66
include/soc/tegra/fuse.h
···11+/*22+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.33+ *44+ * This program is free software; you can redistribute it and/or modify it55+ * under the terms and conditions of the GNU General Public License,66+ * version 2, as published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope it will be useful, but WITHOUT99+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1010+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1111+ * more details.1212+ *1313+ * You should have received a copy of the GNU General Public License1414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.1515+ */1616+1717+#ifndef __SOC_TEGRA_FUSE_H__1818+#define __SOC_TEGRA_FUSE_H__1919+2020+#define TEGRA20 0x202121+#define TEGRA30 0x302222+#define TEGRA114 0x352323+#define TEGRA124 0x402424+2525+#define TEGRA_FUSE_SKU_CALIB_0 0xf02626+#define TEGRA30_FUSE_SATA_CALIB 0x1242727+2828+#ifndef __ASSEMBLY__2929+3030+u32 tegra_read_chipid(void);3131+u8 tegra_get_chip_id(void);3232+3333+enum tegra_revision {3434+ TEGRA_REVISION_UNKNOWN = 0,3535+ TEGRA_REVISION_A01,3636+ TEGRA_REVISION_A02,3737+ TEGRA_REVISION_A03,3838+ TEGRA_REVISION_A03p,3939+ TEGRA_REVISION_A04,4040+ TEGRA_REVISION_MAX,4141+};4242+4343+struct tegra_sku_info {4444+ int sku_id;4545+ int cpu_process_id;4646+ int cpu_speedo_id;4747+ int cpu_speedo_value;4848+ int cpu_iddq_value;4949+ int core_process_id;5050+ int soc_speedo_id;5151+ int gpu_speedo_id;5252+ int gpu_process_id;5353+ int gpu_speedo_value;5454+ enum tegra_revision revision;5555+};5656+5757+u32 tegra_read_straps(void);5858+u32 tegra_read_chipid(void);5959+void tegra_init_fuse(void);6060+int tegra_fuse_readl(unsigned long offset, u32 *value);6161+6262+extern struct tegra_sku_info tegra_sku_info;6363+6464+#endif /* __ASSEMBLY__ */6565+6666+#endif /* __SOC_TEGRA_FUSE_H__ */