1
2
3
4
5
6
7
8
9#ifndef HW_PMBUS_DEVICE_H
10#define HW_PMBUS_DEVICE_H
11
12#include "qemu/bitops.h"
13#include "hw/i2c/smbus_slave.h"
14
15enum pmbus_registers {
16 PMBUS_PAGE = 0x00,
17 PMBUS_OPERATION = 0x01,
18 PMBUS_ON_OFF_CONFIG = 0x02,
19 PMBUS_CLEAR_FAULTS = 0x03,
20 PMBUS_PHASE = 0x04,
21 PMBUS_PAGE_PLUS_WRITE = 0x05,
22 PMBUS_PAGE_PLUS_READ = 0x06,
23 PMBUS_WRITE_PROTECT = 0x10,
24 PMBUS_STORE_DEFAULT_ALL = 0x11,
25 PMBUS_RESTORE_DEFAULT_ALL = 0x12,
26 PMBUS_STORE_DEFAULT_CODE = 0x13,
27 PMBUS_RESTORE_DEFAULT_CODE = 0x14,
28 PMBUS_STORE_USER_ALL = 0x15,
29 PMBUS_RESTORE_USER_ALL = 0x16,
30 PMBUS_STORE_USER_CODE = 0x17,
31 PMBUS_RESTORE_USER_CODE = 0x18,
32 PMBUS_CAPABILITY = 0x19,
33 PMBUS_QUERY = 0x1A,
34 PMBUS_SMBALERT_MASK = 0x1B,
35 PMBUS_VOUT_MODE = 0x20,
36 PMBUS_VOUT_COMMAND = 0x21,
37 PMBUS_VOUT_TRIM = 0x22,
38 PMBUS_VOUT_CAL_OFFSET = 0x23,
39 PMBUS_VOUT_MAX = 0x24,
40 PMBUS_VOUT_MARGIN_HIGH = 0x25,
41 PMBUS_VOUT_MARGIN_LOW = 0x26,
42 PMBUS_VOUT_TRANSITION_RATE = 0x27,
43 PMBUS_VOUT_DROOP = 0x28,
44 PMBUS_VOUT_SCALE_LOOP = 0x29,
45 PMBUS_VOUT_SCALE_MONITOR = 0x2A,
46 PMBUS_COEFFICIENTS = 0x30,
47 PMBUS_POUT_MAX = 0x31,
48 PMBUS_MAX_DUTY = 0x32,
49 PMBUS_FREQUENCY_SWITCH = 0x33,
50 PMBUS_VIN_ON = 0x35,
51 PMBUS_VIN_OFF = 0x36,
52 PMBUS_INTERLEAVE = 0x37,
53 PMBUS_IOUT_CAL_GAIN = 0x38,
54 PMBUS_IOUT_CAL_OFFSET = 0x39,
55 PMBUS_FAN_CONFIG_1_2 = 0x3A,
56 PMBUS_FAN_COMMAND_1 = 0x3B,
57 PMBUS_FAN_COMMAND_2 = 0x3C,
58 PMBUS_FAN_CONFIG_3_4 = 0x3D,
59 PMBUS_FAN_COMMAND_3 = 0x3E,
60 PMBUS_FAN_COMMAND_4 = 0x3F,
61 PMBUS_VOUT_OV_FAULT_LIMIT = 0x40,
62 PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41,
63 PMBUS_VOUT_OV_WARN_LIMIT = 0x42,
64 PMBUS_VOUT_UV_WARN_LIMIT = 0x43,
65 PMBUS_VOUT_UV_FAULT_LIMIT = 0x44,
66 PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45,
67 PMBUS_IOUT_OC_FAULT_LIMIT = 0x46,
68 PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47,
69 PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48,
70 PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49,
71 PMBUS_IOUT_OC_WARN_LIMIT = 0x4A,
72 PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B,
73 PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C,
74 PMBUS_OT_FAULT_LIMIT = 0x4F,
75 PMBUS_OT_FAULT_RESPONSE = 0x50,
76 PMBUS_OT_WARN_LIMIT = 0x51,
77 PMBUS_UT_WARN_LIMIT = 0x52,
78 PMBUS_UT_FAULT_LIMIT = 0x53,
79 PMBUS_UT_FAULT_RESPONSE = 0x54,
80 PMBUS_VIN_OV_FAULT_LIMIT = 0x55,
81 PMBUS_VIN_OV_FAULT_RESPONSE = 0x56,
82 PMBUS_VIN_OV_WARN_LIMIT = 0x57,
83 PMBUS_VIN_UV_WARN_LIMIT = 0x58,
84 PMBUS_VIN_UV_FAULT_LIMIT = 0x59,
85 PMBUS_VIN_UV_FAULT_RESPONSE = 0x5A,
86 PMBUS_IIN_OC_FAULT_LIMIT = 0x5B,
87 PMBUS_IIN_OC_FAULT_RESPONSE = 0x5C,
88 PMBUS_IIN_OC_WARN_LIMIT = 0x5D,
89 PMBUS_POWER_GOOD_ON = 0x5E,
90 PMBUS_POWER_GOOD_OFF = 0x5F,
91 PMBUS_TON_DELAY = 0x60,
92 PMBUS_TON_RISE = 0x61,
93 PMBUS_TON_MAX_FAULT_LIMIT = 0x62,
94 PMBUS_TON_MAX_FAULT_RESPONSE = 0x63,
95 PMBUS_TOFF_DELAY = 0x64,
96 PMBUS_TOFF_FALL = 0x65,
97 PMBUS_TOFF_MAX_WARN_LIMIT = 0x66,
98 PMBUS_POUT_OP_FAULT_LIMIT = 0x68,
99 PMBUS_POUT_OP_FAULT_RESPONSE = 0x69,
100 PMBUS_POUT_OP_WARN_LIMIT = 0x6A,
101 PMBUS_PIN_OP_WARN_LIMIT = 0x6B,
102 PMBUS_STATUS_BYTE = 0x78,
103 PMBUS_STATUS_WORD = 0x79,
104 PMBUS_STATUS_VOUT = 0x7A,
105 PMBUS_STATUS_IOUT = 0x7B,
106 PMBUS_STATUS_INPUT = 0x7C,
107 PMBUS_STATUS_TEMPERATURE = 0x7D,
108 PMBUS_STATUS_CML = 0x7E,
109 PMBUS_STATUS_OTHER = 0x7F,
110 PMBUS_STATUS_MFR_SPECIFIC = 0x80,
111 PMBUS_STATUS_FANS_1_2 = 0x81,
112 PMBUS_STATUS_FANS_3_4 = 0x82,
113 PMBUS_READ_EIN = 0x86,
114 PMBUS_READ_EOUT = 0x87,
115 PMBUS_READ_VIN = 0x88,
116 PMBUS_READ_IIN = 0x89,
117 PMBUS_READ_VCAP = 0x8A,
118 PMBUS_READ_VOUT = 0x8B,
119 PMBUS_READ_IOUT = 0x8C,
120 PMBUS_READ_TEMPERATURE_1 = 0x8D,
121 PMBUS_READ_TEMPERATURE_2 = 0x8E,
122 PMBUS_READ_TEMPERATURE_3 = 0x8F,
123 PMBUS_READ_FAN_SPEED_1 = 0x90,
124 PMBUS_READ_FAN_SPEED_2 = 0x91,
125 PMBUS_READ_FAN_SPEED_3 = 0x92,
126 PMBUS_READ_FAN_SPEED_4 = 0x93,
127 PMBUS_READ_DUTY_CYCLE = 0x94,
128 PMBUS_READ_FREQUENCY = 0x95,
129 PMBUS_READ_POUT = 0x96,
130 PMBUS_READ_PIN = 0x97,
131 PMBUS_REVISION = 0x98,
132 PMBUS_MFR_ID = 0x99,
133 PMBUS_MFR_MODEL = 0x9A,
134 PMBUS_MFR_REVISION = 0x9B,
135 PMBUS_MFR_LOCATION = 0x9C,
136 PMBUS_MFR_DATE = 0x9D,
137 PMBUS_MFR_SERIAL = 0x9E,
138 PMBUS_APP_PROFILE_SUPPORT = 0x9F,
139 PMBUS_MFR_VIN_MIN = 0xA0,
140 PMBUS_MFR_VIN_MAX = 0xA1,
141 PMBUS_MFR_IIN_MAX = 0xA2,
142 PMBUS_MFR_PIN_MAX = 0xA3,
143 PMBUS_MFR_VOUT_MIN = 0xA4,
144 PMBUS_MFR_VOUT_MAX = 0xA5,
145 PMBUS_MFR_IOUT_MAX = 0xA6,
146 PMBUS_MFR_POUT_MAX = 0xA7,
147 PMBUS_MFR_TAMBIENT_MAX = 0xA8,
148 PMBUS_MFR_TAMBIENT_MIN = 0xA9,
149 PMBUS_MFR_EFFICIENCY_LL = 0xAA,
150 PMBUS_MFR_EFFICIENCY_HL = 0xAB,
151 PMBUS_MFR_PIN_ACCURACY = 0xAC,
152 PMBUS_IC_DEVICE_ID = 0xAD,
153 PMBUS_IC_DEVICE_REV = 0xAE,
154 PMBUS_MFR_MAX_TEMP_1 = 0xC0,
155 PMBUS_MFR_MAX_TEMP_2 = 0xC1,
156 PMBUS_MFR_MAX_TEMP_3 = 0xC2,
157};
158
159
160#define PB_STATUS_VOUT BIT(15)
161#define PB_STATUS_IOUT_POUT BIT(14)
162#define PB_STATUS_INPUT BIT(13)
163#define PB_STATUS_WORD_MFR BIT(12)
164#define PB_STATUS_POWER_GOOD_N BIT(11)
165#define PB_STATUS_FAN BIT(10)
166#define PB_STATUS_OTHER BIT(9)
167#define PB_STATUS_UNKNOWN BIT(8)
168
169#define PB_STATUS_BUSY BIT(7)
170#define PB_STATUS_OFF BIT(6)
171#define PB_STATUS_VOUT_OV BIT(5)
172#define PB_STATUS_IOUT_OC BIT(4)
173#define PB_STATUS_VIN_UV BIT(3)
174#define PB_STATUS_TEMPERATURE BIT(2)
175#define PB_STATUS_CML BIT(1)
176#define PB_STATUS_NONE_ABOVE BIT(0)
177
178
179#define PB_STATUS_VOUT_OV_FAULT BIT(7)
180#define PB_STATUS_VOUT_OV_WARN BIT(6)
181#define PB_STATUS_VOUT_UV_WARN BIT(5)
182#define PB_STATUS_VOUT_UV_FAULT BIT(4)
183#define PB_STATUS_VOUT_MAX BIT(3)
184#define PB_STATUS_VOUT_TON_MAX_FAULT BIT(2)
185#define PB_STATUS_VOUT_TOFF_MAX_WARN BIT(1)
186
187
188#define PB_STATUS_IOUT_OC_FAULT BIT(7)
189#define PB_STATUS_IOUT_OC_LV_FAULT BIT(6)
190#define PB_STATUS_IOUT_OC_WARN BIT(5)
191#define PB_STATUS_IOUT_UC_FAULT BIT(4)
192#define PB_STATUS_CURR_SHARE BIT(3)
193#define PB_STATUS_PWR_LIM_MODE BIT(2)
194#define PB_STATUS_POUT_OP_FAULT BIT(1)
195#define PB_STATUS_POUT_OP_WARN BIT(0)
196
197
198#define PB_STATUS_INPUT_VIN_OV_FAULT BIT(7)
199#define PB_STATUS_INPUT_VIN_OV_WARN BIT(6)
200#define PB_STATUS_INPUT_VIN_UV_WARN BIT(5)
201#define PB_STATUS_INPUT_VIN_UV_FAULT BIT(4)
202#define PB_STATUS_INPUT_IIN_OC_FAULT BIT(2)
203#define PB_STATUS_INPUT_IIN_OC_WARN BIT(1)
204#define PB_STATUS_INPUT_PIN_OP_WARN BIT(0)
205
206
207#define PB_STATUS_OT_FAULT BIT(7)
208#define PB_STATUS_OT_WARN BIT(6)
209#define PB_STATUS_UT_WARN BIT(5)
210#define PB_STATUS_UT_FAULT BIT(4)
211
212
213#define PB_CML_FAULT_INVALID_CMD BIT(7)
214#define PB_CML_FAULT_INVALID_DATA BIT(6)
215#define PB_CML_FAULT_PEC BIT(5)
216#define PB_CML_FAULT_MEMORY BIT(4)
217#define PB_CML_FAULT_PROCESSOR BIT(3)
218#define PB_CML_FAULT_OTHER_COMM BIT(1)
219#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0)
220
221
222#define PB_OP_ON BIT(7)
223#define PB_OP_MARGIN_HIGH BIT(5)
224#define PB_OP_MARGIN_LOW BIT(4)
225
226
227#define PB_MAX_PAGES 0x1F
228#define PB_ALL_PAGES 0xFF
229
230#define TYPE_PMBUS_DEVICE "pmbus-device"
231OBJECT_DECLARE_TYPE(PMBusDevice, PMBusDeviceClass,
232 PMBUS_DEVICE)
233
234
235#define PB_HAS_COEFFICIENTS BIT_ULL(9)
236#define PB_HAS_VIN BIT_ULL(10)
237#define PB_HAS_VOUT BIT_ULL(11)
238#define PB_HAS_VOUT_MARGIN BIT_ULL(12)
239#define PB_HAS_VIN_RATING BIT_ULL(13)
240#define PB_HAS_VOUT_RATING BIT_ULL(14)
241#define PB_HAS_VOUT_MODE BIT_ULL(15)
242#define PB_HAS_IOUT BIT_ULL(21)
243#define PB_HAS_IIN BIT_ULL(22)
244#define PB_HAS_IOUT_RATING BIT_ULL(23)
245#define PB_HAS_IIN_RATING BIT_ULL(24)
246#define PB_HAS_IOUT_GAIN BIT_ULL(25)
247#define PB_HAS_POUT BIT_ULL(30)
248#define PB_HAS_PIN BIT_ULL(31)
249#define PB_HAS_EIN BIT_ULL(32)
250#define PB_HAS_EOUT BIT_ULL(33)
251#define PB_HAS_POUT_RATING BIT_ULL(34)
252#define PB_HAS_PIN_RATING BIT_ULL(35)
253#define PB_HAS_TEMPERATURE BIT_ULL(40)
254#define PB_HAS_TEMP2 BIT_ULL(41)
255#define PB_HAS_TEMP3 BIT_ULL(42)
256#define PB_HAS_TEMP_RATING BIT_ULL(43)
257#define PB_HAS_MFR_INFO BIT_ULL(50)
258
259struct PMBusDeviceClass {
260 SMBusDeviceClass parent_class;
261 uint8_t device_num_pages;
262
263
264
265
266
267 void (*quick_cmd)(PMBusDevice *dev, uint8_t read);
268 int (*write_data)(PMBusDevice *dev, const uint8_t *buf, uint8_t len);
269 uint8_t (*receive_byte)(PMBusDevice *dev);
270};
271
272
273
274
275
276
277
278
279typedef struct PMBusPage {
280 uint64_t page_flags;
281
282 uint8_t page;
283 uint8_t operation;
284 uint8_t on_off_config;
285 uint8_t write_protect;
286 uint8_t phase;
287 uint8_t vout_mode;
288 uint16_t vout_command;
289 uint16_t vout_trim;
290 uint16_t vout_cal_offset;
291 uint16_t vout_max;
292 uint16_t vout_margin_high;
293 uint16_t vout_margin_low;
294 uint16_t vout_transition_rate;
295 uint16_t vout_droop;
296 uint16_t vout_scale_loop;
297 uint16_t vout_scale_monitor;
298 uint8_t coefficients[5];
299 uint16_t pout_max;
300 uint16_t max_duty;
301 uint16_t frequency_switch;
302 uint16_t vin_on;
303 uint16_t vin_off;
304 uint16_t iout_cal_gain;
305 uint16_t iout_cal_offset;
306 uint8_t fan_config_1_2;
307 uint16_t fan_command_1;
308 uint16_t fan_command_2;
309 uint8_t fan_config_3_4;
310 uint16_t fan_command_3;
311 uint16_t fan_command_4;
312 uint16_t vout_ov_fault_limit;
313 uint8_t vout_ov_fault_response;
314 uint16_t vout_ov_warn_limit;
315 uint16_t vout_uv_warn_limit;
316 uint16_t vout_uv_fault_limit;
317 uint8_t vout_uv_fault_response;
318 uint16_t iout_oc_fault_limit;
319 uint8_t iout_oc_fault_response;
320 uint16_t iout_oc_lv_fault_limit;
321 uint8_t iout_oc_lv_fault_response;
322 uint16_t iout_oc_warn_limit;
323 uint16_t iout_uc_fault_limit;
324 uint8_t iout_uc_fault_response;
325 uint16_t ot_fault_limit;
326 uint8_t ot_fault_response;
327 uint16_t ot_warn_limit;
328 uint16_t ut_warn_limit;
329 uint16_t ut_fault_limit;
330 uint8_t ut_fault_response;
331 uint16_t vin_ov_fault_limit;
332 uint8_t vin_ov_fault_response;
333 uint16_t vin_ov_warn_limit;
334 uint16_t vin_uv_warn_limit;
335 uint16_t vin_uv_fault_limit;
336 uint8_t vin_uv_fault_response;
337 uint16_t iin_oc_fault_limit;
338 uint8_t iin_oc_fault_response;
339 uint16_t iin_oc_warn_limit;
340 uint16_t power_good_on;
341 uint16_t power_good_off;
342 uint16_t ton_delay;
343 uint16_t ton_rise;
344 uint16_t ton_max_fault_limit;
345 uint8_t ton_max_fault_response;
346 uint16_t toff_delay;
347 uint16_t toff_fall;
348 uint16_t toff_max_warn_limit;
349 uint16_t pout_op_fault_limit;
350 uint8_t pout_op_fault_response;
351 uint16_t pout_op_warn_limit;
352 uint16_t pin_op_warn_limit;
353 uint16_t status_word;
354 uint8_t status_vout;
355 uint8_t status_iout;
356 uint8_t status_input;
357 uint8_t status_temperature;
358 uint8_t status_cml;
359 uint8_t status_other;
360 uint8_t status_mfr_specific;
361 uint8_t status_fans_1_2;
362 uint8_t status_fans_3_4;
363 uint8_t read_ein[5];
364 uint8_t read_eout[5];
365 uint16_t read_vin;
366 uint16_t read_iin;
367 uint16_t read_vcap;
368 uint16_t read_vout;
369 uint16_t read_iout;
370 uint16_t read_temperature_1;
371 uint16_t read_temperature_2;
372 uint16_t read_temperature_3;
373 uint16_t read_fan_speed_1;
374 uint16_t read_fan_speed_2;
375 uint16_t read_fan_speed_3;
376 uint16_t read_fan_speed_4;
377 uint16_t read_duty_cycle;
378 uint16_t read_frequency;
379 uint16_t read_pout;
380 uint16_t read_pin;
381 uint8_t revision;
382 const char *mfr_id;
383 const char *mfr_model;
384 const char *mfr_revision;
385 const char *mfr_location;
386 const char *mfr_date;
387 const char *mfr_serial;
388 const char *app_profile_support;
389 uint16_t mfr_vin_min;
390 uint16_t mfr_vin_max;
391 uint16_t mfr_iin_max;
392 uint16_t mfr_pin_max;
393 uint16_t mfr_vout_min;
394 uint16_t mfr_vout_max;
395 uint16_t mfr_iout_max;
396 uint16_t mfr_pout_max;
397 uint16_t mfr_tambient_max;
398 uint16_t mfr_tambient_min;
399 uint8_t mfr_efficiency_ll[14];
400 uint8_t mfr_efficiency_hl[14];
401 uint8_t mfr_pin_accuracy;
402 uint16_t mfr_max_temp_1;
403 uint16_t mfr_max_temp_2;
404 uint16_t mfr_max_temp_3;
405} PMBusPage;
406
407
408struct PMBusDevice {
409 SMBusDevice smb;
410
411 uint8_t num_pages;
412 uint8_t code;
413 uint8_t page;
414
415
416
417
418
419 PMBusPage *pages;
420 uint8_t capability;
421
422
423 int32_t in_buf_len;
424 uint8_t *in_buf;
425 int32_t out_buf_len;
426 uint8_t out_buf[SMBUS_DATA_MAX_LEN];
427};
428
429
430
431
432
433
434
435typedef struct PMBusCoefficients {
436 int32_t m;
437 int64_t b;
438 int32_t R;
439} PMBusCoefficients;
440
441
442
443
444
445
446
447
448uint16_t pmbus_data2direct_mode(PMBusCoefficients c, uint32_t value);
449
450
451
452
453
454
455
456
457uint32_t pmbus_direct_mode2data(PMBusCoefficients c, uint16_t value);
458
459
460
461
462
463
464
465
466
467
468void pmbus_send(PMBusDevice *state, const uint8_t *data, uint16_t len);
469void pmbus_send8(PMBusDevice *state, uint8_t data);
470void pmbus_send16(PMBusDevice *state, uint16_t data);
471void pmbus_send32(PMBusDevice *state, uint32_t data);
472void pmbus_send64(PMBusDevice *state, uint64_t data);
473
474
475
476
477
478void pmbus_send_string(PMBusDevice *state, const char *data);
479
480
481
482
483
484
485uint8_t pmbus_receive8(PMBusDevice *pmdev);
486uint16_t pmbus_receive16(PMBusDevice *pmdev);
487uint32_t pmbus_receive32(PMBusDevice *pmdev);
488uint64_t pmbus_receive64(PMBusDevice *pmdev);
489
490
491
492
493
494
495
496
497
498int pmbus_page_config(PMBusDevice *pmdev, uint8_t page_index, uint64_t flags);
499
500
501
502
503
504
505void pmbus_check_limits(PMBusDevice *pmdev);
506
507extern const VMStateDescription vmstate_pmbus_device;
508
509#define VMSTATE_PMBUS_DEVICE(_field, _state) { \
510 .name = (stringify(_field)), \
511 .size = sizeof(PMBusDevice), \
512 .vmsd = &vmstate_pmbus_device, \
513 .flags = VMS_STRUCT, \
514 .offset = vmstate_offset_value(_state, _field, PMBusDevice), \
515}
516
517#endif
518