summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Walmsley <pwalmsley@nvidia.com>2014-03-14 16:06:05 -0700
committerDiwakar Tundlam <dtundlam@nvidia.com>2014-04-04 17:54:32 -0700
commit4f9d14cc1e330a0bda9b5b044d3241d4eeffe934 (patch)
tree230c5265975ae4f1edf89924f9ba68e124ef9cf0
parente59ade4c2b236c0366f58cc6b75d44748d6ceec3 (diff)
arm: tegra: soctherm: move PMC register accesses into PMC driver
The PMC IP block is not part of the SOC_THERM IP block, but the SOC_THERM code contains direct register reads and writes to the PMC IP block. Move these accesses into something PMC-specific: in this case, drivers/platform/tegra/pmc.c. While here, remove the usage of the REG_SET/GET* macros, since upstream Linux practice is to use the actual bit-manipulation operations, rather than these macros. This is part of the process of modifying the tegra11_soctherm.c code to convert it into a low-level device driver for the arsoc_therm IP block. We also relocate struct tegra_tsensor_pmu_data to a PMC-specific header file, since it is PMC-specific, and convert any header references to the old location to point to the new location. Thanks to Matt Longnecker for comments on the first version of this patch. Bug 1201644 Bug 1380438 Bug 1482001 Change-Id: Iea630ac9d9b3dfaab03edf44e2a2725174c7a3d8 Signed-off-by: Paul Walmsley <pwalmsley@nvidia.com> Cc: Diwakar Tundlam <dtundlam@nvidia.com> Cc: Matthew Longnecker <mlongnecker@nvidia.com> Reviewed-on: http://git-master/r/392198 Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com> Tested-by: Diwakar Tundlam <dtundlam@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board-ardbeg-power.c1
-rw-r--r--arch/arm/mach-tegra/board-dalmore-power.c2
-rw-r--r--arch/arm/mach-tegra/board-loki-power.c2
-rw-r--r--arch/arm/mach-tegra/board-macallan-power.c4
-rw-r--r--arch/arm/mach-tegra/board-norrin-power.c1
-rw-r--r--arch/arm/mach-tegra/board-pluto-power.c2
-rw-r--r--arch/arm/mach-tegra/board-roth-power.c4
-rw-r--r--arch/arm/mach-tegra/board-vcm30_t124-power.c2
-rw-r--r--arch/arm/mach-tegra/tegra11_soctherm.c77
-rw-r--r--arch/arm/mach-tegra/tegra3_tsensor.c6
-rw-r--r--arch/arm/mach-tegra/tegra3_tsensor.h46
-rw-r--r--drivers/platform/tegra/pmc.c122
-rw-r--r--include/linux/tegra-pmc.h49
13 files changed, 184 insertions, 134 deletions
diff --git a/arch/arm/mach-tegra/board-ardbeg-power.c b/arch/arm/mach-tegra/board-ardbeg-power.c
index d5f3e5ce34a5..4be005b7a152 100644
--- a/arch/arm/mach-tegra/board-ardbeg-power.c
+++ b/arch/arm/mach-tegra/board-ardbeg-power.c
@@ -53,7 +53,6 @@
#include "iomap.h"
#include "tegra_cl_dvfs.h"
#include "tegra11_soctherm.h"
-#include "tegra3_tsensor.h"
#define E1735_EMULATE_E1767_SKU 1001
diff --git a/arch/arm/mach-tegra/board-dalmore-power.c b/arch/arm/mach-tegra/board-dalmore-power.c
index c63403cc091d..28d685578d46 100644
--- a/arch/arm/mach-tegra/board-dalmore-power.c
+++ b/arch/arm/mach-tegra/board-dalmore-power.c
@@ -35,6 +35,7 @@
#include <linux/regulator/userspace-consumer.h>
#include <linux/pid_thermal_gov.h>
#include <linux/tegra-soc.h>
+#include <linux/tegra-pmc.h>
#include <asm/mach-types.h>
#include <linux/power/sbs-battery.h>
@@ -55,7 +56,6 @@
#include "devices.h"
#include "tegra11_soctherm.h"
#include "iomap.h"
-#include "tegra3_tsensor.h"
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
diff --git a/arch/arm/mach-tegra/board-loki-power.c b/arch/arm/mach-tegra/board-loki-power.c
index ff8c7ff2f961..d3e251decd22 100644
--- a/arch/arm/mach-tegra/board-loki-power.c
+++ b/arch/arm/mach-tegra/board-loki-power.c
@@ -29,6 +29,7 @@
#include <linux/regulator/tegra-dfll-bypass-regulator.h>
#include <linux/power/power_supply_extcon.h>
#include <linux/tegra-fuse.h>
+#include <linux/tegra-pmc.h>
#include <mach/irqs.h>
#include <mach/edp.h>
@@ -50,7 +51,6 @@
#include "dvfs.h"
#include "tegra_cl_dvfs.h"
#include "tegra11_soctherm.h"
-#include "tegra3_tsensor.h"
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
diff --git a/arch/arm/mach-tegra/board-macallan-power.c b/arch/arm/mach-tegra/board-macallan-power.c
index 30f1a188b319..b10d7ac803bb 100644
--- a/arch/arm/mach-tegra/board-macallan-power.c
+++ b/arch/arm/mach-tegra/board-macallan-power.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-macallan-power.c
*
- * Copyright (C) 2012-2013 NVIDIA Corporation. All rights reserved.
+ * Copyright (C) 2012-2014 NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,6 +34,7 @@
#include <linux/regulator/userspace-consumer.h>
#include <linux/pid_thermal_gov.h>
#include <linux/tegra-soc.h>
+#include <linux/tegra-pmc.h>
#include <asm/mach-types.h>
#include <linux/power/sbs-battery.h>
@@ -53,7 +54,6 @@
#include "tegra_cl_dvfs.h"
#include "devices.h"
#include "tegra11_soctherm.h"
-#include "tegra3_tsensor.h"
#include "iomap.h"
#include "battery-ini-model-data.h"
diff --git a/arch/arm/mach-tegra/board-norrin-power.c b/arch/arm/mach-tegra/board-norrin-power.c
index 2eedcbcc62db..f2812911d851 100644
--- a/arch/arm/mach-tegra/board-norrin-power.c
+++ b/arch/arm/mach-tegra/board-norrin-power.c
@@ -45,7 +45,6 @@
#include "devices.h"
#include "tegra11_soctherm.h"
#include "iomap.h"
-#include "tegra3_tsensor.h"
int __init norrin_as3722_regulator_init(void)
{
diff --git a/arch/arm/mach-tegra/board-pluto-power.c b/arch/arm/mach-tegra/board-pluto-power.c
index 4205446f9090..f8f4dae5532b 100644
--- a/arch/arm/mach-tegra/board-pluto-power.c
+++ b/arch/arm/mach-tegra/board-pluto-power.c
@@ -33,6 +33,7 @@
#include <linux/regulator/machine.h>
#include <linux/irq.h>
#include <linux/pid_thermal_gov.h>
+#include <linux/tegra-pmc.h>
#include <asm/mach-types.h>
@@ -46,7 +47,6 @@
#include "tegra_cl_dvfs.h"
#include "devices.h"
#include "tegra11_soctherm.h"
-#include "tegra3_tsensor.h"
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
diff --git a/arch/arm/mach-tegra/board-roth-power.c b/arch/arm/mach-tegra/board-roth-power.c
index a2144cb54bf9..ea2f75e76e71 100644
--- a/arch/arm/mach-tegra/board-roth-power.c
+++ b/arch/arm/mach-tegra/board-roth-power.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-roth-power.c
*
- * Copyright (c) 2012-2013 NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2012-2014 NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -33,6 +33,7 @@
#include <linux/gpio.h>
#include <linux/regulator/userspace-consumer.h>
#include <linux/tegra-soc.h>
+#include <linux/tegra-pmc.h>
#include <asm/mach-types.h>
@@ -51,7 +52,6 @@
#include "devices.h"
#include "tegra11_soctherm.h"
#include "iomap.h"
-#include "tegra3_tsensor.h"
#include "battery-ini-model-data.h"
#define PMC_CTRL 0x0
diff --git a/arch/arm/mach-tegra/board-vcm30_t124-power.c b/arch/arm/mach-tegra/board-vcm30_t124-power.c
index c6011fdac65c..df96af2cc0dc 100644
--- a/arch/arm/mach-tegra/board-vcm30_t124-power.c
+++ b/arch/arm/mach-tegra/board-vcm30_t124-power.c
@@ -22,6 +22,7 @@
#include <linux/regulator/max15569-regulator.h>
#include <linux/gpio.h>
#include <linux/i2c/pca953x.h>
+#include <linux/tegra-pmc.h>
#include <mach/edp.h>
@@ -33,7 +34,6 @@
#include "tegra_cl_dvfs.h"
#include "devices.h"
#include "tegra11_soctherm.h"
-#include "tegra3_tsensor.h"
#include <mach/board_id.h>
#define PMC_CTRL 0x0
diff --git a/arch/arm/mach-tegra/tegra11_soctherm.c b/arch/arm/mach-tegra/tegra11_soctherm.c
index 6111f0918374..ee8bfcfea1a8 100644
--- a/arch/arm/mach-tegra/tegra11_soctherm.c
+++ b/arch/arm/mach-tegra/tegra11_soctherm.c
@@ -38,10 +38,10 @@
#include <linux/platform_data/thermal_sensors.h>
#include <linux/bug.h>
#include <linux/tegra-fuse.h>
+#include <linux/tegra-pmc.h>
#include <linux/regulator/consumer.h>
#include "iomap.h"
-#include "tegra3_tsensor.h"
#include "tegra11_soctherm.h"
#include "gpio-names.h"
#include "common.h"
@@ -388,37 +388,6 @@ static const int precision; /* default 0 -> low precision */
#define CDIVG_DIVISOR_MASK 0xff
#define CDIVG_DIVISOR_SHIFT 0
-/* pmc register offsets needed for powering off PMU */
-#define PMC_SCRATCH_WRITE_SHIFT 2
-#define PMC_SCRATCH_WRITE_MASK 0x1
-#define PMC_ENABLE_RST_SHIFT 1
-#define PMC_ENABLE_RST_MASK 0x1
-#define PMC_SENSOR_CTRL 0x1B0
-#define PMC_SCRATCH54 0x258
-#define PMC_SCRATCH55 0x25C
-
-/* scratch54 register bit fields */
-#define PMU_OFF_DATA_SHIFT 8
-#define PMU_OFF_DATA_MASK 0xff
-#define PMU_OFF_ADDR_SHIFT 0
-#define PMU_OFF_ADDR_MASK 0xff
-
-/* scratch55 register bit fields */
-#define RESET_TEGRA_SHIFT 31
-#define RESET_TEGRA_MASK 0x1
-#define CONTROLLER_TYPE_SHIFT 30
-#define CONTROLLER_TYPE_MASK 0x1
-#define I2C_CONTROLLER_ID_SHIFT 27
-#define I2C_CONTROLLER_ID_MASK 0x7
-#define PINMUX_SHIFT 24
-#define PINMUX_MASK 0x7
-#define CHECKSUM_SHIFT 16
-#define CHECKSUM_MASK 0xff
-#define PMU_16BIT_SUPPORT_SHIFT 15
-#define PMU_16BIT_SUPPORT_MASK 0x1
-#define PMU_I2C_ADDRESS_SHIFT 0
-#define PMU_I2C_ADDRESS_MASK 0x7f
-
#define CAR_SUPER_CLK_DIVIDER_REGISTER() (IS_T13X ? \
CAR13_SUPER_CCLKG_DIVIDER : \
CAR_SUPER_CCLKG_DIVIDER)
@@ -478,7 +447,6 @@ static const int precision; /* default 0 -> low precision */
#define IS_T13X (tegra_chip_id == TEGRA_CHIPID_TEGRA13)
static void __iomem *reg_soctherm_base = IOMEM(IO_ADDRESS(TEGRA_SOCTHERM_BASE));
-static void __iomem *pmc_base = IOMEM(IO_ADDRESS(TEGRA_PMC_BASE));
static void __iomem *clk_reset_base = IOMEM(IO_ADDRESS(TEGRA_CLK_RESET_BASE));
static void __iomem *clk13_rst_base = IOMEM(IO_ADDRESS(TEGRA_CLK13_RESET_BASE));
@@ -549,17 +517,6 @@ static inline u32 throtctl_readl(u32 reg)
return soctherm_readl(reg);
}
-static inline void pmc_writel(u32 value, u32 reg)
-{
- __raw_writel(value, (void __iomem *)
- (pmc_base + reg));
-}
-
-static inline u32 pmc_readl(u32 reg)
-{
- return __raw_readl(pmc_base + reg);
-}
-
static inline void clk_reset_writel(u32 value, u32 reg)
{
if (IS_T13X) {
@@ -2648,39 +2605,11 @@ static int soctherm_fuse_read_tsensor(enum soctherm_sense sensor)
*/
static void soctherm_therm_trip_init(struct tegra_tsensor_pmu_data *data)
{
- u32 val, checksum;
-
if (!data)
return;
- /* enable therm trip at PMC */
- val = pmc_readl(PMC_SENSOR_CTRL);
- val = REG_SET(val, PMC_SCRATCH_WRITE, 0);
- val = REG_SET(val, PMC_ENABLE_RST, 1);
- pmc_writel(val, PMC_SENSOR_CTRL);
-
- /* Fill scratch registers to shutdown device on therm TRIP */
- val = REG_SET(0, PMU_OFF_DATA, data->poweroff_reg_data);
- val = REG_SET(val, PMU_OFF_ADDR, data->poweroff_reg_addr);
- pmc_writel(val, PMC_SCRATCH54);
-
- val = REG_SET(0, RESET_TEGRA, 1);
- val = REG_SET(val, CONTROLLER_TYPE, data->controller_type);
- val = REG_SET(val, I2C_CONTROLLER_ID, data->i2c_controller_id);
- val = REG_SET(val, PINMUX, data->pinmux);
- val = REG_SET(val, PMU_16BIT_SUPPORT, data->pmu_16bit_ops);
- val = REG_SET(val, PMU_I2C_ADDRESS, data->pmu_i2c_addr);
-
- checksum = data->poweroff_reg_addr +
- data->poweroff_reg_data +
- (val & 0xFF) +
- ((val >> 8) & 0xFF) +
- ((val >> 24) & 0xFF);
- checksum &= 0xFF;
- checksum = 0x100 - checksum;
-
- val = REG_SET(val, CHECKSUM, checksum);
- pmc_writel(val, PMC_SCRATCH55);
+ tegra_pmc_enable_thermal_trip();
+ tegra_pmc_config_thermal_trip(data);
}
/**
diff --git a/arch/arm/mach-tegra/tegra3_tsensor.c b/arch/arm/mach-tegra/tegra3_tsensor.c
index 9d3ee457402f..e8e2d119ede2 100644
--- a/arch/arm/mach-tegra/tegra3_tsensor.c
+++ b/arch/arm/mach-tegra/tegra3_tsensor.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/tegra3_tsensor.c
*
- * Copyright (C) 2011-2013, NVIDIA Corporation. All rights reserved.
+ * Copyright (C) 2011-2014, NVIDIA Corporation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -17,17 +17,15 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
-#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/tegra-fuse.h>
+#include <linux/tegra-pmc.h>
#include <mach/tsensor.h>
-#include <mach/tsensor.h>
#include "cpu-tegra.h"
#include "devices.h"
#include "iomap.h"
-#include "tegra3_tsensor.h"
/* fuse revision constants used for tsensor */
#define TSENSOR_FUSE_REVISION_DECIMAL 8
diff --git a/arch/arm/mach-tegra/tegra3_tsensor.h b/arch/arm/mach-tegra/tegra3_tsensor.h
index 29ddd786823c..b88c71a84020 100644
--- a/arch/arm/mach-tegra/tegra3_tsensor.h
+++ b/arch/arm/mach-tegra/tegra3_tsensor.h
@@ -19,52 +19,6 @@
#ifndef __MACH_TEGRA_TEGRA3_TSENSOR_H
#define __MACH_TEGRA_TEGRA3_TSENSOR_H
-
-/**
- * struct tegra_tsensor_pmu_data - PMIC temperature sensor
- * configuration
- * @poweroff_reg_data: The data to write to turn the system off
- * @poweroff_reg_addr: The PMU address of poweroff register
- * @reset_tegra: Flag indicating whether or not the system
- * will shutdown during a thermal trip.
- * @controller_type: If this field is set to 0, the PMIC is
- * connected via I2C. If it is set to 1,
- * it is connected via SPI. If it is set to
- * 2, it is connected via GPIO.
- * @i2c_controller_id: The i2c bus controller id
- * @pinmux: An array index used to configure which pins
- * on the chip are muxed to the I2C/SPI/GPIO
- * controller that is in use. Contact NVIDIA
- * for more information on what these index values
- * mean for a given chip.
- * @pmu_16bit_ops: If 0, sends three bytes from the PMC_SCRATCH54
- * register to the PMIC to turn it off; if 1, sends
- * four bytes from the PMC_SCRATCH54 register to the PMIC
- * to turn it off, plus one other byte. Must be set to
- * 0 - the current code does not support 16 bit
- * operations.
- * @pmu_i2c_addr: The address of the PMIC on the I2C bus
- *
- * When the temperature gets too high, the PMIC will power off the device
- * based on what is written to the PMIC registers.
- *
- * @poweroff_reg_data and @poweroff_reg_addr are written to the PMC SCRATCH54
- * register.
- *
- * @reset_tegra, @controller_type, @i2c_controller_id, @pinmux, @pmu_16bit_ops
- * and @pmu_i2c_addr are written to the PMC SCRATCH55 register.
- */
-struct tegra_tsensor_pmu_data {
- u8 poweroff_reg_data;
- u8 poweroff_reg_addr;
- u8 reset_tegra;
- u8 controller_type;
- u8 i2c_controller_id;
- u8 pinmux;
- u8 pmu_16bit_ops;
- u8 pmu_i2c_addr;
-};
-
#ifdef CONFIG_SENSORS_TEGRA_TSENSOR
void __init tegra3_tsensor_init(struct tegra_tsensor_pmu_data *data);
#else
diff --git a/drivers/platform/tegra/pmc.c b/drivers/platform/tegra/pmc.c
index 4a1c5f4c124f..c266f2b6614a 100644
--- a/drivers/platform/tegra/pmc.c
+++ b/drivers/platform/tegra/pmc.c
@@ -45,6 +45,37 @@
#define PMC_IO_DPD_REQ 0x1B8
#define PMC_IO_DPD2_REQ 0x1C0
+/* pmc register offsets needed for powering off PMU */
+#define PMC_SCRATCH_WRITE_SHIFT 2
+#define PMC_SCRATCH_WRITE_MASK BIT(2)
+#define PMC_ENABLE_RST_SHIFT 1
+#define PMC_ENABLE_RST_MASK BIT(1)
+#define PMC_SENSOR_CTRL 0x1B0
+#define PMC_SCRATCH54 0x258
+#define PMC_SCRATCH55 0x25C
+
+/* scratch54 register bit fields */
+#define PMU_OFF_DATA_SHIFT 8
+#define PMU_OFF_DATA_MASK 0xff
+#define PMU_OFF_ADDR_SHIFT 0
+#define PMU_OFF_ADDR_MASK 0xff
+
+/* scratch55 register bit fields */
+#define RESET_TEGRA_SHIFT 31
+#define RESET_TEGRA_MASK 0x1
+#define CONTROLLER_TYPE_SHIFT 30
+#define CONTROLLER_TYPE_MASK 0x1
+#define I2C_CONTROLLER_ID_SHIFT 27
+#define I2C_CONTROLLER_ID_MASK 0x7
+#define PINMUX_SHIFT 24
+#define PINMUX_MASK 0x7
+#define CHECKSUM_SHIFT 16
+#define CHECKSUM_MASK 0xff
+#define PMU_16BIT_SUPPORT_SHIFT 15
+#define PMU_16BIT_SUPPORT_MASK 0x1
+#define PMU_I2C_ADDRESS_SHIFT 0
+#define PMU_I2C_ADDRESS_MASK 0x7f
+
static u8 tegra_cpu_domains[] = {
0xFF, /* not available for CPU0 */
TEGRA_POWERGATE_CPU1,
@@ -87,6 +118,97 @@ static inline void tegra_pmc_writel(u32 val, u32 reg)
writel(val, tegra_pmc_base + reg);
}
+/**
+ * _compute_pmic_checksum - compute checksum for some PMC_SCRATCH regs
+ * @a: First half of the top PMC_SCRATCH register
+ * @b: Second half of the top PMC_SCRATCH register
+ * @v: Complete contents of the bottom PMC_SCRATCH register (except checksum)
+ *
+ * Compute a simple eight-bit checksum across two PMC_SCRATCH register
+ * values. There are two sets of two registers in the PMC scratch
+ * space, and they are intended to configure how the boot ROM reacts
+ * to certain exceptional cases (overtemperature and watchdog timer
+ * expiration). See the "Checksum Calculation" section in the "Boot
+ * Process" section of the Tegra K1 TRM for more details here.
+ * Originally intended for use with PMC_SCRATCH54/55. Returns the
+ * computed checksum byte.
+ */
+static u8 _compute_pmic_checksum(u32 a, u32 b, u32 v)
+{
+ u32 c;
+
+ c = a + b;
+ c += (v & 0xff) + ((v >> 8) & 0xff) + ((v >> 24) & 0xff);
+ c &= 0xff;
+ c = 0x100 - c;
+ c &= 0xff;
+
+ return c;
+}
+
+/**
+ * tegra_pmc_enable_thermal_trip - enable hardware-controlled thermal reset
+ *
+ * Configure the PMC to initiate a hardware reset when the SOC_THERM
+ * IP block detects a high temperature condition, and to allow us to
+ * write to the PMC scratch registers to store the PMIC shutdown
+ * command (in another function). No return value.
+ */
+void tegra_pmc_enable_thermal_trip(void)
+{
+ u32 val;
+
+ val = tegra_pmc_readl(PMC_SENSOR_CTRL);
+ val &= ~PMC_SCRATCH_WRITE_MASK;
+ val |= PMC_ENABLE_RST_MASK;
+ tegra_pmc_writel(val, PMC_SENSOR_CTRL);
+}
+EXPORT_SYMBOL(tegra_pmc_enable_thermal_trip);
+
+/**
+ * tegra_pmc_config_thermal_trip - set PMC_SCRATCH54/55 from parameters
+ * @poweroff_reg_data: What register value to write to the PMIC to power off
+ * @poweroff_reg_addr: The PMIC register address to write @poweroff_reg_data
+ * @controller_type: 0 for I2C, 1 for SPI, 2 for GPIO
+ * @i2c_controller_id: I2C controller ID
+ * @pinmux: pinmux configuration ID for the @controller_type pads
+ * @pmu_16bit_ops: Must be set to 0.
+ * @pmu_i2c_addr: I2C bus address of the PMIC to write to
+ *
+ * Configure the hardware thermal reset PMIC interaction functions of
+ * the Tegra SoC. More information on the argument values can be
+ * found in include/linux/tegra-pmc.h. No return value.
+ *
+ * XXX This function does no input validation, but it should.
+ * XXX This function should read back the values that it programs into the
+ * PMIC scratch registers to ensure that the writes weren't blocked by
+ * the BLOCK_SCRATCH_WRITES hardware mechanism.
+ */
+void tegra_pmc_config_thermal_trip(struct tegra_tsensor_pmu_data *data)
+{
+ u32 v = 0;
+ u32 c;
+
+ /* Fill scratch registers to shutdown device on therm TRIP */
+ v = data->poweroff_reg_data << PMU_OFF_DATA_SHIFT;
+ v |= data->poweroff_reg_addr << PMU_OFF_ADDR_SHIFT;
+ tegra_pmc_writel(v, PMC_SCRATCH54);
+
+ v = 1 << RESET_TEGRA_SHIFT;
+ v |= data->controller_type << CONTROLLER_TYPE_SHIFT;
+ v |= data->i2c_controller_id << I2C_CONTROLLER_ID_SHIFT;
+ v |= data->pinmux << PINMUX_SHIFT;
+ v |= data->pmu_16bit_ops << PMU_16BIT_SUPPORT_SHIFT;
+ v |= data->pmu_i2c_addr << PMU_I2C_ADDRESS_SHIFT;
+
+ c = _compute_pmic_checksum(data->poweroff_reg_addr,
+ data->poweroff_reg_data, v);
+ v |= c << CHECKSUM_SHIFT;
+
+ tegra_pmc_writel(v, PMC_SCRATCH55);
+}
+EXPORT_SYMBOL(tegra_pmc_config_thermal_trip);
+
void tegra_pmc_set_dpd_sample()
{
tegra_pmc_writel(0x1, PMC_DPD_SAMPLE);
diff --git a/include/linux/tegra-pmc.h b/include/linux/tegra-pmc.h
index b0f0236cf286..9f712ca13af3 100644
--- a/include/linux/tegra-pmc.h
+++ b/include/linux/tegra-pmc.h
@@ -51,6 +51,51 @@ struct pmc_pm_data {
enum tegra_suspend_mode suspend_mode;
};
+/**
+ * struct tegra_tsensor_pmu_data - PMIC temperature sensor
+ * configuration
+ * @poweroff_reg_data: The data to write to turn the system off
+ * @poweroff_reg_addr: The PMU address of poweroff register
+ * @reset_tegra: Flag indicating whether or not the system
+ * will shutdown during a thermal trip.
+ * @controller_type: If this field is set to 0, the PMIC is
+ * connected via I2C. If it is set to 1,
+ * it is connected via SPI. If it is set to
+ * 2, it is connected via GPIO.
+ * @i2c_controller_id: The i2c bus controller id
+ * @pinmux: An array index used to configure which pins
+ * on the chip are muxed to the I2C/SPI/GPIO
+ * controller that is in use. Contact NVIDIA
+ * for more information on what these index values
+ * mean for a given chip.
+ * @pmu_16bit_ops: If 0, sends three bytes from the PMC_SCRATCH54
+ * register to the PMIC to turn it off; if 1, sends
+ * four bytes from the PMC_SCRATCH54 register to the PMIC
+ * to turn it off, plus one other byte. Must be set to
+ * 0 - the current code does not support 16 bit
+ * operations.
+ * @pmu_i2c_addr: The address of the PMIC on the I2C bus
+ *
+ * When the temperature gets too high, the PMIC will power off the device
+ * based on what is written to the PMIC registers.
+ *
+ * @poweroff_reg_data and @poweroff_reg_addr are written to the PMC SCRATCH54
+ * register.
+ *
+ * @reset_tegra, @controller_type, @i2c_controller_id, @pinmux, @pmu_16bit_ops
+ * and @pmu_i2c_addr are written to the PMC SCRATCH55 register.
+ */
+struct tegra_tsensor_pmu_data {
+ u8 poweroff_reg_data;
+ u8 poweroff_reg_addr;
+ u8 reset_tegra;
+ u8 controller_type;
+ u8 i2c_controller_id;
+ u8 pinmux;
+ u8 pmu_16bit_ops;
+ u8 pmu_i2c_addr;
+};
+
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) && defined(CONFIG_PM_SLEEP)
void set_power_timers(unsigned long us_on, unsigned long us_off);
#endif
@@ -61,4 +106,8 @@ int tegra_pmc_cpu_remove_clamping(int cpuid);
void tegra_pmc_pmu_interrupt_polarity(bool active_low);
struct pmc_pm_data *tegra_get_pm_data(void);
+extern void tegra_pmc_config_thermal_trip(struct tegra_tsensor_pmu_data *data);
+
+extern void tegra_pmc_enable_thermal_trip(void);
+
#endif /* __LINUX_TEGRA_PMC_H__ */