summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenu byravarasu <vbyravarasu@nvidia.com>2011-08-03 16:51:57 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-08-05 18:12:31 -0700
commit73a50496f4657a5e6d4a689fd15e44dbfccfaf6a (patch)
tree86f26a6799ad3c93bf68f86ef12fa1d39f03b8e0
parent77411f6f444b0c1db680016bec2629272d69749d (diff)
ARM: tegra: cardhu: switch off PMU at high temperature
Add board support needed for PMU switch off when tsensor detects temperature > TH3 threshold set. bug 850047 Change-Id: I7a283cedc735264dd8ea52801f7f1a103e9293cb Reviewed-on: http://git-master/r/41531 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board-cardhu-power.c17
-rw-r--r--arch/arm/mach-tegra/board-enterprise-power.c5
-rw-r--r--arch/arm/mach-tegra/include/mach/tsensor.h13
-rw-r--r--arch/arm/mach-tegra/tegra3_tsensor.c73
4 files changed, 106 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-power.c b/arch/arm/mach-tegra/board-cardhu-power.c
index b769bf64bf65..cb77efc41703 100644
--- a/arch/arm/mach-tegra/board-cardhu-power.c
+++ b/arch/arm/mach-tegra/board-cardhu-power.c
@@ -40,6 +40,7 @@
#include "board-cardhu.h"
#include "power.h"
#include "wakeups-t3.h"
+#include "mach/tsensor.h"
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
@@ -1001,6 +1002,22 @@ int __init cardhu_power_off_init(void)
return 0;
}
+static struct tegra_tsensor_pmu_data tpdata = {
+ .poweroff_reg_addr = 0x3F,
+ .poweroff_reg_data = 0x80,
+ .reset_tegra = 1,
+ .controller_type = 0,
+ .i2c_controller_id = 4,
+ .pinmux = 0,
+ .pmu_16bit_ops = 0,
+ .pmu_i2c_addr = 0x2D,
+};
+
+void __init tegra_tsensor_init(void)
+{
+ tegra3_tsensor_init(&tpdata);
+}
+
#ifdef CONFIG_TEGRA_EDP_LIMITS
int __init cardhu_edp_init(void)
diff --git a/arch/arm/mach-tegra/board-enterprise-power.c b/arch/arm/mach-tegra/board-enterprise-power.c
index 87436b8f8691..2138d6857f17 100644
--- a/arch/arm/mach-tegra/board-enterprise-power.c
+++ b/arch/arm/mach-tegra/board-enterprise-power.c
@@ -401,6 +401,11 @@ static void enterprise_power_off(void)
while(1);
}
+void __init tegra_tsensor_init(void)
+{
+/* To be implemented */
+}
+
int __init enterprise_regulator_init(void)
{
void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
diff --git a/arch/arm/mach-tegra/include/mach/tsensor.h b/arch/arm/mach-tegra/include/mach/tsensor.h
index d4d8c64acb43..63a9c9676ebd 100644
--- a/arch/arm/mach-tegra/include/mach/tsensor.h
+++ b/arch/arm/mach-tegra/include/mach/tsensor.h
@@ -25,6 +25,17 @@
#define MAX_ZONES 16
+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;
+};
+
struct tegra_tsensor_platform_data {
int sw_intr_temperature;
int hw_clk_div_temperature;
@@ -36,5 +47,7 @@ struct tegra_tsensor_platform_data {
void (*alarm_fn)(bool raised);
};
+void __init tegra3_tsensor_init(struct tegra_tsensor_pmu_data *);
+
#endif /* __MACH_TEGRA_TSENSOR_H */
diff --git a/arch/arm/mach-tegra/tegra3_tsensor.c b/arch/arm/mach-tegra/tegra3_tsensor.c
index 199536a35adb..5c441f7dbb76 100644
--- a/arch/arm/mach-tegra/tegra3_tsensor.c
+++ b/arch/arm/mach-tegra/tegra3_tsensor.c
@@ -22,6 +22,9 @@
#include <mach/tsensor.h>
#include <mach/tegra_fuse.h>
#include <devices.h>
+#include <mach/iomap.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
static struct tegra_tsensor_platform_data tsensor_data = {
.hysteresis = 5,
@@ -34,10 +37,35 @@ static struct tegra_tsensor_platform_data tsensor_data = {
#define TSENSOR_FUSE_REVISION_DECIMAL 8
#define TSENSOR_FUSE_REVISION_INTEGER 0
-void __init tegra_tsensor_init(void)
+/* scratch register offsets needed for powering off PMU */
+#define SCRATCH54_OFFSET 0x258
+#define SCRATCH55_OFFSET 0x25C
+
+/* scratch 54 register bit field offsets */
+#define PMU_OFF_DATA_OFFSET 8
+
+/* scratch 55 register bit field offsets */
+#define RESET_TEGRA_OFFSET 31
+#define CONTROLLER_TYPE_OFFSET 30
+#define I2C_CONTROLLER_ID_OFFSET 27
+#define PINMUX_OFFSET 24
+#define CHECKSUM_OFFSET 16
+#define PMU_16BIT_SUPPORT_OFFSET 15
+/* scratch 55 register bit field masks */
+#define RESET_TEGRA_MASK 0x1
+#define CONTROLLER_TYPE_MASK 0x1
+#define I2C_CONTROLLER_ID_MASK 0x7
+#define PINMUX_MASK 0x7
+#define CHECKSUM_MASK 0xff
+#define PMU_16BIT_SUPPORT_MASK 0x1
+
+
+void __init tegra3_tsensor_init(struct tegra_tsensor_pmu_data *data)
{
unsigned int reg, fuse_rev_integer, fuse_rev_decimal;
int err;
+ u32 val, checksum;
+ void __iomem *pMem = NULL;
/* tsensor driver is instantiated based on fuse revision */
err = tegra_fuse_get_revision(&reg);
if (err)
@@ -48,6 +76,47 @@ void __init tegra_tsensor_init(void)
fuse_rev_decimal);
if ((fuse_rev_decimal >= TSENSOR_FUSE_REVISION_DECIMAL) &&
(fuse_rev_integer >= TSENSOR_FUSE_REVISION_INTEGER)) {
+
+ if (!request_mem_region(TEGRA_PMC_BASE + SCRATCH54_OFFSET,
+ 8, "tegra-tsensor")) {
+ pr_err(" [%s, line=%d]: Error mem busy\n",
+ __func__, __LINE__);
+ }
+
+ pMem = ioremap(TEGRA_PMC_BASE + SCRATCH54_OFFSET, 8);
+ if (!pMem) {
+ pr_err(" [%s, line=%d]: can't ioremap "
+ "pmc iomem\n", __FILE__, __LINE__);
+ }
+
+ /*
+ Fill scratch registers to power off the device
+ in case if temperature crosses threshold TH3
+ */
+ val = (data->poweroff_reg_data << PMU_OFF_DATA_OFFSET) |
+ data->poweroff_reg_addr;
+ writel(val, pMem);
+
+ val = ((data->reset_tegra & RESET_TEGRA_MASK) <<
+ RESET_TEGRA_OFFSET) |
+ ((data->controller_type & CONTROLLER_TYPE_MASK) <<
+ CONTROLLER_TYPE_OFFSET) |
+ ((data->i2c_controller_id & I2C_CONTROLLER_ID_MASK) <<
+ I2C_CONTROLLER_ID_OFFSET) |
+ ((data->pinmux & PINMUX_MASK) << PINMUX_OFFSET) |
+ ((data->pmu_16bit_ops & PMU_16BIT_SUPPORT_MASK) <<
+ PMU_16BIT_SUPPORT_OFFSET) |
+ 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 |= (checksum << CHECKSUM_OFFSET);
+ writel(val, pMem + 4);
+
/* set platform data for device before register */
tegra_tsensor_device.dev.platform_data = &tsensor_data;
platform_device_register(&tegra_tsensor_device);
@@ -57,6 +126,6 @@ errLabel:
}
#else
-void __init tegra_tsensor_init(void) { }
+void __init tegra3_tsensor_init(void) { }
#endif