You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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>
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
What: /sys/devices/*/<our-device>/fuse
|
||||
Date: February 2014
|
||||
Contact: Peter De Schrijver <pdeschrijver@nvidia.com>
|
||||
Description: read-only access to the efuses on Tegra20, Tegra30, Tegra114
|
||||
and Tegra124 SoC's from NVIDIA. The efuses contain write once
|
||||
data programmed at the factory. The data is layed out in 32bit
|
||||
words in LSB first format. Each bit represents a single value
|
||||
as decoded from the fuse registers. Bits order/assignment
|
||||
exactly matches the HW registers, including any unused bits.
|
||||
Users: any user space application which wants to read the efuses on
|
||||
Tegra SoC's
|
||||
@@ -0,0 +1,40 @@
|
||||
NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse block.
|
||||
|
||||
Required properties:
|
||||
- compatible : should be:
|
||||
"nvidia,tegra20-efuse"
|
||||
"nvidia,tegra30-efuse"
|
||||
"nvidia,tegra114-efuse"
|
||||
"nvidia,tegra124-efuse"
|
||||
Details:
|
||||
nvidia,tegra20-efuse: Tegra20 requires using APB DMA to read the fuse data
|
||||
due to a hardware bug. Tegra20 also lacks certain information which is
|
||||
available in later generations such as fab code, lot code, wafer id,..
|
||||
nvidia,tegra30-efuse, nvidia,tegra114-efuse and nvidia,tegra124-efuse:
|
||||
The differences between these SoCs are the size of the efuse array,
|
||||
the location of the spare (OEM programmable) bits and the location of
|
||||
the speedo data.
|
||||
- reg: Should contain 1 entry: the entry gives the physical address and length
|
||||
of the fuse registers.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- fuse
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- fuse
|
||||
|
||||
Example:
|
||||
|
||||
fuse@7000f800 {
|
||||
compatible = "nvidia,tegra20-efuse";
|
||||
reg = <0x7000F800 0x400>,
|
||||
<0x70000000 0x400>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_FUSE>;
|
||||
clock-names = "fuse";
|
||||
resets = <&tegra_car 39>;
|
||||
reset-names = "fuse";
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block
|
||||
|
||||
Required properties:
|
||||
- compatible : should be:
|
||||
"nvidia,tegra20-apbmisc"
|
||||
"nvidia,tegra30-apbmisc"
|
||||
"nvidia,tegra114-apbmisc"
|
||||
"nvidia,tegra124-apbmisc"
|
||||
- reg: Should contain 2 entries: the first entry gives the physical address
|
||||
and length of the registers which contain revision and debug features.
|
||||
The second entry gives the physical address and length of the
|
||||
registers indicating the strapping options.
|
||||
|
||||
@@ -220,6 +220,12 @@
|
||||
interrupt-controller;
|
||||
};
|
||||
|
||||
apbmisc@70000800 {
|
||||
compatible = "nvidia,tegra114-apbmisc", "nvidia,tegra20-apbmisc";
|
||||
reg = <0x70000800 0x64 /* Chip revision */
|
||||
0x70000008 0x04>; /* Strapping options */
|
||||
};
|
||||
|
||||
pinmux: pinmux@70000868 {
|
||||
compatible = "nvidia,tegra114-pinmux";
|
||||
reg = <0x70000868 0x148 /* Pad control registers */
|
||||
@@ -485,6 +491,15 @@
|
||||
clock-names = "pclk", "clk32k_in";
|
||||
};
|
||||
|
||||
fuse@7000f800 {
|
||||
compatible = "nvidia,tegra114-efuse";
|
||||
reg = <0x7000f800 0x400>;
|
||||
clocks = <&tegra_car TEGRA114_CLK_FUSE>;
|
||||
clock-names = "fuse";
|
||||
resets = <&tegra_car 39>;
|
||||
reset-names = "fuse";
|
||||
};
|
||||
|
||||
iommu@70019010 {
|
||||
compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu";
|
||||
reg = <0x70019010 0x02c
|
||||
|
||||
@@ -179,6 +179,12 @@
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
apbmisc@0,70000800 {
|
||||
compatible = "nvidia,tegra124-apbmisc", "nvidia,tegra20-apbmisc";
|
||||
reg = <0x0 0x70000800 0x0 0x64>, /* Chip revision */
|
||||
<0x0 0x7000E864 0x0 0x04>; /* Strapping options */
|
||||
};
|
||||
|
||||
pinmux: pinmux@0,70000868 {
|
||||
compatible = "nvidia,tegra124-pinmux";
|
||||
reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */
|
||||
@@ -449,6 +455,15 @@
|
||||
clock-names = "pclk", "clk32k_in";
|
||||
};
|
||||
|
||||
fuse@0,7000f800 {
|
||||
compatible = "nvidia,tegra124-efuse";
|
||||
reg = <0x0 0x7000f800 0x0 0x400>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_FUSE>;
|
||||
clock-names = "fuse";
|
||||
resets = <&tegra_car 39>;
|
||||
reset-names = "fuse";
|
||||
};
|
||||
|
||||
sdhci@0,700b0000 {
|
||||
compatible = "nvidia,tegra124-sdhci";
|
||||
reg = <0x0 0x700b0000 0x0 0x200>;
|
||||
|
||||
@@ -236,6 +236,12 @@
|
||||
interrupt-controller;
|
||||
};
|
||||
|
||||
apbmisc@70000800 {
|
||||
compatible = "nvidia,tegra20-apbmisc";
|
||||
reg = <0x70000800 0x64 /* Chip revision */
|
||||
0x70000008 0x04>; /* Strapping options */
|
||||
};
|
||||
|
||||
pinmux: pinmux@70000014 {
|
||||
compatible = "nvidia,tegra20-pinmux";
|
||||
reg = <0x70000014 0x10 /* Tri-state registers */
|
||||
@@ -545,6 +551,15 @@
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
fuse@7000f800 {
|
||||
compatible = "nvidia,tegra20-efuse";
|
||||
reg = <0x7000F800 0x400>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_FUSE>;
|
||||
clock-names = "fuse";
|
||||
resets = <&tegra_car 39>;
|
||||
reset-names = "fuse";
|
||||
};
|
||||
|
||||
pcie-controller@80003000 {
|
||||
compatible = "nvidia,tegra20-pcie";
|
||||
device_type = "pci";
|
||||
|
||||
@@ -335,6 +335,12 @@
|
||||
interrupt-controller;
|
||||
};
|
||||
|
||||
apbmisc@70000800 {
|
||||
compatible = "nvidia,tegra30-apbmisc", "nvidia,tegra20-apbmisc";
|
||||
reg = <0x70000800 0x64 /* Chip revision */
|
||||
0x70000008 0x04>; /* Strapping options */
|
||||
};
|
||||
|
||||
pinmux: pinmux@70000868 {
|
||||
compatible = "nvidia,tegra30-pinmux";
|
||||
reg = <0x70000868 0xd4 /* Pad control registers */
|
||||
@@ -631,6 +637,15 @@
|
||||
nvidia,ahb = <&ahb>;
|
||||
};
|
||||
|
||||
fuse@7000f800 {
|
||||
compatible = "nvidia,tegra30-efuse";
|
||||
reg = <0x7000f800 0x400>;
|
||||
clocks = <&tegra_car TEGRA30_CLK_FUSE>;
|
||||
clock-names = "fuse";
|
||||
resets = <&tegra_car 39>;
|
||||
reset-names = "fuse";
|
||||
};
|
||||
|
||||
ahub@70080000 {
|
||||
compatible = "nvidia,tegra30-ahub";
|
||||
reg = <0x70080000 0x200
|
||||
|
||||
@@ -2,24 +2,20 @@ asflags-y += -march=armv7-a
|
||||
|
||||
obj-y += io.o
|
||||
obj-y += irq.o
|
||||
obj-y += fuse.o
|
||||
obj-y += pmc.o
|
||||
obj-y += flowctrl.o
|
||||
obj-y += powergate.o
|
||||
obj-y += apbio.o
|
||||
obj-y += pm.o
|
||||
obj-y += reset.o
|
||||
obj-y += reset-handler.o
|
||||
obj-y += sleep.o
|
||||
obj-y += tegra.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
|
||||
endif
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
@@ -28,7 +24,6 @@ endif
|
||||
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
|
||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 NVIDIA Corporation.
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include "apbio.h"
|
||||
#include "iomap.h"
|
||||
|
||||
#if defined(CONFIG_TEGRA20_APB_DMA)
|
||||
static DEFINE_MUTEX(tegra_apb_dma_lock);
|
||||
static u32 *tegra_apb_bb;
|
||||
static dma_addr_t tegra_apb_bb_phys;
|
||||
static DECLARE_COMPLETION(tegra_apb_wait);
|
||||
|
||||
static u32 tegra_apb_readl_direct(unsigned long offset);
|
||||
static void tegra_apb_writel_direct(u32 value, unsigned long offset);
|
||||
|
||||
static struct dma_chan *tegra_apb_dma_chan;
|
||||
static struct dma_slave_config dma_sconfig;
|
||||
|
||||
static bool tegra_apb_dma_init(void)
|
||||
{
|
||||
dma_cap_mask_t mask;
|
||||
|
||||
mutex_lock(&tegra_apb_dma_lock);
|
||||
|
||||
/* Check to see if we raced to setup */
|
||||
if (tegra_apb_dma_chan)
|
||||
goto skip_init;
|
||||
|
||||
dma_cap_zero(mask);
|
||||
dma_cap_set(DMA_SLAVE, mask);
|
||||
tegra_apb_dma_chan = dma_request_channel(mask, NULL, NULL);
|
||||
if (!tegra_apb_dma_chan) {
|
||||
/*
|
||||
* This is common until the device is probed, so don't
|
||||
* shout about it.
|
||||
*/
|
||||
pr_debug("%s: can not allocate dma channel\n", __func__);
|
||||
goto err_dma_alloc;
|
||||
}
|
||||
|
||||
tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),
|
||||
&tegra_apb_bb_phys, GFP_KERNEL);
|
||||
if (!tegra_apb_bb) {
|
||||
pr_err("%s: can not allocate bounce buffer\n", __func__);
|
||||
goto err_buff_alloc;
|
||||
}
|
||||
|
||||
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
dma_sconfig.src_maxburst = 1;
|
||||
dma_sconfig.dst_maxburst = 1;
|
||||
|
||||
skip_init:
|
||||
mutex_unlock(&tegra_apb_dma_lock);
|
||||
return true;
|
||||
|
||||
err_buff_alloc:
|
||||
dma_release_channel(tegra_apb_dma_chan);
|
||||
tegra_apb_dma_chan = NULL;
|
||||
|
||||
err_dma_alloc:
|
||||
mutex_unlock(&tegra_apb_dma_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void apb_dma_complete(void *args)
|
||||
{
|
||||
complete(&tegra_apb_wait);
|
||||
}
|
||||
|
||||
static int do_dma_transfer(unsigned long apb_add,
|
||||
enum dma_transfer_direction dir)
|
||||
{
|
||||
struct dma_async_tx_descriptor *dma_desc;
|
||||
int ret;
|
||||
|
||||
if (dir == DMA_DEV_TO_MEM)
|
||||
dma_sconfig.src_addr = apb_add;
|
||||
else
|
||||
dma_sconfig.dst_addr = apb_add;
|
||||
|
||||
ret = dmaengine_slave_config(tegra_apb_dma_chan, &dma_sconfig);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dma_desc = dmaengine_prep_slave_single(tegra_apb_dma_chan,
|
||||
tegra_apb_bb_phys, sizeof(u32), dir,
|
||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
if (!dma_desc)
|
||||
return -EINVAL;
|
||||
|
||||
dma_desc->callback = apb_dma_complete;
|
||||
dma_desc->callback_param = NULL;
|
||||
|
||||
reinit_completion(&tegra_apb_wait);
|
||||
|
||||
dmaengine_submit(dma_desc);
|
||||
dma_async_issue_pending(tegra_apb_dma_chan);
|
||||
ret = wait_for_completion_timeout(&tegra_apb_wait,
|
||||
msecs_to_jiffies(50));
|
||||
|
||||
if (WARN(ret == 0, "apb read dma timed out")) {
|
||||
dmaengine_terminate_all(tegra_apb_dma_chan);
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 tegra_apb_readl_using_dma(unsigned long offset)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
|
||||
return tegra_apb_readl_direct(offset);
|
||||
|
||||
mutex_lock(&tegra_apb_dma_lock);
|
||||
ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);
|
||||
if (ret < 0) {
|
||||
pr_err("error in reading offset 0x%08lx using dma\n", offset);
|
||||
*(u32 *)tegra_apb_bb = 0;
|
||||
}
|
||||
mutex_unlock(&tegra_apb_dma_lock);
|
||||
return *((u32 *)tegra_apb_bb);
|
||||
}
|
||||
|
||||
static void tegra_apb_writel_using_dma(u32 value, unsigned long offset)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!tegra_apb_dma_chan && !tegra_apb_dma_init()) {
|
||||
tegra_apb_writel_direct(value, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&tegra_apb_dma_lock);
|
||||
*((u32 *)tegra_apb_bb) = value;
|
||||
ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);
|
||||
if (ret < 0)
|
||||
pr_err("error in writing offset 0x%08lx using dma\n", offset);
|
||||
mutex_unlock(&tegra_apb_dma_lock);
|
||||
}
|
||||
#else
|
||||
#define tegra_apb_readl_using_dma tegra_apb_readl_direct
|
||||
#define tegra_apb_writel_using_dma tegra_apb_writel_direct
|
||||
#endif
|
||||
|
||||
typedef u32 (*apbio_read_fptr)(unsigned long offset);
|
||||
typedef void (*apbio_write_fptr)(u32 value, unsigned long offset);
|
||||
|
||||
static apbio_read_fptr apbio_read;
|
||||
static apbio_write_fptr apbio_write;
|
||||
|
||||
static u32 tegra_apb_readl_direct(unsigned long offset)
|
||||
{
|
||||
return readl(IO_ADDRESS(offset));
|
||||
}
|
||||
|
||||
static void tegra_apb_writel_direct(u32 value, unsigned long offset)
|
||||
{
|
||||
writel(value, IO_ADDRESS(offset));
|
||||
}
|
||||
|
||||
void tegra_apb_io_init(void)
|
||||
{
|
||||
/* Need to use dma only when it is Tegra20 based platform */
|
||||
if (of_machine_is_compatible("nvidia,tegra20") ||
|
||||
!of_have_populated_dt()) {
|
||||
apbio_read = tegra_apb_readl_using_dma;
|
||||
apbio_write = tegra_apb_writel_using_dma;
|
||||
} else {
|
||||
apbio_read = tegra_apb_readl_direct;
|
||||
apbio_write = tegra_apb_writel_direct;
|
||||
}
|
||||
}
|
||||
|
||||
u32 tegra_apb_readl(unsigned long offset)
|
||||
{
|
||||
return apbio_read(offset);
|
||||
}
|
||||
|
||||
void tegra_apb_writel(u32 value, unsigned long offset)
|
||||
{
|
||||
apbio_write(value, offset);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 NVIDIA Corporation.
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_TEGRA_APBIO_H
|
||||
#define __MACH_TEGRA_APBIO_H
|
||||
|
||||
void tegra_apb_io_init(void);
|
||||
u32 tegra_apb_readl(unsigned long offset);
|
||||
void tegra_apb_writel(u32 value, unsigned long offset);
|
||||
#endif
|
||||
@@ -17,9 +17,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rfkill-gpio.h>
|
||||
|
||||
#include "board.h"
|
||||
|
||||
static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = {
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
#include "pm.h"
|
||||
#include "sleep.h"
|
||||
|
||||
@@ -19,23 +19,23 @@
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/proc-fns.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
#include "pm.h"
|
||||
#include "sleep.h"
|
||||
#include "flowctrl.h"
|
||||
#include "iomap.h"
|
||||
#include "irq.h"
|
||||
#include "flowctrl.h"
|
||||
#include "pm.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static bool abort_flag;
|
||||
|
||||
@@ -19,17 +19,17 @@
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/proc-fns.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
#include "pm.h"
|
||||
#include "sleep.h"
|
||||
|
||||
@@ -24,12 +24,13 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "fuse.h"
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
||||
#include "cpuidle.h"
|
||||
|
||||
void __init tegra_cpuidle_init(void)
|
||||
{
|
||||
switch (tegra_chip_id) {
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA20:
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
|
||||
tegra20_cpuidle_init();
|
||||
@@ -49,7 +50,7 @@ void __init tegra_cpuidle_init(void)
|
||||
|
||||
void tegra_cpuidle_pcie_irqs_in_use(void)
|
||||
{
|
||||
switch (tegra_chip_id) {
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA20:
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
|
||||
tegra20_cpuidle_pcie_irqs_in_use();
|
||||
|
||||
@@ -18,14 +18,15 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
||||
#include "flowctrl.h"
|
||||
#include "iomap.h"
|
||||
#include "fuse.h"
|
||||
|
||||
static u8 flowctrl_offset_halt_cpu[] = {
|
||||
FLOW_CTRL_HALT_CPU0_EVENTS,
|
||||
@@ -76,7 +77,7 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
|
||||
int i;
|
||||
|
||||
reg = flowctrl_read_cpu_csr(cpuid);
|
||||
switch (tegra_chip_id) {
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA20:
|
||||
/* clear wfe bitmap */
|
||||
reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
|
||||
@@ -117,7 +118,7 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)
|
||||
|
||||
/* Disable powergating via flow controller for CPU0 */
|
||||
reg = flowctrl_read_cpu_csr(cpuid);
|
||||
switch (tegra_chip_id) {
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA20:
|
||||
/* clear wfe bitmap */
|
||||
reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* arch/arm/mach-tegra/fuse.c
|
||||
*
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Author:
|
||||
* Colin Cross <ccross@android.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/tegra-soc.h>
|
||||
|
||||
#include "fuse.h"
|
||||
#include "iomap.h"
|
||||
#include "apbio.h"
|
||||
|
||||
/* Tegra20 only */
|
||||
#define FUSE_UID_LOW 0x108
|
||||
#define FUSE_UID_HIGH 0x10c
|
||||
|
||||
/* Tegra30 and later */
|
||||
#define FUSE_VENDOR_CODE 0x200
|
||||
#define FUSE_FAB_CODE 0x204
|
||||
#define FUSE_LOT_CODE_0 0x208
|
||||
#define FUSE_LOT_CODE_1 0x20c
|
||||
#define FUSE_WAFER_ID 0x210
|
||||
#define FUSE_X_COORDINATE 0x214
|
||||
#define FUSE_Y_COORDINATE 0x218
|
||||
|
||||
#define FUSE_SKU_INFO 0x110
|
||||
|
||||
#define TEGRA20_FUSE_SPARE_BIT 0x200
|
||||
#define TEGRA30_FUSE_SPARE_BIT 0x244
|
||||
|
||||
int tegra_sku_id;
|
||||
int tegra_cpu_process_id;
|
||||
int tegra_core_process_id;
|
||||
int tegra_chip_id;
|
||||
int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
|
||||
int tegra_soc_speedo_id;
|
||||
enum tegra_revision tegra_revision;
|
||||
|
||||
static struct clk *fuse_clk;
|
||||
static int tegra_fuse_spare_bit;
|
||||
static void (*tegra_init_speedo_data)(void);
|
||||
|
||||
/* The BCT to use at boot is specified by board straps that can be read
|
||||
* through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
|
||||
*/
|
||||
int tegra_bct_strapping;
|
||||
|
||||
#define STRAP_OPT 0x008
|
||||
#define GMI_AD0 (1 << 4)
|
||||
#define GMI_AD1 (1 << 5)
|
||||
#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
|
||||
#define RAM_CODE_SHIFT 4
|
||||
|
||||
static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
|
||||
[TEGRA_REVISION_UNKNOWN] = "unknown",
|
||||
[TEGRA_REVISION_A01] = "A01",
|
||||
[TEGRA_REVISION_A02] = "A02",
|
||||
[TEGRA_REVISION_A03] = "A03",
|
||||
[TEGRA_REVISION_A03p] = "A03 prime",
|
||||
[TEGRA_REVISION_A04] = "A04",
|
||||
};
|
||||
|
||||
static void tegra_fuse_enable_clk(void)
|
||||
{
|
||||
if (IS_ERR(fuse_clk))
|
||||
fuse_clk = clk_get_sys(NULL, "fuse");
|
||||
if (IS_ERR(fuse_clk))
|
||||
return;
|
||||
clk_prepare_enable(fuse_clk);
|
||||
}
|
||||
|
||||
static void tegra_fuse_disable_clk(void)
|
||||
{
|
||||
if (IS_ERR(fuse_clk))
|
||||
return;
|
||||
clk_disable_unprepare(fuse_clk);
|
||||
}
|
||||
|
||||
u32 tegra_fuse_readl(unsigned long offset)
|
||||
{
|
||||
return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
|
||||
}
|
||||
|
||||
bool tegra_spare_fuse(int bit)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
tegra_fuse_enable_clk();
|
||||
|
||||
ret = tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);
|
||||
|
||||
tegra_fuse_disable_clk();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum tegra_revision tegra_get_revision(u32 id)
|
||||
{
|
||||
u32 minor_rev = (id >> 16) & 0xf;
|
||||
|
||||
switch (minor_rev) {
|
||||
case 1:
|
||||
return TEGRA_REVISION_A01;
|
||||
case 2:
|
||||
return TEGRA_REVISION_A02;
|
||||
case 3:
|
||||
if (tegra_chip_id == TEGRA20 &&
|
||||
(tegra_spare_fuse(18) || tegra_spare_fuse(19)))
|
||||
return TEGRA_REVISION_A03p;
|
||||
else
|
||||
return TEGRA_REVISION_A03;
|
||||
case 4:
|
||||
return TEGRA_REVISION_A04;
|
||||
default:
|
||||
return TEGRA_REVISION_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void tegra_get_process_id(void)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
tegra_fuse_enable_clk();
|
||||
|
||||
reg = tegra_fuse_readl(tegra_fuse_spare_bit);
|
||||
tegra_cpu_process_id = (reg >> 6) & 3;
|
||||
reg = tegra_fuse_readl(tegra_fuse_spare_bit);
|
||||
tegra_core_process_id = (reg >> 12) & 3;
|
||||
|
||||
tegra_fuse_disable_clk();
|
||||
}
|
||||
|
||||
u32 tegra_read_chipid(void)
|
||||
{
|
||||
return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
|
||||
}
|
||||
|
||||
static void __init tegra20_fuse_init_randomness(void)
|
||||
{
|
||||
u32 randomness[2];
|
||||
|
||||
randomness[0] = tegra_fuse_readl(FUSE_UID_LOW);
|
||||
randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH);
|
||||
|
||||
add_device_randomness(randomness, sizeof(randomness));
|
||||
}
|
||||
|
||||
/* Applies to Tegra30 or later */
|
||||
static void __init tegra30_fuse_init_randomness(void)
|
||||
{
|
||||
u32 randomness[7];
|
||||
|
||||
randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE);
|
||||
randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE);
|
||||
randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0);
|
||||
randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1);
|
||||
randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID);
|
||||
randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE);
|
||||
randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE);
|
||||
|
||||
add_device_randomness(randomness, sizeof(randomness));
|
||||
}
|
||||
|
||||
void __init tegra_init_fuse(void)
|
||||
{
|
||||
u32 id;
|
||||
u32 randomness[5];
|
||||
|
||||
u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
|
||||
reg |= 1 << 28;
|
||||
writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
|
||||
|
||||
/*
|
||||
* Enable FUSE clock. This needs to be hardcoded because the clock
|
||||
* subsystem is not active during early boot.
|
||||
*/
|
||||
reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
|
||||
reg |= 1 << 7;
|
||||
writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
|
||||
fuse_clk = ERR_PTR(-EINVAL);
|
||||
|
||||
reg = tegra_fuse_readl(FUSE_SKU_INFO);
|
||||
randomness[0] = reg;
|
||||
tegra_sku_id = reg & 0xFF;
|
||||
|
||||
reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
|
||||
randomness[1] = reg;
|
||||
tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
|
||||
|
||||
id = tegra_read_chipid();
|
||||
randomness[2] = id;
|
||||
tegra_chip_id = (id >> 8) & 0xff;
|
||||
|
||||
switch (tegra_chip_id) {
|
||||
case TEGRA20:
|
||||
tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
|
||||
tegra_init_speedo_data = &tegra20_init_speedo_data;
|
||||
break;
|
||||
case TEGRA30:
|
||||
tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
|
||||
tegra_init_speedo_data = &tegra30_init_speedo_data;
|
||||
break;
|
||||
case TEGRA114:
|
||||
tegra_init_speedo_data = &tegra114_init_speedo_data;
|
||||
break;
|
||||
default:
|
||||
pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
|
||||
tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
|
||||
tegra_init_speedo_data = &tegra_get_process_id;
|
||||
}
|
||||
|
||||
tegra_revision = tegra_get_revision(id);
|
||||
tegra_init_speedo_data();
|
||||
randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id;
|
||||
randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id;
|
||||
|
||||
add_device_randomness(randomness, sizeof(randomness));
|
||||
switch (tegra_chip_id) {
|
||||
case TEGRA20:
|
||||
tegra20_fuse_init_randomness();
|
||||
break;
|
||||
case TEGRA30:
|
||||
case TEGRA114:
|
||||
default:
|
||||
tegra30_fuse_init_randomness();
|
||||
break;
|
||||
}
|
||||
|
||||
pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
|
||||
tegra_revision_name[tegra_revision],
|
||||
tegra_sku_id, tegra_cpu_process_id,
|
||||
tegra_core_process_id);
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Author:
|
||||
* Colin Cross <ccross@android.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_TEGRA_FUSE_H
|
||||
#define __MACH_TEGRA_FUSE_H
|
||||
|
||||
#define SKU_ID_T20 8
|
||||
#define SKU_ID_T25SE 20
|
||||
#define SKU_ID_AP25 23
|
||||
#define SKU_ID_T25 24
|
||||
#define SKU_ID_AP25E 27
|
||||
#define SKU_ID_T25E 28
|
||||
|
||||
#define TEGRA20 0x20
|
||||
#define TEGRA30 0x30
|
||||
#define TEGRA114 0x35
|
||||
#define TEGRA124 0x40
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
enum tegra_revision {
|
||||
TEGRA_REVISION_UNKNOWN = 0,
|
||||
TEGRA_REVISION_A01,
|
||||
TEGRA_REVISION_A02,
|
||||
TEGRA_REVISION_A03,
|
||||
TEGRA_REVISION_A03p,
|
||||
TEGRA_REVISION_A04,
|
||||
TEGRA_REVISION_MAX,
|
||||
};
|
||||
|
||||
extern int tegra_sku_id;
|
||||
extern int tegra_cpu_process_id;
|
||||
extern int tegra_core_process_id;
|
||||
extern int tegra_chip_id;
|
||||
extern int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
|
||||
extern int tegra_soc_speedo_id;
|
||||
extern enum tegra_revision tegra_revision;
|
||||
|
||||
extern int tegra_bct_strapping;
|
||||
|
||||
unsigned long long tegra_chip_uid(void);
|
||||
void tegra_init_fuse(void);
|
||||
bool tegra_spare_fuse(int bit);
|
||||
u32 tegra_fuse_readl(unsigned long offset);
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
void tegra20_init_speedo_data(void);
|
||||
#else
|
||||
static inline void tegra20_init_speedo_data(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
|
||||
void tegra30_init_speedo_data(void);
|
||||
#else
|
||||
static inline void tegra30_init_speedo_data(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_114_SOC
|
||||
void tegra114_init_speedo_data(void);
|
||||
#else
|
||||
static inline void tegra114_init_speedo_data(void) {}
|
||||
#endif
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
@@ -7,13 +7,15 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/clk/tegra.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
#include "fuse.h"
|
||||
#include "sleep.h"
|
||||
|
||||
static void (*tegra_hotplug_shutdown)(void);
|
||||
@@ -51,12 +53,12 @@ void __init tegra_hotplug_init(void)
|
||||
if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
|
||||
return;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)
|
||||
tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)
|
||||
tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)
|
||||
tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124)
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)
|
||||
tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "iomap.h"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user