21
#include "qemu/osdep.h"
23
#include "hw/i2c/pm_smbus.h"
24
#include "hw/i2c/smbus_master.h"
25
#include "migration/vmstate.h"
32
#define SMBHSTDAT0 0x05
33
#define SMBHSTDAT1 0x06
37
#define STS_HOST_BUSY (1 << 0)
38
#define STS_INTR (1 << 1)
39
#define STS_DEV_ERR (1 << 2)
40
#define STS_BUS_ERR (1 << 3)
41
#define STS_FAILED (1 << 4)
42
#define STS_SMBALERT (1 << 5)
43
#define STS_INUSE_STS (1 << 6)
44
#define STS_BYTE_DONE (1 << 7)
49
#define CTL_INTREN (1 << 0)
50
#define CTL_KILL (1 << 1)
51
#define CTL_LAST_BYTE (1 << 5)
52
#define CTL_START (1 << 6)
53
#define CTL_PEC_EN (1 << 7)
54
#define CTL_RETURN_MASK 0x1f
58
#define PROT_BYTE_DATA 2
59
#define PROT_WORD_DATA 3
60
#define PROT_PROC_CALL 4
61
#define PROT_BLOCK_DATA 5
62
#define PROT_I2C_BLOCK_READ 6
64
#define AUX_PEC (1 << 0)
65
#define AUX_BLK (1 << 1)
68
static void smb_transaction(PMSMBus *s)
70
uint8_t prot = (s->smb_ctl >> 2) & 0x07;
71
uint8_t read = s->smb_addr & 0x01;
72
uint8_t cmd = s->smb_cmd;
73
uint8_t addr = s->smb_addr >> 1;
74
I2CBus *bus = s->smbus;
77
trace_smbus_transaction(addr, prot);
79
if ((s->smb_stat & STS_DEV_ERR) != 0) {
85
ret = smbus_quick_command(bus, addr, read);
89
ret = smbus_receive_byte(bus, addr);
92
ret = smbus_send_byte(bus, addr, cmd);
97
ret = smbus_read_byte(bus, addr, cmd);
100
ret = smbus_write_byte(bus, addr, cmd, s->smb_data0);
106
ret = smbus_read_word(bus, addr, cmd);
109
ret = smbus_write_word(bus, addr, cmd,
110
(s->smb_data1 << 8) | s->smb_data0);
114
case PROT_I2C_BLOCK_READ:
123
if (i2c_start_send(bus, addr)) {
126
ret = i2c_send(bus, s->smb_data1);
130
if (i2c_start_recv(bus, addr)) {
133
s->in_i2c_block_read = true;
134
s->smb_blkdata = i2c_recv(s->smbus);
136
s->smb_stat |= STS_HOST_BUSY | STS_BYTE_DONE;
139
case PROT_BLOCK_DATA:
141
ret = smbus_read_block(bus, addr, cmd, s->smb_data,
142
sizeof(s->smb_data), !s->i2c_enable,
149
if (s->smb_auxctl & AUX_BLK) {
150
s->smb_stat |= STS_INTR;
152
s->smb_blkdata = s->smb_data[0];
153
s->smb_stat |= STS_HOST_BUSY | STS_BYTE_DONE;
158
if (s->smb_auxctl & AUX_BLK) {
159
if (s->smb_index != s->smb_data0) {
166
ret = smbus_write_block(bus, addr, cmd, s->smb_data,
167
s->smb_data0, !s->i2c_enable);
172
s->smb_stat |= STS_INTR;
173
s->smb_stat &= ~STS_HOST_BUSY;
176
s->smb_stat |= STS_HOST_BUSY | STS_BYTE_DONE;
177
s->smb_data[0] = s->smb_blkdata;
192
s->smb_data1 = ret >> 8;
202
s->smb_stat |= STS_INTR;
207
s->smb_stat |= STS_DEV_ERR;
211
static void smb_transaction_start(PMSMBus *s)
213
if (s->smb_ctl & CTL_INTREN) {
215
s->start_transaction_on_status_read = false;
224
s->smb_stat |= STS_HOST_BUSY;
225
s->start_transaction_on_status_read = true;
230
smb_irq_value(PMSMBus *s)
232
return ((s->smb_stat & ~STS_HOST_BUSY) != 0) && (s->smb_ctl & CTL_INTREN);
236
smb_byte_by_byte(PMSMBus *s)
241
if (s->in_i2c_block_read) {
244
return !(s->smb_auxctl & AUX_BLK);
247
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
251
uint8_t clear_byte_done;
253
trace_smbus_ioport_writeb(addr, val);
256
clear_byte_done = s->smb_stat & val & STS_BYTE_DONE;
257
s->smb_stat &= ~(val & ~STS_HOST_BUSY);
258
if (clear_byte_done && smb_byte_by_byte(s)) {
259
uint8_t read = s->smb_addr & 0x01;
261
if (s->in_i2c_block_read) {
267
if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
270
if (!read && s->smb_index == s->smb_data0) {
271
uint8_t prot = (s->smb_ctl >> 2) & 0x07;
272
uint8_t cmd = s->smb_cmd;
273
uint8_t smb_addr = s->smb_addr >> 1;
276
if (prot == PROT_I2C_BLOCK_READ) {
277
s->smb_stat |= STS_DEV_ERR;
281
ret = smbus_write_block(s->smbus, smb_addr, cmd, s->smb_data,
282
s->smb_data0, !s->i2c_enable);
284
s->smb_stat |= STS_DEV_ERR;
288
s->smb_stat |= STS_INTR;
289
s->smb_stat &= ~STS_HOST_BUSY;
291
s->smb_data[s->smb_index] = s->smb_blkdata;
292
s->smb_stat |= STS_BYTE_DONE;
293
} else if (s->smb_ctl & CTL_LAST_BYTE) {
295
if (s->in_i2c_block_read) {
296
s->in_i2c_block_read = false;
297
s->smb_blkdata = i2c_recv(s->smbus);
299
i2c_end_transfer(s->smbus);
301
s->smb_blkdata = s->smb_data[s->smb_index];
304
s->smb_stat |= STS_INTR;
305
s->smb_stat &= ~STS_HOST_BUSY;
307
if (s->in_i2c_block_read) {
308
s->smb_blkdata = i2c_recv(s->smbus);
310
s->smb_blkdata = s->smb_data[s->smb_index];
312
s->smb_stat |= STS_BYTE_DONE;
317
s->smb_ctl = val & ~CTL_START;
318
if (val & CTL_START) {
322
if (s->in_i2c_block_read) {
323
s->in_i2c_block_read = false;
324
i2c_end_transfer(s->smbus);
327
smb_transaction_start(s);
329
if (s->smb_ctl & CTL_KILL) {
332
s->smb_stat |= STS_FAILED;
333
s->smb_stat &= ~STS_HOST_BUSY;
349
if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
352
if (s->smb_auxctl & AUX_BLK) {
353
s->smb_data[s->smb_index++] = val;
355
s->smb_blkdata = val;
359
s->smb_auxctl = val & AUX_MASK;
367
s->set_irq(s, smb_irq_value(s));
371
static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
379
if (s->start_transaction_on_status_read) {
381
s->start_transaction_on_status_read = false;
382
s->smb_stat &= ~STS_HOST_BUSY;
387
val = s->smb_ctl & CTL_RETURN_MASK;
402
if (s->smb_auxctl & AUX_BLK && !s->in_i2c_block_read) {
403
if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
406
val = s->smb_data[s->smb_index++];
407
if (!s->op_done && s->smb_index == s->smb_data0) {
410
s->smb_stat &= ~STS_HOST_BUSY;
413
val = s->smb_blkdata;
423
trace_smbus_ioport_readb(addr, val);
426
s->set_irq(s, smb_irq_value(s));
432
static void pm_smbus_reset(PMSMBus *s)
439
static const MemoryRegionOps pm_smbus_ops = {
440
.read = smb_ioport_readb,
441
.write = smb_ioport_writeb,
442
.valid.min_access_size = 1,
443
.valid.max_access_size = 1,
444
.endianness = DEVICE_LITTLE_ENDIAN,
447
bool pm_smbus_vmstate_needed(void)
449
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
451
return !mc->smbus_no_migration_support;
454
const VMStateDescription pmsmb_vmstate = {
457
.minimum_version_id = 1,
458
.fields = (const VMStateField[]) {
459
VMSTATE_UINT8(smb_stat, PMSMBus),
460
VMSTATE_UINT8(smb_ctl, PMSMBus),
461
VMSTATE_UINT8(smb_cmd, PMSMBus),
462
VMSTATE_UINT8(smb_addr, PMSMBus),
463
VMSTATE_UINT8(smb_data0, PMSMBus),
464
VMSTATE_UINT8(smb_data1, PMSMBus),
465
VMSTATE_UINT32(smb_index, PMSMBus),
466
VMSTATE_UINT8_ARRAY(smb_data, PMSMBus, PM_SMBUS_MAX_MSG_SIZE),
467
VMSTATE_UINT8(smb_auxctl, PMSMBus),
468
VMSTATE_UINT8(smb_blkdata, PMSMBus),
469
VMSTATE_BOOL(i2c_enable, PMSMBus),
470
VMSTATE_BOOL(op_done, PMSMBus),
471
VMSTATE_BOOL(in_i2c_block_read, PMSMBus),
472
VMSTATE_BOOL(start_transaction_on_status_read, PMSMBus),
473
VMSTATE_END_OF_LIST()
477
void pm_smbus_init(DeviceState *parent, PMSMBus *smb, bool force_aux_blk)
480
smb->reset = pm_smbus_reset;
481
smb->smbus = i2c_init_bus(parent, "i2c");
483
smb->smb_auxctl |= AUX_BLK;
485
memory_region_init_io(&smb->io, OBJECT(parent), &pm_smbus_ops, smb,