summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenu byravarasu <vbyravarasu@nvidia.com>2011-08-03 16:51:57 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:48:05 -0800
commit3e8e2a67e2d2a0d77218d487082fdbffccbb548d (patch)
treeb9ea4aa8afcecd7af5a6c19490023e14ecca4192
parent1351a51c206601dd552d85905d2b6c3800a87761 (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 Original-Change-Id: I7a283cedc735264dd8ea52801f7f1a103e9293cb Reviewed-on: http://git-master/r/41531 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: Rc4bf2206a7207e28434b46baed442cd6f2797fbc
-rw-r--r--arch/arm/mach-tegra/board-cardhu-power.c17
-rw-r--r--arch/arm/mach-tegra/board-cardhu.c2
-rw-r--r--arch/arm/mach-tegra/board-cardhu.h1
-rw-r--r--arch/arm/mach-tegra/board-enterprise-power.c5
-rw-r--r--arch/arm/mach-tegra/board-enterprise.c2
-rw-r--r--arch/arm/mach-tegra/board-enterprise.h1
-rw-r--r--arch/arm/mach-tegra/board.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/tsensor.h13
-rw-r--r--arch/arm/mach-tegra/tegra3_tsensor.c76
9 files changed, 112 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-power.c b/arch/arm/mach-tegra/board-cardhu-power.c
index bab3e7218d05..319b9b1ad544 100644
--- a/arch/arm/mach-tegra/board-cardhu-power.c
+++ b/arch/arm/mach-tegra/board-cardhu-power.c
@@ -33,6 +33,7 @@
#include <mach/irqs.h>
#include <mach/pinmux.h>
#include <mach/edp.h>
+#include <mach/tsensor.h>
#include "gpio-names.h"
#include "board.h"
@@ -994,6 +995,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 cardhu_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-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 09e9f9613396..c46841577b2d 100644
--- a/arch/arm/mach-tegra/board-cardhu.c
+++ b/arch/arm/mach-tegra/board-cardhu.c
@@ -739,7 +739,7 @@ static void __init tegra_cardhu_init(void)
cardhu_edp_init();
#endif
cardhu_uart_init();
- tegra_tsensor_init();
+ cardhu_tsensor_init();
platform_add_devices(cardhu_devices, ARRAY_SIZE(cardhu_devices));
cardhu_sdhci_init();
cardhu_regulator_init();
diff --git a/arch/arm/mach-tegra/board-cardhu.h b/arch/arm/mach-tegra/board-cardhu.h
index 01a29c5a689e..711fadb42575 100644
--- a/arch/arm/mach-tegra/board-cardhu.h
+++ b/arch/arm/mach-tegra/board-cardhu.h
@@ -170,6 +170,7 @@ int cardhu_emc_init(void);
int cardhu_power_off_init(void);
int cardhu_edp_init(void);
int cardhu_pmon_init(void);
+void __init cardhu_tsensor_init(void);
/* Baseband GPIO addresses */
#define BB_GPIO_BB_EN TEGRA_GPIO_PR5
diff --git a/arch/arm/mach-tegra/board-enterprise-power.c b/arch/arm/mach-tegra/board-enterprise-power.c
index 52ef8fc822e6..edc25a3bf314 100644
--- a/arch/arm/mach-tegra/board-enterprise-power.c
+++ b/arch/arm/mach-tegra/board-enterprise-power.c
@@ -400,6 +400,11 @@ static void enterprise_power_off(void)
while(1);
}
+void __init enterprise_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/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c
index 90677aef934a..430e6855e205 100644
--- a/arch/arm/mach-tegra/board-enterprise.c
+++ b/arch/arm/mach-tegra/board-enterprise.c
@@ -476,7 +476,7 @@ static void __init tegra_enterprise_init(void)
enterprise_pinmux_init();
enterprise_i2c_init();
enterprise_uart_init();
- tegra_tsensor_init();
+ enterprise_tsensor_init();
platform_add_devices(enterprise_devices, ARRAY_SIZE(enterprise_devices));
enterprise_regulator_init();
enterprise_sdhci_init();
diff --git a/arch/arm/mach-tegra/board-enterprise.h b/arch/arm/mach-tegra/board-enterprise.h
index 6d82274b8f41..296250ff3622 100644
--- a/arch/arm/mach-tegra/board-enterprise.h
+++ b/arch/arm/mach-tegra/board-enterprise.h
@@ -37,6 +37,7 @@ int enterprise_regulator_init(void);
int enterprise_modem_init(void);
int enterprise_suspend_init(void);
int enterprise_edp_init(void);
+void __init enterprise_tsensor_init(void);
/* Touchscreen GPIO addresses */
#ifdef CONFIG_TOUCHSCREEN_ATMEL_MT_T9
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 1a0be7397980..942a1864944e 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -44,7 +44,6 @@ int __init tegra_pcie_init(bool init_port0, bool init_port1);
void tegra_init_cache(void);
void __init tegra_release_bootloader_fb(void);
void __init tegra_protected_aperture_init(unsigned long aperture);
-void __init tegra_tsensor_init(void);
void tegra_move_framebuffer(unsigned long to, unsigned long from,
unsigned long size);
bool is_tegra_debug_uartport_hs(void);
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 019513218939..00c3b6d38afa 100644
--- a/arch/arm/mach-tegra/tegra3_tsensor.c
+++ b/arch/arm/mach-tegra/tegra3_tsensor.c
@@ -16,12 +16,16 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include "board.h"
#ifdef CONFIG_SENSORS_TEGRA_TSENSOR
+#include <linux/io.h>
+#include <linux/ioport.h>
+
+#include <mach/iomap.h>
#include <mach/tsensor.h>
#include <mach/tegra_fuse.h>
+#include "board.h"
#include "devices.h"
#include "fuse.h"
@@ -36,10 +40,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)
@@ -50,6 +79,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);
@@ -59,6 +129,6 @@ errLabel:
}
#else
-void __init tegra_tsensor_init(void) { }
+void __init tegra3_tsensor_init(void) { }
#endif