提交 a0395eee 编写于 作者: A Amit Daniel Kachhap 提交者: Eduardo Valentin

thermal: exynos: Add driver support for exynos5440 TMU sensor

This patch modifies TMU controller to add changes needed to work with
exynos5440 platform. This sensor registers 3 instance of the tmu controller
with the thermal zone and hence reports 3 temperature output. This controller
supports upto five trip points. For critical threshold the driver uses the
core driver thermal framework for shutdown.
Acked-by: NJonghwa Lee <jonghwa3.lee@samsung.com>
Acked-by: NKukjin Kim <kgene.kim@samsung.com>
Signed-off-by: NJungseok Lee <jays.lee@samsung.com>
Signed-off-by: NAmit Daniel Kachhap <amit.daniel@samsung.com>
Acked-by: NEduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: NEduardo Valentin <eduardo.valentin@ti.com>
上级 d9b6ee14
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -27,7 +27,7 @@
#define SENSOR_NAME_LEN 16
#define MAX_TRIP_COUNT 8
#define MAX_COOLING_DEVICE 4
#define MAX_THRESHOLD_LEVS 4
#define MAX_THRESHOLD_LEVS 5
#define ACTIVE_INTERVAL 500
#define IDLE_INTERVAL 10000
......
......@@ -156,7 +156,26 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
__raw_writel(1, data->base + reg->triminfo_ctrl);
/* Save trimming info in order to perform calibration */
trim_info = readl(data->base + reg->triminfo_data);
if (data->soc == SOC_ARCH_EXYNOS5440) {
/*
* For exynos5440 soc triminfo value is swapped between TMU0 and
* TMU2, so the below logic is needed.
*/
switch (data->id) {
case 0:
trim_info = readl(data->base +
EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data);
break;
case 1:
trim_info = readl(data->base + reg->triminfo_data);
break;
case 2:
trim_info = readl(data->base -
EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data);
}
} else {
trim_info = readl(data->base + reg->triminfo_data);
}
data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK;
data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) &
EXYNOS_TMU_TEMP_MASK);
......@@ -201,7 +220,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
reg->threshold_th0 + i * sizeof(reg->threshold_th0));
writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
} else if (data->soc == SOC_ARCH_EXYNOS) {
} else {
/* Write temperature code for rising and falling threshold */
for (i = 0;
i < trigger_levs && i < EXYNOS_MAX_TRIGGER_PER_REG; i++) {
......@@ -241,14 +260,26 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
ret = threshold_code;
goto out;
}
rising_threshold |= threshold_code << 8 * i;
writel(rising_threshold,
data->base + reg->threshold_th0);
if (i == EXYNOS_MAX_TRIGGER_PER_REG - 1) {
/* 1-4 level to be assigned in th0 reg */
rising_threshold |= threshold_code << 8 * i;
writel(rising_threshold,
data->base + reg->threshold_th0);
} else if (i == EXYNOS_MAX_TRIGGER_PER_REG) {
/* 5th level to be assigned in th2 reg */
rising_threshold =
threshold_code << reg->threshold_th3_l0_shift;
writel(rising_threshold,
data->base + reg->threshold_th2);
}
con = readl(data->base + reg->tmu_ctrl);
con |= (1 << reg->therm_trip_en_shift);
writel(con, data->base + reg->tmu_ctrl);
}
}
/*Clear the PMIN in the common TMU register*/
if (reg->tmu_pmin && !data->id)
writel(0, data->base_common + reg->tmu_pmin);
out:
clk_disable(data->clk);
mutex_unlock(&data->lock);
......@@ -377,7 +408,14 @@ static void exynos_tmu_work(struct work_struct *work)
struct exynos_tmu_data, irq_work);
struct exynos_tmu_platform_data *pdata = data->pdata;
const struct exynos_tmu_registers *reg = pdata->registers;
unsigned int val_irq;
unsigned int val_irq, val_type;
/* Find which sensor generated this interrupt */
if (reg->tmu_irqstatus) {
val_type = readl(data->base_common + reg->tmu_irqstatus);
if (!((val_type >> data->id) & 0x1))
goto out;
}
exynos_report_trigger(data->reg_conf);
mutex_lock(&data->lock);
......@@ -390,7 +428,7 @@ static void exynos_tmu_work(struct work_struct *work)
clk_disable(data->clk);
mutex_unlock(&data->lock);
out:
enable_irq(data->irq);
}
......@@ -538,7 +576,8 @@ static int exynos_tmu_probe(struct platform_device *pdev)
return ret;
if (pdata->type == SOC_ARCH_EXYNOS ||
pdata->type == SOC_ARCH_EXYNOS4210)
pdata->type == SOC_ARCH_EXYNOS4210 ||
pdata->type == SOC_ARCH_EXYNOS5440)
data->soc = pdata->type;
else {
ret = -EINVAL;
......
......@@ -40,6 +40,7 @@ enum calibration_mode {
enum soc_type {
SOC_ARCH_EXYNOS4210 = 1,
SOC_ARCH_EXYNOS,
SOC_ARCH_EXYNOS5440,
};
/**
......@@ -131,6 +132,8 @@ enum soc_type {
* @emul_temp_shift: shift bits of emulation temperature.
* @emul_time_shift: shift bits of emulation time.
* @emul_time_mask: mask bits of emulation time.
* @tmu_irqstatus: register to find which TMU generated interrupts.
* @tmu_pmin: register to get/set the Pmin value.
*/
struct exynos_tmu_registers {
u32 triminfo_data;
......@@ -198,6 +201,9 @@ struct exynos_tmu_registers {
u32 emul_temp_shift;
u32 emul_time_shift;
u32 emul_time_mask;
u32 tmu_irqstatus;
u32 tmu_pmin;
};
/**
......
......@@ -93,6 +93,42 @@
#define EXYNOS_MAX_TRIGGER_PER_REG 4
/*exynos5440 specific registers*/
#define EXYNOS5440_TMU_S0_7_TRIM 0x000
#define EXYNOS5440_TMU_S0_7_CTRL 0x020
#define EXYNOS5440_TMU_S0_7_DEBUG 0x040
#define EXYNOS5440_TMU_S0_7_STATUS 0x060
#define EXYNOS5440_TMU_S0_7_TEMP 0x0f0
#define EXYNOS5440_TMU_S0_7_TH0 0x110
#define EXYNOS5440_TMU_S0_7_TH1 0x130
#define EXYNOS5440_TMU_S0_7_TH2 0x150
#define EXYNOS5440_TMU_S0_7_EVTEN 0x1F0
#define EXYNOS5440_TMU_S0_7_IRQEN 0x210
#define EXYNOS5440_TMU_S0_7_IRQ 0x230
/* exynos5440 common registers */
#define EXYNOS5440_TMU_IRQ_STATUS 0x000
#define EXYNOS5440_TMU_PMIN 0x004
#define EXYNOS5440_TMU_TEMP 0x008
#define EXYNOS5440_TMU_RISE_INT_MASK 0xf
#define EXYNOS5440_TMU_RISE_INT_SHIFT 0
#define EXYNOS5440_TMU_FALL_INT_MASK 0xf
#define EXYNOS5440_TMU_FALL_INT_SHIFT 4
#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0
#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1
#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2
#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT 3
#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT 4
#define EXYNOS5440_TMU_INTEN_FALL1_SHIFT 5
#define EXYNOS5440_TMU_INTEN_FALL2_SHIFT 6
#define EXYNOS5440_TMU_INTEN_FALL3_SHIFT 7
#define EXYNOS5440_TMU_TH_RISE0_SHIFT 0
#define EXYNOS5440_TMU_TH_RISE1_SHIFT 8
#define EXYNOS5440_TMU_TH_RISE2_SHIFT 16
#define EXYNOS5440_TMU_TH_RISE3_SHIFT 24
#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24
#define EXYNOS5440_EFUSE_SWAP_OFFSET 8
#if defined(CONFIG_CPU_EXYNOS4210)
extern struct exynos_tmu_init_data const exynos4210_default_tmu_data;
#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部