提交 2e568f56 编写于 作者: O Olof Johansson

Merge tag 'tegra-for-3.20-arm64' of...

Merge tag 'tegra-for-3.20-arm64' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/arm64

Merge "arm64: Add initial Tegra support" from Thierry Reding:

This adds support for the Tegra132 SoC, which is essentially a Tegra124
with a dual Denver CPU complex instead of the quad-Cortex-A15. There is
not much here, only the Kconfig entries, but it will allow us to more
easily get subsequent patches in (many of which have already been sent
for review).

* tag 'tegra-for-3.20-arm64' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  arm64: Add Tegra132 support
  soc: tegra: Add thermal reset (thermtrip) support to PMC
  ARM: tegra: Add PMC thermtrip programming to Jetson TK1 device tree
  of: Add descriptions of thermtrip properties to Tegra PMC bindings
  soc/tegra: pmc: Add Tegra132 support
  soc/tegra: fuse: Add Tegra132 support
  soc/tegra: fuse: Constify tegra_fuse_info structures
  soc/tegra: Add Tegra132 support
  clocksource: Build Tegra timer on 32-bit ARM only
  soc/tegra: pmc: restrict compilation of suspend-related support to ARM
Signed-off-by: NOlof Johansson <olof@lixom.net>
......@@ -47,6 +47,23 @@ Required properties when nvidia,suspend-mode=<0>:
sleep mode, the warm boot code will restore some PLLs, clocks and then
bring up CPU0 for resuming the system.
Hardware-triggered thermal reset:
On Tegra30, Tegra114 and Tegra124, if the 'i2c-thermtrip' subnode exists,
hardware-triggered thermal reset will be enabled.
Required properties for hardware-triggered thermal reset (inside 'i2c-thermtrip'):
- nvidia,i2c-controller-id : ID of I2C controller to send poweroff command to. Valid values are
described in section 9.2.148 "APBDEV_PMC_SCRATCH53_0" of the
Tegra K1 Technical Reference Manual.
- nvidia,bus-addr : Bus address of the PMU on the I2C bus
- nvidia,reg-addr : I2C register address to write poweroff command to
- nvidia,reg-data : Poweroff command to write to PMU
Optional properties for hardware-triggered thermal reset (inside 'i2c-thermtrip'):
- nvidia,pinmux-id : Pinmux used by the hardware when issuing poweroff command.
Defaults to 0. Valid values are described in section 12.5.2
"Pinmux Support" of the Tegra4 Technical Reference Manual.
Example:
/ SoC dts including file
......@@ -68,6 +85,15 @@ pmc@7000f400 {
/ Tegra board dts file
{
...
pmc@7000f400 {
i2c-thermtrip {
nvidia,i2c-controller-id = <4>;
nvidia,bus-addr = <0x40>;
nvidia,reg-addr = <0x36>;
nvidia,reg-data = <0x2>;
};
};
...
clocks {
compatible = "simple-bus";
......
......@@ -1673,6 +1673,13 @@
nvidia,core-pwr-off-time = <61036>;
nvidia,core-power-req-active-high;
nvidia,sys-clock-req-active-high;
i2c-thermtrip {
nvidia,i2c-controller-id = <4>;
nvidia,bus-addr = <0x40>;
nvidia,reg-addr = <0x36>;
nvidia,reg-data = <0x2>;
};
};
/* Serial ATA */
......
......@@ -27,6 +27,7 @@ config ARCH_TEGRA_2x_SOC
select PINCTRL_TEGRA20
select PL310_ERRATA_727915 if CACHE_L2X0
select PL310_ERRATA_769419 if CACHE_L2X0
select TEGRA_TIMER
help
Support for NVIDIA Tegra AP20 and T20 processors, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
......@@ -37,6 +38,7 @@ config ARCH_TEGRA_3x_SOC
select ARM_ERRATA_764369 if SMP
select PINCTRL_TEGRA30
select PL310_ERRATA_769419 if CACHE_L2X0
select TEGRA_TIMER
help
Support for NVIDIA Tegra T30 processor family, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
......@@ -47,6 +49,7 @@ config ARCH_TEGRA_114_SOC
select ARM_L1_CACHE_SHIFT_6
select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA114
select TEGRA_TIMER
help
Support for NVIDIA Tegra T114 processor family, based on the
ARM CortexA15MP CPU
......@@ -56,6 +59,7 @@ config ARCH_TEGRA_124_SOC
select ARM_L1_CACHE_SHIFT_6
select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA124
select TEGRA_TIMER
help
Support for NVIDIA Tegra T124 processor family, based on the
ARM CortexA15MP CPU
......
......@@ -170,6 +170,34 @@ config ARCH_SEATTLE
help
This enables support for AMD Seattle SOC Family
config ARCH_TEGRA
bool "NVIDIA Tegra SoC Family"
select ARCH_HAS_RESET_CONTROLLER
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
select CLKSRC_MMIO
select CLKSRC_OF
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select HAVE_SMP
select PINCTRL
select RESET_CONTROLLER
help
This enables support for the NVIDIA Tegra SoC family.
config ARCH_TEGRA_132_SOC
bool "NVIDIA Tegra132 SoC"
depends on ARCH_TEGRA
select PINCTRL_TEGRA124
select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB_PHY
select USB_ULPI_VIEWPORT if USB_PHY
help
Enable support for NVIDIA Tegra132 SoC, based on the Denver
ARMv8 CPU. The Tegra132 SoC is similar to the Tegra124 SoC,
but contains an NVIDIA Denver CPU complex in place of
Tegra124's "4+1" Cortex-A15 CPU complex.
config ARCH_THUNDER
bool "Cavium Inc. Thunder SoC Family"
help
......
......@@ -47,6 +47,9 @@ config SUN5I_HSTIMER
select CLKSRC_MMIO
bool
config TEGRA_TIMER
bool
config VT8500_TIMER
bool
......
......@@ -27,7 +27,7 @@ obj-$(CONFIG_ARCH_U300) += timer-u300.o
obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o
obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o
obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o
obj-$(CONFIG_TEGRA_TIMER) += tegra20_timer.o
obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o
obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o
obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o
......
......@@ -81,6 +81,7 @@ static const struct of_device_id car_match[] __initconst = {
{ .compatible = "nvidia,tegra30-car", },
{ .compatible = "nvidia,tegra114-car", },
{ .compatible = "nvidia,tegra124-car", },
{ .compatible = "nvidia,tegra132-car", },
{},
};
......
......@@ -56,7 +56,7 @@ struct tegra_fuse_info {
static void __iomem *fuse_base;
static struct clk *fuse_clk;
static struct tegra_fuse_info *fuse_info;
static const struct tegra_fuse_info *fuse_info;
u32 tegra30_fuse_readl(const unsigned int offset)
{
......@@ -78,18 +78,18 @@ u32 tegra30_fuse_readl(const unsigned int offset)
return val;
}
static struct tegra_fuse_info tegra30_info = {
static const struct tegra_fuse_info tegra30_info = {
.size = 0x2a4,
.spare_bit = 0x144,
.speedo_idx = SPEEDO_TEGRA30,
};
static struct tegra_fuse_info tegra114_info = {
static const struct tegra_fuse_info tegra114_info = {
.size = 0x2a0,
.speedo_idx = SPEEDO_TEGRA114,
};
static struct tegra_fuse_info tegra124_info = {
static const struct tegra_fuse_info tegra124_info = {
.size = 0x300,
.speedo_idx = SPEEDO_TEGRA124,
};
......@@ -182,6 +182,7 @@ static void __init legacy_fuse_init(void)
fuse_info = &tegra114_info;
break;
case TEGRA124:
case TEGRA132:
fuse_info = &tegra124_info;
break;
default:
......
......@@ -70,6 +70,10 @@
#define PMC_SCRATCH41 0x140
#define PMC_SENSOR_CTRL 0x1b0
#define PMC_SENSOR_CTRL_SCRATCH_WRITE (1 << 2)
#define PMC_SENSOR_CTRL_ENABLE_RST (1 << 1)
#define IO_DPD_REQ 0x1b8
#define IO_DPD_REQ_CODE_IDLE (0 << 30)
#define IO_DPD_REQ_CODE_OFF (1 << 30)
......@@ -81,6 +85,18 @@
#define IO_DPD2_STATUS 0x1c4
#define SEL_DPD_TIM 0x1c8
#define PMC_SCRATCH54 0x258
#define PMC_SCRATCH54_DATA_SHIFT 8
#define PMC_SCRATCH54_ADDR_SHIFT 0
#define PMC_SCRATCH55 0x25c
#define PMC_SCRATCH55_RESET_TEGRA (1 << 31)
#define PMC_SCRATCH55_CNTRL_ID_SHIFT 27
#define PMC_SCRATCH55_PINMUX_SHIFT 24
#define PMC_SCRATCH55_16BITOP (1 << 15)
#define PMC_SCRATCH55_CHECKSUM_SHIFT 16
#define PMC_SCRATCH55_I2CSLV1_SHIFT 0
#define GPU_RG_CNTRL 0x2d4
struct tegra_pmc_soc {
......@@ -88,6 +104,9 @@ struct tegra_pmc_soc {
const char *const *powergates;
unsigned int num_cpu_powergates;
const u8 *cpu_powergates;
bool has_tsense_reset;
bool has_gpu_clamps;
};
/**
......@@ -110,6 +129,7 @@ struct tegra_pmc_soc {
* @powergates_lock: mutex for power gate register access
*/
struct tegra_pmc {
struct device *dev;
void __iomem *base;
struct clk *clk;
......@@ -225,11 +245,11 @@ int tegra_powergate_remove_clamping(int id)
return -EINVAL;
/*
* The Tegra124 GPU has a separate register (with different semantics)
* to remove clamps.
* On Tegra124 and later, the clamps for the GPU are controlled by a
* separate register (with different semantics).
*/
if (tegra_get_chip_id() == TEGRA124) {
if (id == TEGRA_POWERGATE_3D) {
if (id == TEGRA_POWERGATE_3D) {
if (pmc->soc->has_gpu_clamps) {
tegra_pmc_writel(0, GPU_RG_CNTRL);
return 0;
}
......@@ -703,6 +723,83 @@ static void tegra_pmc_init(struct tegra_pmc *pmc)
tegra_pmc_writel(value, PMC_CNTRL);
}
void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
{
static const char disabled[] = "emergency thermal reset disabled";
u32 pmu_addr, ctrl_id, reg_addr, reg_data, pinmux;
struct device *dev = pmc->dev;
struct device_node *np;
u32 value, checksum;
if (!pmc->soc->has_tsense_reset)
goto out;
np = of_find_node_by_name(pmc->dev->of_node, "i2c-thermtrip");
if (!np) {
dev_warn(dev, "i2c-thermtrip node not found, %s.\n", disabled);
goto out;
}
if (of_property_read_u32(np, "nvidia,i2c-controller-id", &ctrl_id)) {
dev_err(dev, "I2C controller ID missing, %s.\n", disabled);
goto out;
}
if (of_property_read_u32(np, "nvidia,bus-addr", &pmu_addr)) {
dev_err(dev, "nvidia,bus-addr missing, %s.\n", disabled);
goto out;
}
if (of_property_read_u32(np, "nvidia,reg-addr", &reg_addr)) {
dev_err(dev, "nvidia,reg-addr missing, %s.\n", disabled);
goto out;
}
if (of_property_read_u32(np, "nvidia,reg-data", &reg_data)) {
dev_err(dev, "nvidia,reg-data missing, %s.\n", disabled);
goto out;
}
if (of_property_read_u32(np, "nvidia,pinmux-id", &pinmux))
pinmux = 0;
value = tegra_pmc_readl(PMC_SENSOR_CTRL);
value |= PMC_SENSOR_CTRL_SCRATCH_WRITE;
tegra_pmc_writel(value, PMC_SENSOR_CTRL);
value = (reg_data << PMC_SCRATCH54_DATA_SHIFT) |
(reg_addr << PMC_SCRATCH54_ADDR_SHIFT);
tegra_pmc_writel(value, PMC_SCRATCH54);
value = PMC_SCRATCH55_RESET_TEGRA;
value |= ctrl_id << PMC_SCRATCH55_CNTRL_ID_SHIFT;
value |= pinmux << PMC_SCRATCH55_PINMUX_SHIFT;
value |= pmu_addr << PMC_SCRATCH55_I2CSLV1_SHIFT;
/*
* Calculate checksum of SCRATCH54, SCRATCH55 fields. Bits 23:16 will
* contain the checksum and are currently zero, so they are not added.
*/
checksum = reg_addr + reg_data + (value & 0xff) + ((value >> 8) & 0xff)
+ ((value >> 24) & 0xff);
checksum &= 0xff;
checksum = 0x100 - checksum;
value |= checksum << PMC_SCRATCH55_CHECKSUM_SHIFT;
tegra_pmc_writel(value, PMC_SCRATCH55);
value = tegra_pmc_readl(PMC_SENSOR_CTRL);
value |= PMC_SENSOR_CTRL_ENABLE_RST;
tegra_pmc_writel(value, PMC_SENSOR_CTRL);
dev_info(pmc->dev, "emergency thermal reset enabled\n");
out:
of_node_put(np);
return;
}
static int tegra_pmc_probe(struct platform_device *pdev)
{
void __iomem *base = pmc->base;
......@@ -728,8 +825,12 @@ static int tegra_pmc_probe(struct platform_device *pdev)
return err;
}
pmc->dev = &pdev->dev;
tegra_pmc_init(pmc);
tegra_pmc_init_tsense_reset(pmc);
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
err = tegra_powergate_debugfs_init();
if (err < 0)
......@@ -739,7 +840,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM_SLEEP
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
static int tegra_pmc_suspend(struct device *dev)
{
tegra_pmc_writel(virt_to_phys(tegra_resume), PMC_SCRATCH41);
......@@ -753,10 +854,11 @@ static int tegra_pmc_resume(struct device *dev)
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(tegra_pmc_pm_ops, tegra_pmc_suspend, tegra_pmc_resume);
#endif
static const char * const tegra20_powergates[] = {
[TEGRA_POWERGATE_CPU] = "cpu",
[TEGRA_POWERGATE_3D] = "3d",
......@@ -772,6 +874,8 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.powergates = tegra20_powergates,
.num_cpu_powergates = 0,
.cpu_powergates = NULL,
.has_tsense_reset = false,
.has_gpu_clamps = false,
};
static const char * const tegra30_powergates[] = {
......@@ -803,6 +907,8 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.powergates = tegra30_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
.cpu_powergates = tegra30_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = false,
};
static const char * const tegra114_powergates[] = {
......@@ -838,6 +944,8 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.powergates = tegra114_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates),
.cpu_powergates = tegra114_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = false,
};
static const char * const tegra124_powergates[] = {
......@@ -879,6 +987,8 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.powergates = tegra124_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates),
.cpu_powergates = tegra124_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = true,
};
static const struct of_device_id tegra_pmc_match[] = {
......@@ -894,7 +1004,9 @@ static struct platform_driver tegra_pmc_driver = {
.name = "tegra-pmc",
.suppress_bind_attrs = true,
.of_match_table = tegra_pmc_match,
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
.pm = &tegra_pmc_pm_ops,
#endif
},
.probe = tegra_pmc_probe,
};
......
......@@ -21,6 +21,7 @@
#define TEGRA30 0x30
#define TEGRA114 0x35
#define TEGRA124 0x40
#define TEGRA132 0x13
#define TEGRA_FUSE_SKU_CALIB_0 0xf0
#define TEGRA30_FUSE_SATA_CALIB 0x124
......
......@@ -17,7 +17,7 @@ enum tegra_suspend_mode {
TEGRA_MAX_SUSPEND_MODE,
};
#ifdef CONFIG_PM_SLEEP
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
enum tegra_suspend_mode
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册