blob: c52cbb24da47ba9458e11f2e2763fb3a864cf2e5 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Sven Schnelleca682972012-07-03 21:33:47 +02003
4#include <stdint.h>
Sven Schnelleca682972012-07-03 21:33:47 +02005#include <console/console.h>
6#include <device/device.h>
7#include "w83793.h"
8#include <device/smbus.h>
9#include "chip.h"
10
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +110011static int w83793_fan_limit(struct device *dev, int fan, uint16_t limit)
Sven Schnelleca682972012-07-03 21:33:47 +020012{
13 return smbus_write_byte(dev, 0x90 + fan * 2, limit >> 8) ||
14 smbus_write_byte(dev, 0x91 + fan * 2, limit & 0xff);
15}
16
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +110017static int w83793_bank(struct device *dev, int bank)
Sven Schnelleca682972012-07-03 21:33:47 +020018{
19 return smbus_write_byte(dev, 0, bank);
20}
21
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +110022static int w83793_td_level(struct device *dev, int fan, const char *level)
Sven Schnelleca682972012-07-03 21:33:47 +020023{
24 fan *= 0x10;
25
26 smbus_write_byte(dev, 0x30 + fan, level[0]);
27 smbus_write_byte(dev, 0x31 + fan, level[1]);
28 smbus_write_byte(dev, 0x32 + fan, level[2]);
29 smbus_write_byte(dev, 0x33 + fan, level[3]);
30 smbus_write_byte(dev, 0x34 + fan, level[4]);
31 smbus_write_byte(dev, 0x35 + fan, level[5]);
32 smbus_write_byte(dev, 0x36 + fan, level[6]);
33 return 0;
34}
35
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +110036static int w83793_tr_level(struct device *dev, int fan, const char *level)
Sven Schnelleca682972012-07-03 21:33:47 +020037{
38 fan *= 0x10;
39
40 smbus_write_byte(dev, 0x70 + fan, level[0]);
41 smbus_write_byte(dev, 0x71 + fan, level[1]);
42 smbus_write_byte(dev, 0x72 + fan, level[2]);
43 smbus_write_byte(dev, 0x73 + fan, level[3]);
44 smbus_write_byte(dev, 0x74 + fan, level[4]);
45 smbus_write_byte(dev, 0x75 + fan, level[5]);
46 smbus_write_byte(dev, 0x76 + fan, level[6]);
47 return 0;
48}
49
50
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +110051static int w83793_td_fan_level(struct device *dev, int fan, const char *level)
Sven Schnelleca682972012-07-03 21:33:47 +020052{
53 fan *= 0x10;
54
55 smbus_write_byte(dev, 0x38 + fan, level[0]);
56 smbus_write_byte(dev, 0x39 + fan, level[1]);
57 smbus_write_byte(dev, 0x3a + fan, level[2]);
58 smbus_write_byte(dev, 0x3b + fan, level[3]);
59 smbus_write_byte(dev, 0x3c + fan, level[4]);
60 smbus_write_byte(dev, 0x3d + fan, level[5]);
61 smbus_write_byte(dev, 0x3e + fan, level[6]);
62 return 0;
63}
64
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +110065static int w83793_tr_fan_level(struct device *dev, int fan, const char *level)
Sven Schnelleca682972012-07-03 21:33:47 +020066{
67 fan *= 0x10;
68
69 smbus_write_byte(dev, 0x78 + fan, level[0]);
70 smbus_write_byte(dev, 0x79 + fan, level[1]);
71 smbus_write_byte(dev, 0x7a + fan, level[2]);
72 smbus_write_byte(dev, 0x7b + fan, level[3]);
73 smbus_write_byte(dev, 0x7c + fan, level[4]);
74 smbus_write_byte(dev, 0x7d + fan, level[5]);
75 smbus_write_byte(dev, 0x7e + fan, level[6]);
76 return 0;
77}
78
Timothy Pearsond3e31be2015-02-21 01:45:35 -060079static uint8_t millivolts_to_limit_value_type1(int millivolts)
80{
81 /* Datasheet v1.4 page 64 (VCoreA, VCoreB, Vtt Limit) */
82 return ((millivolts * 125) / 1000);
83}
84
85static uint8_t millivolts_to_limit_value_type2(int millivolts)
86{
87 /* Datasheet v1.4 page 64 (VSEN1, VEN2, VSEN3) */
88 return ((millivolts * 625) / 10000);
89}
90
91static uint8_t millivolts_to_limit_value_type3(int millivolts)
92{
93 /* Datasheet v1.4 page 64 (5VDD, 5VSB) */
94 return ((((millivolts * 10) + 1500) * 417) / 10000);
95}
96
97static uint8_t fan_pct_to_cfg_val(uint8_t percent)
98{
99 uint8_t cfg = (((unsigned int)percent * 10000) / 15873);
100 if (cfg > 0x3f)
101 cfg = 0x3f;
102 return cfg;
103}
Sven Schnelleca682972012-07-03 21:33:47 +0200104
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100105static void w83793_init(struct device *dev)
Sven Schnelleca682972012-07-03 21:33:47 +0200106{
107 struct drivers_i2c_w83793_config *config = dev->chip_info;
108 uint16_t id;
109 int i;
110
111 if (w83793_bank(dev, 0))
112 printk(BIOS_ERR, "%s: failed\n", __func__);
113
114 if (!config)
115 return;
116
117 id = smbus_read_byte(dev, 0x0d);
118 w83793_bank(dev, 0x80);
119 id |= smbus_read_byte(dev, 0x0d) << 8;
120 printk(BIOS_ERR, "ID: %04x\n", id);
121
122 /* reset configuration */
123 smbus_write_byte(dev, 0x40, 0x80);
124 smbus_write_byte(dev, 0x51, 0x06);
125
126 /* Multi function control */
127 smbus_write_byte(dev, 0x58, config->mfc);
128
129 /* FANIN_Ctrl */
130 smbus_write_byte(dev, 0x5c, config->fanin);
131
Timothy Pearsond3e31be2015-02-21 01:45:35 -0600132 /* FANIN_Sel */
133 smbus_write_byte(dev, 0x5d, config->fanin_sel);
134
135 /* Temperature source */
136 smbus_write_byte(dev, 0x5e, config->td_mode_select);
Sven Schnelleca682972012-07-03 21:33:47 +0200137 /* TR monitor enable */
138 smbus_write_byte(dev, 0x5f, config->tr_enable);
139 /* PECI Agent configuration */
140 smbus_write_byte(dev, 0xd0, config->peci_agent_conf);
141 /* TCase */
142 smbus_write_byte(dev, 0xd1, config->tcase0);
143 smbus_write_byte(dev, 0xd2, config->tcase1);
144 smbus_write_byte(dev, 0xd3, config->tcase2);
145 smbus_write_byte(dev, 0xd4, config->tcase3);
146 /* PECI Reportstyle */
147 smbus_write_byte(dev, 0xd5, 0x00);
148
Timothy Pearsond3e31be2015-02-21 01:45:35 -0600149 /* Voltage high/low limits */
150 smbus_write_byte(dev, 0x60, millivolts_to_limit_value_type1(config->vcorea_high_limit_mv));
151 smbus_write_byte(dev, 0x61, millivolts_to_limit_value_type1(config->vcorea_low_limit_mv));
152 smbus_write_byte(dev, 0x62, millivolts_to_limit_value_type1(config->vcoreb_high_limit_mv));
153 smbus_write_byte(dev, 0x63, millivolts_to_limit_value_type1(config->vcoreb_low_limit_mv));
154 smbus_write_byte(dev, 0x64, millivolts_to_limit_value_type1(config->vtt_high_limit_mv));
155 smbus_write_byte(dev, 0x65, millivolts_to_limit_value_type1(config->vtt_low_limit_mv));
156 smbus_write_byte(dev, 0x6a, millivolts_to_limit_value_type2(config->vsen1_high_limit_mv));
157 smbus_write_byte(dev, 0x6b, millivolts_to_limit_value_type2(config->vsen1_low_limit_mv));
158 smbus_write_byte(dev, 0x6c, millivolts_to_limit_value_type2(config->vsen2_high_limit_mv));
159 smbus_write_byte(dev, 0x6d, millivolts_to_limit_value_type2(config->vsen2_low_limit_mv));
160 smbus_write_byte(dev, 0x6e, millivolts_to_limit_value_type2(config->vsen3_high_limit_mv));
161 smbus_write_byte(dev, 0x6f, millivolts_to_limit_value_type2(config->vsen3_low_limit_mv));
162 smbus_write_byte(dev, 0x70, millivolts_to_limit_value_type1(config->vsen4_high_limit_mv));
163 smbus_write_byte(dev, 0x71, millivolts_to_limit_value_type1(config->vsen4_low_limit_mv));
164 smbus_write_byte(dev, 0x72, millivolts_to_limit_value_type3(config->vdd_high_limit_mv));
165 smbus_write_byte(dev, 0x73, millivolts_to_limit_value_type3(config->vdd_low_limit_mv));
166 smbus_write_byte(dev, 0x74, millivolts_to_limit_value_type3(config->vsb_high_limit_mv));
167 smbus_write_byte(dev, 0x75, millivolts_to_limit_value_type3(config->vsb_low_limit_mv));
168 smbus_write_byte(dev, 0x76, millivolts_to_limit_value_type2(config->vbat_high_limit_mv));
169 smbus_write_byte(dev, 0x77, millivolts_to_limit_value_type2(config->vbat_low_limit_mv));
170
171 /* Temperature high/low limits */
172 smbus_write_byte(dev, 0x78, config->td1_critical_temperature);
173 smbus_write_byte(dev, 0x79, config->td1_critical_hysteresis);
174 smbus_write_byte(dev, 0x7a, config->td1_warning_temperature);
175 smbus_write_byte(dev, 0x7b, config->td1_warning_hysteresis);
176 smbus_write_byte(dev, 0x7c, config->td2_critical_temperature);
177 smbus_write_byte(dev, 0x7d, config->td2_critical_hysteresis);
178 smbus_write_byte(dev, 0x7e, config->td2_warning_temperature);
179 smbus_write_byte(dev, 0x7f, config->td2_warning_hysteresis);
180 smbus_write_byte(dev, 0x80, config->td3_critical_temperature);
181 smbus_write_byte(dev, 0x81, config->td3_critical_hysteresis);
182 smbus_write_byte(dev, 0x82, config->td3_warning_temperature);
183 smbus_write_byte(dev, 0x83, config->td3_warning_hysteresis);
184 smbus_write_byte(dev, 0x84, config->td4_critical_temperature);
185 smbus_write_byte(dev, 0x85, config->td4_critical_hysteresis);
186 smbus_write_byte(dev, 0x86, config->td4_warning_temperature);
187 smbus_write_byte(dev, 0x87, config->td4_warning_hysteresis);
188 smbus_write_byte(dev, 0x88, config->tr1_critical_temperature);
189 smbus_write_byte(dev, 0x89, config->tr1_critical_hysteresis);
190 smbus_write_byte(dev, 0x8a, config->tr1_warning_temperature);
191 smbus_write_byte(dev, 0x8b, config->tr1_warning_hysteresis);
192 smbus_write_byte(dev, 0x8c, config->tr2_critical_temperature);
193 smbus_write_byte(dev, 0x8d, config->tr2_critical_hysteresis);
194 smbus_write_byte(dev, 0x8e, config->tr2_warning_temperature);
195 smbus_write_byte(dev, 0x8f, config->tr2_warning_hysteresis);
196
197 /* Set minimum FAN speeds before alarms will be set */
198 for (i = 0; i < config->first_valid_fan_number; i++)
199 w83793_fan_limit(dev, i, 0x0);
200 for (i = config->first_valid_fan_number; i < 12; i++)
Sven Schnelleca682972012-07-03 21:33:47 +0200201 w83793_fan_limit(dev, i, 0x768);
202
203 /* Fan output style control */
Timothy Pearsond3e31be2015-02-21 01:45:35 -0600204 smbus_write_byte(dev, 0xb0, config->fanctrl1);
205 smbus_write_byte(dev, 0xb1, config->fanctrl2);
Sven Schnelleca682972012-07-03 21:33:47 +0200206
207 /* FAN Uptime */
208 smbus_write_byte(dev, 0xc3, 0x02);
209
210 /* FAN downtime */
211 smbus_write_byte(dev, 0xc4, 0x03);
212
213 /* ALL FAN critical temperature */
214 smbus_write_byte(dev, 0xc5, config->critical_temperature);
215
216 /* Temperature offset */
217 smbus_write_byte(dev, 0xa8, 0xf9);
218 smbus_write_byte(dev, 0xa9, 0xf9);
219 smbus_write_byte(dev, 0xaa, 0xf9);
220 smbus_write_byte(dev, 0xab, 0xf9);
221
Timothy Pearsond3e31be2015-02-21 01:45:35 -0600222 /* Default FAN speed */
223 smbus_write_byte(dev, 0xb2, fan_pct_to_cfg_val(config->default_speed));
224
225 /* Manual FAN speeds */
226 smbus_write_byte(dev, 0xb3, fan_pct_to_cfg_val(config->fan1_duty));
227 smbus_write_byte(dev, 0xb4, fan_pct_to_cfg_val(config->fan2_duty));
228 smbus_write_byte(dev, 0xb5, fan_pct_to_cfg_val(config->fan3_duty));
229 smbus_write_byte(dev, 0xb6, fan_pct_to_cfg_val(config->fan4_duty));
230 smbus_write_byte(dev, 0xb7, fan_pct_to_cfg_val(config->fan5_duty));
231 smbus_write_byte(dev, 0xb8, fan_pct_to_cfg_val(config->fan6_duty));
232 smbus_write_byte(dev, 0xb9, fan_pct_to_cfg_val(config->fan7_duty));
233 smbus_write_byte(dev, 0xba, fan_pct_to_cfg_val(config->fan8_duty));
234
Sven Schnelleca682972012-07-03 21:33:47 +0200235 /* BANK 2 */
236 smbus_write_byte(dev, 0x00, 0x02);
237
238 /* TD FAN select */
239 smbus_write_byte(dev, 0x01, config->td1_fan_select);
240 smbus_write_byte(dev, 0x02, config->td2_fan_select);
241 smbus_write_byte(dev, 0x03, config->td3_fan_select);
242 smbus_write_byte(dev, 0x04, config->td4_fan_select);
243
244 smbus_write_byte(dev, 0x05, config->tr1_fan_select);
245 smbus_write_byte(dev, 0x06, config->tr2_fan_select);
246
247 /* FAN control mode */
248 smbus_write_byte(dev, 0x07, 0x00);
249
250 /* hysteresis tolerance */
251 smbus_write_byte(dev, 0x08, 0xaa);
252 smbus_write_byte(dev, 0x09, 0xaa);
253
254 /* FanNonStop */
Timothy Pearsond3e31be2015-02-21 01:45:35 -0600255 smbus_write_byte(dev, 0x18, fan_pct_to_cfg_val(config->fan1_nonstop));
256 smbus_write_byte(dev, 0x19, fan_pct_to_cfg_val(config->fan2_nonstop));
257 smbus_write_byte(dev, 0x1a, fan_pct_to_cfg_val(config->fan3_nonstop));
258 smbus_write_byte(dev, 0x1b, fan_pct_to_cfg_val(config->fan4_nonstop));
259 smbus_write_byte(dev, 0x1c, fan_pct_to_cfg_val(config->fan5_nonstop));
260 smbus_write_byte(dev, 0x1d, fan_pct_to_cfg_val(config->fan6_nonstop));
261 smbus_write_byte(dev, 0x1e, fan_pct_to_cfg_val(config->fan7_nonstop));
262 smbus_write_byte(dev, 0x1f, fan_pct_to_cfg_val(config->fan8_nonstop));
Sven Schnelleca682972012-07-03 21:33:47 +0200263
264 /* FanStart */
265 smbus_write_byte(dev, 0x20, 0x08);
266 smbus_write_byte(dev, 0x21, 0x08);
267 smbus_write_byte(dev, 0x22, 0x08);
268 smbus_write_byte(dev, 0x23, 0x08);
269 smbus_write_byte(dev, 0x24, 0x08);
270 smbus_write_byte(dev, 0x25, 0x08);
271 smbus_write_byte(dev, 0x26, 0x08);
272 smbus_write_byte(dev, 0x27, 0x08);
273
274 for (i = 0; i < 4; i++)
275 w83793_td_level(dev, i, (const char[]){ 0x32, 0x32, 0x32, 0x32, 0x37, 0x41, 0x4b });
276
277 for (i = 0; i < 2; i++)
278 w83793_tr_level(dev, i, (const char[]){ 0x1e, 0x23, 0x28, 0x2d, 0x32, 0x37, 0x3c });
279
280 for (i = 0; i < 4; i++)
281 w83793_td_fan_level(dev, i, (const char[]){ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x26 });
282
283 for (i = 0; i < 2; i++)
284 w83793_tr_fan_level(dev, i, (const char[]){ 0x08, 0x0c, 0x10, 0x18, 0x20, 0x30, 0x38 });
285
286
287 smbus_write_byte(dev, 0x00, 0x00);
288
Sven Schnelleca682972012-07-03 21:33:47 +0200289 /* start monitoring operation */
290 smbus_write_byte(dev, 0x40, 0x09);
291
292}
293
Sven Schnelleca682972012-07-03 21:33:47 +0200294static struct device_operations w83793_operations = {
Edward O'Callaghan524625d2014-10-31 07:55:45 +1100295 .read_resources = DEVICE_NOOP,
296 .set_resources = DEVICE_NOOP,
Sven Schnelleca682972012-07-03 21:33:47 +0200297 .init = w83793_init,
298};
299
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100300static void enable_dev(struct device *dev)
Sven Schnelleca682972012-07-03 21:33:47 +0200301{
302 dev->ops = &w83793_operations;
303}
304
305struct chip_operations drivers_i2c_w83793_ops = {
306 CHIP_NAME("Nuvoton W83793 Hardware Monitor")
307 .enable_dev = enable_dev,
308};