diff options
author | venu byravarasu <vbyravarasu@nvidia.com> | 2011-08-03 16:51:57 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:48:05 -0800 |
commit | 3e8e2a67e2d2a0d77218d487082fdbffccbb548d (patch) | |
tree | b9ea4aa8afcecd7af5a6c19490023e14ecca4192 /arch | |
parent | 1351a51c206601dd552d85905d2b6c3800a87761 (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
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu-power.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise-power.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/tsensor.h | 13 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_tsensor.c | 76 |
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(®); 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 |