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 db7249ef7..6375a81fd 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 5f2633763..3549667d9 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 d8313b1d3..d4b3e65a3 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);  }  /* |