diff options
| author | Naveen Krishna Chatradhi <ch.naveen@samsung.com> | 2013-12-19 01:06:31 -0500 |
|---|---|---|
| committer | Eduardo Valentin <edubezval@gmail.com> | 2014-05-06 14:51:32 -0400 |
| commit | 14a11dc7e0dbf4acdd9c7b703ebd088f14def739 (patch) | |
| tree | 92b6362dab322f7c2807f2a2f131a1123ad624a0 | |
| parent | 9025d563cd9bd141a7b7f2095b6a760cd9d83a4e (diff) | |
thermal: samsung: Add TMU support for Exynos5420 SoCs
Exynos5420 has 5 TMU channels, the TRIMINFO register is
misplaced for TMU channels 2, 3 and 4
TRIMINFO at 0x1006c000 contains data for TMU channel 3
TRIMINFO at 0x100a0000 contains data for TMU channel 4
TRIMINFO at 0x10068000 contains data for TMU channel 2
This patch
1 Adds the neccessary register changes and arch information
to support Exynos5420 SoCs.
2. Handles the gate clock for misplaced TRIMINFO register
3. Updates the Documentation at
Documentation/devicetree/bindings/thermal/exynos-thermal.txt
Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
Signed-off-by: Andrew Bresticker <abrestic@chromium.org>
Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
| -rw-r--r-- | Documentation/devicetree/bindings/thermal/exynos-thermal.txt | 45 | ||||
| -rw-r--r-- | drivers/thermal/samsung/exynos_tmu.c | 52 | ||||
| -rw-r--r-- | drivers/thermal/samsung/exynos_tmu.h | 1 | ||||
| -rw-r--r-- | drivers/thermal/samsung/exynos_tmu_data.c | 99 | ||||
| -rw-r--r-- | drivers/thermal/samsung/exynos_tmu_data.h | 8 |
5 files changed, 200 insertions, 5 deletions
diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt index a1aa6023d248..79c4055a190d 100644 --- a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt | |||
| @@ -6,6 +6,9 @@ | |||
| 6 | "samsung,exynos4412-tmu" | 6 | "samsung,exynos4412-tmu" |
| 7 | "samsung,exynos4210-tmu" | 7 | "samsung,exynos4210-tmu" |
| 8 | "samsung,exynos5250-tmu" | 8 | "samsung,exynos5250-tmu" |
| 9 | "samsung,exynos5420-tmu" for TMU channel 0, 1 on Exynos5420 | ||
| 10 | "samsung,exynos5420-tmu-ext-triminfo" for TMU channels 2, 3 and 4 | ||
| 11 | Exynos5420 (Must pass triminfo base and triminfo clock) | ||
| 9 | "samsung,exynos5440-tmu" | 12 | "samsung,exynos5440-tmu" |
| 10 | - interrupt-parent : The phandle for the interrupt controller | 13 | - interrupt-parent : The phandle for the interrupt controller |
| 11 | - reg : Address range of the thermal registers. For soc's which has multiple | 14 | - reg : Address range of the thermal registers. For soc's which has multiple |
| @@ -13,9 +16,24 @@ | |||
| 13 | interrupt related then 2 set of register has to supplied. First set | 16 | interrupt related then 2 set of register has to supplied. First set |
| 14 | belongs to register set of TMU instance and second set belongs to | 17 | belongs to register set of TMU instance and second set belongs to |
| 15 | registers shared with the TMU instance. | 18 | registers shared with the TMU instance. |
| 19 | |||
| 20 | NOTE: On Exynos5420, the TRIMINFO register is misplaced for TMU | ||
| 21 | channels 2, 3 and 4 | ||
| 22 | Use "samsung,exynos5420-tmu-ext-triminfo" in cases, there is a misplaced | ||
| 23 | register, also provide clock to access that base. | ||
| 24 | |||
| 25 | TRIMINFO at 0x1006c000 contains data for TMU channel 3 | ||
| 26 | TRIMINFO at 0x100a0000 contains data for TMU channel 4 | ||
| 27 | TRIMINFO at 0x10068000 contains data for TMU channel 2 | ||
| 28 | |||
| 16 | - interrupts : Should contain interrupt for thermal system | 29 | - interrupts : Should contain interrupt for thermal system |
| 17 | - clocks : The main clock for TMU device | 30 | - clocks : The main clocks for TMU device |
| 31 | -- 1. operational clock for TMU channel | ||
| 32 | -- 2. optional clock to access the shared registers of TMU channel | ||
| 18 | - clock-names : Thermal system clock name | 33 | - clock-names : Thermal system clock name |
| 34 | -- "tmu_apbif" operational clock for current TMU channel | ||
| 35 | -- "tmu_triminfo_apbif" clock to access the shared triminfo register | ||
| 36 | for current TMU channel | ||
| 19 | - vtmu-supply: This entry is optional and provides the regulator node supplying | 37 | - vtmu-supply: This entry is optional and provides the regulator node supplying |
| 20 | voltage to TMU. If needed this entry can be placed inside | 38 | voltage to TMU. If needed this entry can be placed inside |
| 21 | board/platform specific dts file. | 39 | board/platform specific dts file. |
| @@ -43,6 +61,31 @@ Example 2): | |||
| 43 | clock-names = "tmu_apbif"; | 61 | clock-names = "tmu_apbif"; |
| 44 | }; | 62 | }; |
| 45 | 63 | ||
| 64 | Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register") | ||
| 65 | tmu_cpu2: tmu@10068000 { | ||
| 66 | compatible = "samsung,exynos5420-tmu-ext-triminfo"; | ||
| 67 | reg = <0x10068000 0x100>, <0x1006c000 0x4>; | ||
| 68 | interrupts = <0 184 0>; | ||
| 69 | clocks = <&clock 318>, <&clock 318>; | ||
| 70 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; | ||
| 71 | }; | ||
| 72 | |||
| 73 | tmu_cpu3: tmu@1006c000 { | ||
| 74 | compatible = "samsung,exynos5420-tmu-ext-triminfo"; | ||
| 75 | reg = <0x1006c000 0x100>, <0x100a0000 0x4>; | ||
| 76 | interrupts = <0 185 0>; | ||
| 77 | clocks = <&clock 318>, <&clock 319>; | ||
| 78 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; | ||
| 79 | }; | ||
| 80 | |||
| 81 | tmu_gpu: tmu@100a0000 { | ||
| 82 | compatible = "samsung,exynos5420-tmu-ext-triminfo"; | ||
| 83 | reg = <0x100a0000 0x100>, <0x10068000 0x4>; | ||
| 84 | interrupts = <0 215 0>; | ||
| 85 | clocks = <&clock 319>, <&clock 318>; | ||
| 86 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; | ||
| 87 | }; | ||
| 88 | |||
| 46 | Note: For multi-instance tmu each instance should have an alias correctly | 89 | Note: For multi-instance tmu each instance should have an alias correctly |
| 47 | numbered in "aliases" node. | 90 | numbered in "aliases" node. |
| 48 | 91 | ||
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index d9e7663fea8c..bc50912a222d 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | * @irq_work: pointer to the irq work structure. | 47 | * @irq_work: pointer to the irq work structure. |
| 48 | * @lock: lock to implement synchronization. | 48 | * @lock: lock to implement synchronization. |
| 49 | * @clk: pointer to the clock structure. | 49 | * @clk: pointer to the clock structure. |
| 50 | * @clk_sec: pointer to the clock structure for accessing the base_second. | ||
| 50 | * @temp_error1: fused value of the first point trim. | 51 | * @temp_error1: fused value of the first point trim. |
| 51 | * @temp_error2: fused value of the second point trim. | 52 | * @temp_error2: fused value of the second point trim. |
| 52 | * @regulator: pointer to the TMU regulator structure. | 53 | * @regulator: pointer to the TMU regulator structure. |
| @@ -61,7 +62,7 @@ struct exynos_tmu_data { | |||
| 61 | enum soc_type soc; | 62 | enum soc_type soc; |
| 62 | struct work_struct irq_work; | 63 | struct work_struct irq_work; |
| 63 | struct mutex lock; | 64 | struct mutex lock; |
| 64 | struct clk *clk; | 65 | struct clk *clk, *clk_sec; |
| 65 | u8 temp_error1, temp_error2; | 66 | u8 temp_error1, temp_error2; |
| 66 | struct regulator *regulator; | 67 | struct regulator *regulator; |
| 67 | struct thermal_sensor_conf *reg_conf; | 68 | struct thermal_sensor_conf *reg_conf; |
| @@ -152,6 +153,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev) | |||
| 152 | 153 | ||
| 153 | mutex_lock(&data->lock); | 154 | mutex_lock(&data->lock); |
| 154 | clk_enable(data->clk); | 155 | clk_enable(data->clk); |
| 156 | if (!IS_ERR(data->clk_sec)) | ||
| 157 | clk_enable(data->clk_sec); | ||
| 155 | 158 | ||
| 156 | if (TMU_SUPPORTS(pdata, READY_STATUS)) { | 159 | if (TMU_SUPPORTS(pdata, READY_STATUS)) { |
| 157 | status = readb(data->base + reg->tmu_status); | 160 | status = readb(data->base + reg->tmu_status); |
| @@ -186,7 +189,12 @@ static int exynos_tmu_initialize(struct platform_device *pdev) | |||
| 186 | EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); | 189 | EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); |
| 187 | } | 190 | } |
| 188 | } else { | 191 | } else { |
| 189 | trim_info = readl(data->base + reg->triminfo_data); | 192 | /* On exynos5420 the triminfo register is in the shared space */ |
| 193 | if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) | ||
| 194 | trim_info = readl(data->base_second + | ||
| 195 | reg->triminfo_data); | ||
| 196 | else | ||
| 197 | trim_info = readl(data->base + reg->triminfo_data); | ||
| 190 | } | 198 | } |
| 191 | data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; | 199 | data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; |
| 192 | data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) & | 200 | data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) & |
| @@ -302,6 +310,8 @@ skip_calib_data: | |||
| 302 | out: | 310 | out: |
| 303 | clk_disable(data->clk); | 311 | clk_disable(data->clk); |
| 304 | mutex_unlock(&data->lock); | 312 | mutex_unlock(&data->lock); |
| 313 | if (!IS_ERR(data->clk_sec)) | ||
| 314 | clk_disable(data->clk_sec); | ||
| 305 | 315 | ||
| 306 | return ret; | 316 | return ret; |
| 307 | } | 317 | } |
| @@ -453,12 +463,16 @@ static void exynos_tmu_work(struct work_struct *work) | |||
| 453 | const struct exynos_tmu_registers *reg = pdata->registers; | 463 | const struct exynos_tmu_registers *reg = pdata->registers; |
| 454 | unsigned int val_irq, val_type; | 464 | unsigned int val_irq, val_type; |
| 455 | 465 | ||
| 466 | if (!IS_ERR(data->clk_sec)) | ||
| 467 | clk_enable(data->clk_sec); | ||
| 456 | /* Find which sensor generated this interrupt */ | 468 | /* Find which sensor generated this interrupt */ |
| 457 | if (reg->tmu_irqstatus) { | 469 | if (reg->tmu_irqstatus) { |
| 458 | val_type = readl(data->base_second + reg->tmu_irqstatus); | 470 | val_type = readl(data->base_second + reg->tmu_irqstatus); |
| 459 | if (!((val_type >> data->id) & 0x1)) | 471 | if (!((val_type >> data->id) & 0x1)) |
| 460 | goto out; | 472 | goto out; |
| 461 | } | 473 | } |
| 474 | if (!IS_ERR(data->clk_sec)) | ||
| 475 | clk_disable(data->clk_sec); | ||
| 462 | 476 | ||
| 463 | exynos_report_trigger(data->reg_conf); | 477 | exynos_report_trigger(data->reg_conf); |
| 464 | mutex_lock(&data->lock); | 478 | mutex_lock(&data->lock); |
| @@ -499,6 +513,14 @@ static const struct of_device_id exynos_tmu_match[] = { | |||
