coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
tmu.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /* EXYNOS - Thermal Management Unit */
4 
5 #include <device/mmio.h>
6 #include <console/console.h>
7 #include <soc/power.h>
8 #include <soc/tmu.h>
9 
10 #define TRIMINFO_RELOAD 1
11 #define CORE_EN 1
12 #define THERM_TRIP_EN (1 << 12)
13 
14 #define INTEN_RISE0 1
15 #define INTEN_RISE1 (1 << 4)
16 #define INTEN_RISE2 (1 << 8)
17 #define INTEN_FALL0 (1 << 16)
18 #define INTEN_FALL1 (1 << 20)
19 #define INTEN_FALL2 (1 << 24)
20 
21 #define TRIM_INFO_MASK 0xff
22 
23 #define INTCLEAR_RISE0 1
24 #define INTCLEAR_RISE1 (1 << 4)
25 #define INTCLEAR_RISE2 (1 << 8)
26 #define INTCLEAR_FALL0 (1 << 16)
27 #define INTCLEAR_FALL1 (1 << 20)
28 #define INTCLEAR_FALL2 (1 << 24)
29 #define INTCLEARALL (INTCLEAR_RISE0 | INTCLEAR_RISE1 | \
30  INTCLEAR_RISE2 | INTCLEAR_FALL0 | \
31  INTCLEAR_FALL1 | INTCLEAR_FALL2)
32 
34  .tmu_base = 0x10060000,
35  .tmu_mux = 6,
36  .data = {
37  .ts = {
38  .min_val = 25,
39  .max_val = 125,
40  .start_warning = 95,
41  .start_tripping = 105,
42  .hardware_tripping = 110,
43  },
44  .efuse_min_value = 40,
45  .efuse_value = 55,
46  .efuse_max_value = 100,
47  .slope = 0x10008802,
48  },
49  .dc_value = 25,
50 };
51 
52 /*
53  * After reading temperature code from register, compensating
54  * its value and calculating celsius temperature,
55  * get current temperature.
56  *
57  * @return current temperature of the chip as sensed by TMU
58  */
59 static int get_cur_temp(struct tmu_info *info)
60 {
61  int cur_temp;
62  struct tmu_reg *reg = (struct tmu_reg *)info->tmu_base;
63 
64  /* Temperature code range between min 25 and max 125 */
65  cur_temp = read32(&reg->current_temp) & 0xff;
66 
67  /* Calibrate current temperature */
68  if (cur_temp)
69  cur_temp = cur_temp - info->te1 + info->dc_value;
70 
71  return cur_temp;
72 }
73 
74 /*
75  * Monitors status of the TMU device and exynos temperature
76  *
77  * @info TMU info
78  * @temp pointer to the current temperature value
79  * @return enum tmu_status_t value, code indicating event to execute
80  */
81 enum tmu_status_t tmu_monitor(struct tmu_info *info, int *temp)
82 {
83  if (info->tmu_state == TMU_STATUS_INIT)
84  return -1;
85 
86  int cur_temp;
87  struct tmu_data *data = &info->data;
88 
89  /* Read current temperature of the SOC */
90  cur_temp = get_cur_temp(info);
91  *temp = cur_temp;
92 
93  /* Temperature code lies between min 25 and max 125 */
94  if (cur_temp >= data->ts.start_tripping &&
95  cur_temp <= data->ts.max_val)
96  return TMU_STATUS_TRIPPED;
97  else if (cur_temp >= data->ts.start_warning)
98  return TMU_STATUS_WARNING;
99  else if (cur_temp < data->ts.start_warning &&
100  cur_temp >= data->ts.min_val)
101  return TMU_STATUS_NORMAL;
102  /* Temperature code does not lie between min 25 and max 125 */
103  else {
104  info->tmu_state = TMU_STATUS_INIT;
105  printk(BIOS_DEBUG, "EXYNOS_TMU: Thermal reading failed\n");
106  return -1;
107  }
108  return 0;
109 }
110 
111 /*
112  * Calibrate and calculate threshold values and
113  * enable interrupt levels
114  *
115  * @param info pointer to the tmu_info struct
116  */
117 static void tmu_setup_parameters(struct tmu_info *info)
118 {
119  unsigned int te_temp, con;
120  unsigned int warning_code, trip_code, hwtrip_code;
121  unsigned int cooling_temp;
122  unsigned int rising_value;
123  struct tmu_data *data = &info->data;
124  struct tmu_reg *reg = (struct tmu_reg *)info->tmu_base;
125 
126  /* Must reload for using efuse value at EXYNOS */
128 
129  /* Get the compensation parameter */
130  te_temp = read32(&reg->triminfo);
131  info->te1 = te_temp & TRIM_INFO_MASK;
132  info->te2 = ((te_temp >> 8) & TRIM_INFO_MASK);
133 
134  if ((data->efuse_min_value > info->te1) ||
135  (info->te1 > data->efuse_max_value)
136  || (info->te2 != 0))
137  info->te1 = data->efuse_value;
138 
139  /* Get RISING & FALLING Threshold value */
140  warning_code = data->ts.start_warning
141  + info->te1 - info->dc_value;
142  trip_code = data->ts.start_tripping
143  + info->te1 - info->dc_value;
144  hwtrip_code = data->ts.hardware_tripping
145  + info->te1 - info->dc_value;
146 
147  cooling_temp = 0;
148 
149  rising_value = ((warning_code << 8) |
150  (trip_code << 16) |
151  (hwtrip_code << 24));
152 
153  /* Set interrupt level */
154  write32(&reg->threshold_temp_rise, rising_value);
155  write32(&reg->threshold_temp_fall, cooling_temp);
156 
157  /*
158  * Need to init all register settings after getting parameter info
159  * [28:23] vref [11:8] slope - Tuning parameter
160  *
161  * WARNING: this slope value writes into many bits in the tmu_control
162  * register, with the default FDT value of 268470274 (0x10008802)
163  * we are using this essentially sets the default register setting
164  * from the TRM for tmu_control.
165  * TODO(bhthompson): rewrite this code such that we are not performing
166  * a hard wipe of tmu_control and re verify functionality.
167  */
168  write32(&reg->tmu_control, data->slope);
169 
170  write32(&reg->intclear, INTCLEARALL);
171  /* TMU core enable */
172  con = read32(&reg->tmu_control);
173  con |= (info->tmu_mux << 20) | THERM_TRIP_EN | CORE_EN;
174 
175  write32(&reg->tmu_control, con);
176 
177  /* Enable HW thermal trip */
179 
180  /* LEV1 LEV2 interrupt enable */
182 }
183 
184 /*
185  * Initialize TMU device
186  *
187  * @return int value, 0 for success
188  */
189 int tmu_init(struct tmu_info *info)
190 {
191  info->tmu_state = TMU_STATUS_INIT;
192 
194  info->tmu_state = TMU_STATUS_NORMAL;
195 
196  return 0;
197 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define printk(level,...)
Definition: stdlib.h:16
static struct smmstore_params_info info
Definition: ramstage.c:12
int tmu_init(struct tmu_info *info)
Definition: tmu.c:189
enum tmu_status_t tmu_monitor(struct tmu_info *info, int *temp)
Definition: tmu.c:81
static void tmu_setup_parameters(struct tmu_info *info)
Definition: tmu.c:117
#define THERM_TRIP_EN
Definition: tmu.c:12
#define INTEN_RISE2
Definition: tmu.c:16
static int get_cur_temp(struct tmu_info *info)
Definition: tmu.c:59
#define TRIM_INFO_MASK
Definition: tmu.c:21
#define INTEN_RISE1
Definition: tmu.c:15
#define CORE_EN
Definition: tmu.c:11
#define TRIMINFO_RELOAD
Definition: tmu.c:10
struct tmu_info exynos5420_tmu_info
Definition: tmu.c:33
#define INTCLEARALL
Definition: tmu.c:29
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
void power_enable_hw_thermal_trip(void)
Definition: power.c:47
unsigned int start_warning
Definition: tmu.h:59
unsigned int hardware_tripping
Definition: tmu.h:63
unsigned int start_tripping
Definition: tmu.h:61
unsigned int max_val
Definition: tmu.h:57
unsigned int min_val
Definition: tmu.h:55
Definition: tmu.h:67
unsigned int efuse_max_value
Definition: tmu.h:75
unsigned int slope
Definition: tmu.h:77
unsigned int efuse_value
Definition: tmu.h:73
unsigned int efuse_min_value
Definition: tmu.h:71
struct temperature_params ts
Definition: tmu.h:69
Definition: tmu.h:81
unsigned int tmu_base
Definition: tmu.h:83
Definition: tmu.h:8
unsigned int triminfo_control
Definition: tmu.h:14
unsigned int threshold_temp_fall
Definition: tmu.h:30
unsigned int tmu_control
Definition: tmu.h:17
unsigned int current_temp
Definition: tmu.h:25
unsigned int threshold_temp_rise
Definition: tmu.h:29
unsigned int inten
Definition: tmu.h:37
unsigned int triminfo
Definition: tmu.h:9
unsigned int intclear
Definition: tmu.h:39
tmu_status_t
Definition: tmu.h:45
@ TMU_STATUS_WARNING
Definition: tmu.h:48
@ TMU_STATUS_INIT
Definition: tmu.h:46
@ TMU_STATUS_TRIPPED
Definition: tmu.h:49
@ TMU_STATUS_NORMAL
Definition: tmu.h:47