thermal: exynos: Support thermal tripping

TMU urgently sends active-high signal (thermal trip) to PMU, and thermal
tripping by hardware logic. Thermal tripping means that PMU cuts off the
whole power of SoC by controlling external voltage regulator.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Jonghwan Choi <jhbird.choi@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
This commit is contained in:
Amit Daniel Kachhap 2013-06-24 16:20:32 +05:30 committed by Eduardo Valentin
parent b8d582b940
commit 7ca04e587e
3 changed files with 44 additions and 5 deletions

View File

@ -117,7 +117,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct exynos_tmu_platform_data *pdata = data->pdata;
const struct exynos_tmu_registers *reg = pdata->registers;
unsigned int status, trim_info;
unsigned int status, trim_info = 0, con;
unsigned int rising_threshold = 0, falling_threshold = 0;
int ret = 0, threshold_code, i, trigger_levs = 0;
@ -144,10 +144,26 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
(data->temp_error2 != 0))
data->temp_error1 = pdata->efuse_value;
/* Count trigger levels to be enabled */
for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
if (pdata->trigger_levels[i])
if (pdata->max_trigger_level > MAX_THRESHOLD_LEVS) {
dev_err(&pdev->dev, "Invalid max trigger level\n");
goto out;
}
for (i = 0; i < pdata->max_trigger_level; i++) {
if (!pdata->trigger_levels[i])
continue;
if ((pdata->trigger_type[i] == HW_TRIP) &&
(!pdata->trigger_levels[pdata->max_trigger_level - 1])) {
dev_err(&pdev->dev, "Invalid hw trigger level\n");
ret = -EINVAL;
goto out;
}
/* Count trigger levels except the HW trip*/
if (!(pdata->trigger_type[i] == HW_TRIP))
trigger_levs++;
}
if (data->soc == SOC_ARCH_EXYNOS4210) {
/* Write temperature code for threshold */
@ -165,7 +181,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
} else if (data->soc == SOC_ARCH_EXYNOS) {
/* Write temperature code for rising and falling threshold */
for (i = 0; i < trigger_levs; i++) {
for (i = 0;
i < trigger_levs && i < EXYNOS_MAX_TRIGGER_PER_REG; i++) {
threshold_code = temp_to_code(data,
pdata->trigger_levels[i]);
if (threshold_code < 0) {
@ -191,6 +208,24 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
writel((reg->inten_rise_mask << reg->inten_rise_shift) |
(reg->inten_fall_mask << reg->inten_fall_shift),
data->base + reg->tmu_intclear);
/* if last threshold limit is also present */
i = pdata->max_trigger_level - 1;
if (pdata->trigger_levels[i] &&
(pdata->trigger_type[i] == HW_TRIP)) {
threshold_code = temp_to_code(data,
pdata->trigger_levels[i]);
if (threshold_code < 0) {
ret = threshold_code;
goto out;
}
rising_threshold |= threshold_code << 8 * i;
writel(rising_threshold,
data->base + reg->threshold_th0);
con = readl(data->base + reg->tmu_ctrl);
con |= (1 << reg->therm_trip_en_shift);
writel(con, data->base + reg->tmu_ctrl);
}
}
out:
clk_disable(data->clk);

View File

@ -123,6 +123,7 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
.trigger_levels[0] = 85,
.trigger_levels[1] = 103,
.trigger_levels[2] = 110,
.trigger_levels[3] = 120,
.trigger_enable[0] = true,
.trigger_enable[1] = true,
.trigger_enable[2] = true,
@ -130,6 +131,7 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
.trigger_type[0] = THROTTLE_ACTIVE,
.trigger_type[1] = THROTTLE_ACTIVE,
.trigger_type[2] = SW_TRIP,
.trigger_type[3] = HW_TRIP,
.max_trigger_level = 4,
.gain = 8,
.reference_voltage = 16,

View File

@ -91,6 +91,8 @@
#define EXYNOS_EMUL_DATA_MASK 0xFF
#define EXYNOS_EMUL_ENABLE 0x1
#define EXYNOS_MAX_TRIGGER_PER_REG 4
#if defined(CONFIG_CPU_EXYNOS4210)
extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)