diff options
-rw-r--r-- | arch/arm/cpu/armv7/exynos/power.c | 12 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-exynos/power.h | 4 | ||||
-rw-r--r-- | drivers/power/exynos-tmu.c | 25 |
3 files changed, 36 insertions, 5 deletions
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index db7249e..6375a81 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -128,3 +128,15 @@ void set_xclkout(void) if (cpu_is_exynos5()) exynos5_set_xclkout(); } + +/* Enables hardware tripping to power off the system when TMU fails */ +void set_hw_thermal_trip(void) +{ + if (cpu_is_exynos5()) { + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + /* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/ + setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP); + } +} diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 5f26337..3549667 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -857,6 +857,9 @@ void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable); void set_usbhost_phy_ctrl(unsigned int enable); +/* Enables hardware tripping to power off the system when TMU fails */ +void set_hw_thermal_trip(void); + #define POWER_USB_HOST_PHY_CTRL_EN (1 << 0) #define POWER_USB_HOST_PHY_CTRL_DISABLE (0 << 0) @@ -865,6 +868,7 @@ void set_dp_phy_ctrl(unsigned int enable); #define EXYNOS_DP_PHY_ENABLE (1 << 0) #define EXYNOS_PS_HOLD_CONTROL_DATA_HIGH (1 << 8) +#define POWER_ENABLE_HW_TRIP (1UL << 31) /* * Set ps_hold data driving value high diff --git a/drivers/power/exynos-tmu.c b/drivers/power/exynos-tmu.c index d8313b1..d4b3e65 100644 --- a/drivers/power/exynos-tmu.c +++ b/drivers/power/exynos-tmu.c @@ -22,9 +22,11 @@ #include <fdtdec.h> #include <tmu.h> #include <asm/arch/tmu.h> +#include <asm/arch/power.h> #define TRIMINFO_RELOAD 1 #define CORE_EN 1 +#define THERM_TRIP_EN (1 << 12) #define INTEN_RISE0 1 #define INTEN_RISE1 (1 << 4) @@ -55,6 +57,8 @@ struct temperature_params { unsigned int start_warning; /* temperature threshold CPU tripping */ unsigned int start_tripping; + /* temperature threshold for HW tripping */ + unsigned int hardware_tripping; }; /* Pre-defined values and thresholds for calibration of current temperature */ @@ -196,6 +200,9 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) info->data.ts.start_tripping = fdtdec_get_int(blob, node, "samsung,start-tripping", -1); error |= info->data.ts.start_tripping; + info->data.ts.hardware_tripping = fdtdec_get_int(blob, + node, "samsung,hw-tripping", -1); + error |= info->data.ts.hardware_tripping; info->data.efuse_min_value = fdtdec_get_int(blob, node, "samsung,efuse-min-value", -1); error |= info->data.efuse_min_value; @@ -230,7 +237,7 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) static void tmu_setup_parameters(struct tmu_info *info) { unsigned int te_code, con; - unsigned int warning_code, trip_code; + unsigned int warning_code, trip_code, hwtrip_code; unsigned int cooling_temp; unsigned int rising_value; struct tmu_data *data = &info->data; @@ -254,9 +261,14 @@ static void tmu_setup_parameters(struct tmu_info *info) + info->te1 - info->dc_value; trip_code = data->ts.start_tripping + info->te1 - info->dc_value; + hwtrip_code = data->ts.hardware_tripping + + info->te1 - info->dc_value; + cooling_temp = 0; - rising_value = ((warning_code << 8) | (trip_code << 16)); + rising_value = ((warning_code << 8) | + (trip_code << 16) | + (hwtrip_code << 24)); /* Set interrupt level */ writel(rising_value, ®->threshold_temp_rise); @@ -276,12 +288,15 @@ static void tmu_setup_parameters(struct tmu_info *info) /* TMU core enable */ con = readl(®->tmu_control); - con |= CORE_EN; + con |= THERM_TRIP_EN | CORE_EN; writel(con, ®->tmu_control); - /* LEV0 LEV1 LEV2 interrupt enable */ - writel(INTEN_RISE0 | INTEN_RISE1 | INTEN_RISE2, ®->inten); + /* Enable HW thermal trip */ + set_hw_thermal_trip(); + + /* LEV1 LEV2 interrupt enable */ + writel(INTEN_RISE1 | INTEN_RISE2, ®->inten); } /* |