master
c 594 lines 17.1 KB
Raw
1 /*
2 * QEMU PowerPC PowerNV Processor I2C model
3 *
4 * Copyright (c) 2019-2023, IBM Corporation.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include "qemu/osdep.h"
10 #include "qemu/module.h"
11 #include "qemu/log.h"
12 #include "system/reset.h"
13
14 #include "hw/core/irq.h"
15 #include "hw/core/qdev-properties.h"
16
17 #include "hw/ppc/pnv.h"
18 #include "hw/ppc/pnv_chip.h"
19 #include "hw/ppc/pnv_i2c.h"
20 #include "hw/ppc/pnv_xscom.h"
21 #include "hw/ppc/fdt.h"
22 #include "migration/vmstate.h"
23
24 #include <libfdt.h>
25
26 #include "hw/i2c/pnv_i2c_regs.h"
27
28 static I2CBus *pnv_i2c_get_bus(PnvI2C *i2c)
29 {
30 uint8_t port = GETFIELD(I2C_MODE_PORT_NUM, i2c->regs[I2C_MODE_REG]);
31
32 if (port >= i2c->num_busses) {
33 qemu_log_mask(LOG_GUEST_ERROR, "I2C: invalid bus number %d/%d\n", port,
34 i2c->num_busses);
35 return NULL;
36 }
37 return i2c->busses[port];
38 }
39
40 static void pnv_i2c_update_irq(PnvI2C *i2c)
41 {
42 I2CBus *bus = pnv_i2c_get_bus(i2c);
43 bool recv = !!(i2c->regs[I2C_CMD_REG] & I2C_CMD_READ_NOT_WRITE);
44 uint16_t front_end = GETFIELD(I2C_RESIDUAL_FRONT_END,
45 i2c->regs[I2C_RESIDUAL_LEN_REG]);
46 uint16_t back_end = GETFIELD(I2C_RESIDUAL_BACK_END,
47 i2c->regs[I2C_RESIDUAL_LEN_REG]);
48 uint8_t fifo_count = GETFIELD(I2C_STAT_FIFO_ENTRY_COUNT,
49 i2c->regs[I2C_STAT_REG]);
50 uint8_t fifo_free = PNV_I2C_FIFO_SIZE - fifo_count;
51
52 if (!bus) {
53 qemu_log_mask(LOG_GUEST_ERROR, "I2C: invalid port\n");
54 return;
55 }
56
57 if (i2c_bus_busy(bus)) {
58 i2c->regs[I2C_STAT_REG] &= ~I2C_STAT_DATA_REQ;
59
60 if (recv) {
61 if (fifo_count >=
62 GETFIELD(I2C_WATERMARK_HIGH, i2c->regs[I2C_WATERMARK_REG])) {
63 i2c->regs[I2C_EXTD_STAT_REG] |= I2C_EXTD_STAT_HIGH_WATER;
64 } else {
65 i2c->regs[I2C_EXTD_STAT_REG] &= ~I2C_EXTD_STAT_HIGH_WATER;
66 }
67
68 if (((i2c->regs[I2C_EXTD_STAT_REG] & I2C_EXTD_STAT_HIGH_WATER) &&
69 fifo_count != 0) || front_end == 0) {
70 i2c->regs[I2C_STAT_REG] |= I2C_STAT_DATA_REQ;
71 }
72 } else {
73 if (fifo_count <=
74 GETFIELD(I2C_WATERMARK_LOW, i2c->regs[I2C_WATERMARK_REG])) {
75 i2c->regs[I2C_EXTD_STAT_REG] |= I2C_EXTD_STAT_LOW_WATER;
76 } else {
77 i2c->regs[I2C_EXTD_STAT_REG] &= ~I2C_EXTD_STAT_LOW_WATER;
78 }
79
80 if (back_end > 0 &&
81 (fifo_free >= back_end ||
82 (i2c->regs[I2C_EXTD_STAT_REG] & I2C_EXTD_STAT_LOW_WATER))) {
83 i2c->regs[I2C_STAT_REG] |= I2C_STAT_DATA_REQ;
84 }
85 }
86
87 if (back_end == 0 && front_end == 0) {
88 i2c->regs[I2C_STAT_REG] &= ~I2C_STAT_DATA_REQ;
89 i2c->regs[I2C_STAT_REG] |= I2C_STAT_CMD_COMP;
90
91 if (i2c->regs[I2C_CMD_REG] & I2C_CMD_WITH_STOP) {
92 i2c_end_transfer(bus);
93 i2c->regs[I2C_EXTD_STAT_REG] &=
94 ~(I2C_EXTD_STAT_I2C_BUSY | I2C_EXTD_STAT_SELF_BUSY);
95 }
96 } else {
97 i2c->regs[I2C_STAT_REG] &= ~I2C_STAT_CMD_COMP;
98 }
99 }
100
101 /*
102 * Status and interrupt registers have nearly the same layout.
103 */
104 i2c->regs[I2C_INTR_RAW_COND_REG] = i2c->regs[I2C_STAT_REG] >> 16;
105 i2c->regs[I2C_INTR_COND_REG] =
106 i2c->regs[I2C_INTR_RAW_COND_REG] & i2c->regs[I2C_INTR_MASK_REG];
107
108 qemu_set_irq(i2c->psi_irq, i2c->regs[I2C_INTR_COND_REG] != 0);
109 }
110
111 static void pnv_i2c_fifo_update_count(PnvI2C *i2c)
112 {
113 uint64_t stat = i2c->regs[I2C_STAT_REG];
114
115 i2c->regs[I2C_STAT_REG] = SETFIELD(I2C_STAT_FIFO_ENTRY_COUNT, stat,
116 fifo8_num_used(&i2c->fifo));
117 }
118
119 static void pnv_i2c_frontend_update(PnvI2C *i2c)
120 {
121 uint64_t residual_end = i2c->regs[I2C_RESIDUAL_LEN_REG];
122 uint16_t front_end = GETFIELD(I2C_RESIDUAL_FRONT_END, residual_end);
123
124 i2c->regs[I2C_RESIDUAL_LEN_REG] =
125 SETFIELD(I2C_RESIDUAL_FRONT_END, residual_end, front_end - 1);
126 }
127
128 static void pnv_i2c_fifo_flush(PnvI2C *i2c)
129 {
130 I2CBus *bus = pnv_i2c_get_bus(i2c);
131 uint8_t data;
132 int ret;
133
134 if (!bus) {
135 qemu_log_mask(LOG_GUEST_ERROR, "I2C: invalid port\n");
136 return;
137 }
138 if (!i2c_bus_busy(bus)) {
139 return;
140 }
141
142 if (i2c->regs[I2C_CMD_REG] & I2C_CMD_READ_NOT_WRITE) {
143 if (fifo8_is_full(&i2c->fifo)) {
144 return;
145 }
146
147 data = i2c_recv(bus);
148 fifo8_push(&i2c->fifo, data);
149 } else {
150 if (fifo8_is_empty(&i2c->fifo)) {
151 return;
152 }
153
154 data = fifo8_pop(&i2c->fifo);
155 ret = i2c_send(bus, data);
156 if (ret) {
157 i2c->regs[I2C_STAT_REG] |= I2C_STAT_NACK_RCVD_ERR;
158 i2c_end_transfer(bus);
159 }
160 }
161
162 pnv_i2c_fifo_update_count(i2c);
163 pnv_i2c_frontend_update(i2c);
164 }
165
166 static void pnv_i2c_handle_cmd(PnvI2C *i2c, uint64_t val)
167 {
168 I2CBus *bus = pnv_i2c_get_bus(i2c);
169 uint8_t addr = GETFIELD(I2C_CMD_DEV_ADDR, val);
170 int recv = !!(val & I2C_CMD_READ_NOT_WRITE);
171 uint32_t len_bytes = GETFIELD(I2C_CMD_LEN_BYTES, val);
172
173 if (!(val & I2C_CMD_WITH_START) && !(val & I2C_CMD_WITH_ADDR) &&
174 !(val & I2C_CMD_WITH_STOP) && !len_bytes) {
175 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
176 qemu_log_mask(LOG_GUEST_ERROR, "I2C: invalid command 0x%"PRIx64"\n",
177 val);
178 return;
179 }
180
181 if (!(i2c->regs[I2C_STAT_REG] & I2C_STAT_CMD_COMP)) {
182 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
183 qemu_log_mask(LOG_GUEST_ERROR, "I2C: command in progress\n");
184 return;
185 }
186
187 if (!bus) {
188 qemu_log_mask(LOG_GUEST_ERROR, "I2C: invalid port\n");
189 return;
190 }
191
192 i2c->regs[I2C_RESIDUAL_LEN_REG] =
193 SETFIELD(I2C_RESIDUAL_FRONT_END, 0ull, len_bytes) |
194 SETFIELD(I2C_RESIDUAL_BACK_END, 0ull, len_bytes);
195
196 if (val & I2C_CMD_WITH_START) {
197 if (i2c_start_transfer(bus, addr, recv)) {
198 i2c->regs[I2C_STAT_REG] |= I2C_STAT_NACK_RCVD_ERR;
199 } else {
200 i2c->regs[I2C_EXTD_STAT_REG] |=
201 (I2C_EXTD_STAT_I2C_BUSY | I2C_EXTD_STAT_SELF_BUSY);
202 pnv_i2c_fifo_flush(i2c);
203 }
204 }
205 }
206
207 static void pnv_i2c_backend_update(PnvI2C *i2c)
208 {
209 uint64_t residual_end = i2c->regs[I2C_RESIDUAL_LEN_REG];
210 uint16_t back_end = GETFIELD(I2C_RESIDUAL_BACK_END, residual_end);
211
212 if (!back_end) {
213 i2c->regs[I2C_STAT_REG] |= I2C_STAT_BKEND_ACCESS_ERR;
214 return;
215 }
216
217 i2c->regs[I2C_RESIDUAL_LEN_REG] =
218 SETFIELD(I2C_RESIDUAL_BACK_END, residual_end, back_end - 1);
219 }
220
221 static void pnv_i2c_fifo_in(PnvI2C *i2c)
222 {
223 uint8_t data = GETFIELD(I2C_FIFO, i2c->regs[I2C_FIFO_REG]);
224 I2CBus *bus = pnv_i2c_get_bus(i2c);
225
226 if (!bus) {
227 qemu_log_mask(LOG_GUEST_ERROR, "I2C: invalid port\n");
228 return;
229 }
230
231 if (!i2c_bus_busy(bus)) {
232 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
233 qemu_log_mask(LOG_GUEST_ERROR, "I2C: no command in progress\n");
234 return;
235 }
236
237 if (i2c->regs[I2C_CMD_REG] & I2C_CMD_READ_NOT_WRITE) {
238 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
239 qemu_log_mask(LOG_GUEST_ERROR, "I2C: read command in progress\n");
240 return;
241 }
242
243 if (fifo8_is_full(&i2c->fifo)) {
244 if (!(i2c->regs[I2C_MODE_REG] & I2C_MODE_PACING_ALLOW)) {
245 i2c->regs[I2C_STAT_REG] |= I2C_STAT_BKEND_OVERRUN_ERR;
246 }
247 return;
248 }
249
250 fifo8_push(&i2c->fifo, data);
251 pnv_i2c_fifo_update_count(i2c);
252 pnv_i2c_backend_update(i2c);
253 pnv_i2c_fifo_flush(i2c);
254 }
255
256 static void pnv_i2c_fifo_out(PnvI2C *i2c)
257 {
258 uint8_t data;
259 I2CBus *bus = pnv_i2c_get_bus(i2c);
260
261 if (!bus) {
262 qemu_log_mask(LOG_GUEST_ERROR, "I2C: invalid port\n");
263 return;
264 }
265
266 if (!i2c_bus_busy(bus)) {
267 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
268 qemu_log_mask(LOG_GUEST_ERROR, "I2C: no command in progress\n");
269 return;
270 }
271
272 if (!(i2c->regs[I2C_CMD_REG] & I2C_CMD_READ_NOT_WRITE)) {
273 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
274 qemu_log_mask(LOG_GUEST_ERROR, "I2C: write command in progress\n");
275 return;
276 }
277
278 if (fifo8_is_empty(&i2c->fifo)) {
279 if (!(i2c->regs[I2C_MODE_REG] & I2C_MODE_PACING_ALLOW)) {
280 i2c->regs[I2C_STAT_REG] |= I2C_STAT_BKEND_OVERRUN_ERR;
281 }
282 return;
283 }
284
285 data = fifo8_pop(&i2c->fifo);
286
287 i2c->regs[I2C_FIFO_REG] = SETFIELD(I2C_FIFO, 0ull, data);
288 pnv_i2c_fifo_update_count(i2c);
289 pnv_i2c_backend_update(i2c);
290 }
291
292 static uint64_t pnv_i2c_xscom_read(void *opaque, hwaddr addr,
293 unsigned size)
294 {
295 PnvI2C *i2c = PNV_I2C(opaque);
296 uint32_t offset = addr >> 3;
297 uint64_t val = -1;
298 int i;
299
300 switch (offset) {
301 case I2C_STAT_REG:
302 val = i2c->regs[offset];
303 break;
304
305 case I2C_FIFO_REG:
306 pnv_i2c_fifo_out(i2c);
307 val = i2c->regs[offset];
308 break;
309
310 case I2C_PORT_BUSY_REG: /* compute busy bit for each port */
311 val = 0;
312 for (i = 0; i < i2c->num_busses; i++) {
313 val |= (uint64_t)i2c_bus_busy(i2c->busses[i]) << i;
314 }
315 break;
316
317 case I2C_CMD_REG:
318 case I2C_MODE_REG:
319 case I2C_WATERMARK_REG:
320 case I2C_INTR_MASK_REG:
321 case I2C_INTR_RAW_COND_REG:
322 case I2C_INTR_COND_REG:
323 case I2C_EXTD_STAT_REG:
324 case I2C_RESIDUAL_LEN_REG:
325 val = i2c->regs[offset];
326 break;
327 default:
328 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
329 qemu_log_mask(LOG_GUEST_ERROR, "I2C: read at register: 0x%"
330 HWADDR_PRIx "\n", addr >> 3);
331 }
332
333 pnv_i2c_update_irq(i2c);
334
335 return val;
336 }
337
338 static void pnv_i2c_reset(void *dev)
339 {
340 PnvI2C *i2c = PNV_I2C(dev);
341
342 memset(i2c->regs, 0, sizeof(i2c->regs));
343
344 i2c->regs[I2C_STAT_REG] =
345 SETFIELD(I2C_STAT_UPPER_THRS, 0ull, i2c->num_busses - 1) |
346 I2C_STAT_CMD_COMP | I2C_STAT_SCL_INPUT_LEVEL |
347 I2C_STAT_SDA_INPUT_LEVEL;
348 i2c->regs[I2C_EXTD_STAT_REG] =
349 SETFIELD(I2C_EXTD_STAT_FIFO_SIZE, 0ull, PNV_I2C_FIFO_SIZE) |
350 SETFIELD(I2C_EXTD_STAT_I2C_VERSION, 0ull, 23); /* last version */
351
352 fifo8_reset(&i2c->fifo);
353 }
354
355 static void pnv_i2c_xscom_write(void *opaque, hwaddr addr,
356 uint64_t val, unsigned size)
357 {
358 PnvI2C *i2c = PNV_I2C(opaque);
359 uint32_t offset = addr >> 3;
360
361 switch (offset) {
362 case I2C_MODE_REG:
363 {
364 i2c->regs[offset] = val;
365 I2CBus *bus = pnv_i2c_get_bus(i2c);
366 if (!bus) {
367 qemu_log_mask(LOG_GUEST_ERROR, "I2C: invalid port\n");
368 return;
369 }
370 if (i2c_bus_busy(bus)) {
371 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
372 qemu_log_mask(LOG_GUEST_ERROR, "I2C: command in progress\n");
373 }
374 }
375 break;
376
377 case I2C_CMD_REG:
378 i2c->regs[offset] = val;
379 pnv_i2c_handle_cmd(i2c, val);
380 break;
381
382 case I2C_FIFO_REG:
383 i2c->regs[offset] = val;
384 pnv_i2c_fifo_in(i2c);
385 break;
386
387 case I2C_WATERMARK_REG:
388 i2c->regs[offset] = val;
389 break;
390
391 case I2C_RESET_I2C_REG:
392 pnv_i2c_reset(i2c);
393 break;
394
395 case I2C_RESET_ERRORS:
396 i2c->regs[I2C_STAT_REG] &= ~I2C_STAT_ANY_ERR;
397 i2c->regs[I2C_RESIDUAL_LEN_REG] = 0;
398 i2c->regs[I2C_EXTD_STAT_REG] &=
399 (I2C_EXTD_STAT_FIFO_SIZE | I2C_EXTD_STAT_I2C_VERSION);
400 fifo8_reset(&i2c->fifo);
401 break;
402
403 case I2C_INTR_MASK_REG:
404 i2c->regs[offset] = val;
405 break;
406
407 case I2C_INTR_MASK_OR_REG:
408 i2c->regs[I2C_INTR_MASK_REG] |= val;
409 break;
410
411 case I2C_INTR_MASK_AND_REG:
412 i2c->regs[I2C_INTR_MASK_REG] &= val;
413 break;
414
415 case I2C_PORT_BUSY_REG:
416 case I2C_SET_S_SCL_REG:
417 case I2C_RESET_S_SCL_REG:
418 case I2C_SET_S_SDA_REG:
419 case I2C_RESET_S_SDA_REG:
420 i2c->regs[offset] = val;
421 break;
422 default:
423 i2c->regs[I2C_STAT_REG] |= I2C_STAT_INVALID_CMD;
424 qemu_log_mask(LOG_GUEST_ERROR, "I2C: write at register: 0x%"
425 HWADDR_PRIx " val=0x%"PRIx64"\n", addr >> 3, val);
426 }
427
428 pnv_i2c_update_irq(i2c);
429 }
430
431 static const MemoryRegionOps pnv_i2c_xscom_ops = {
432 .read = pnv_i2c_xscom_read,
433 .write = pnv_i2c_xscom_write,
434 .valid.min_access_size = 8,
435 .valid.max_access_size = 8,
436 .impl.min_access_size = 8,
437 .impl.max_access_size = 8,
438 .endianness = DEVICE_BIG_ENDIAN,
439 };
440
441 static int pnv_i2c_bus_dt_xscom(PnvI2C *i2c, void *fdt,
442 int offset, int index)
443 {
444 int i2c_bus_offset;
445 const char i2c_compat[] =
446 "ibm,opal-i2c\0ibm,power8-i2c-port\0ibm,power9-i2c-port";
447 g_autofree char *i2c_port_name = NULL;
448 g_autofree char *name = g_strdup_printf("i2c-bus@%x", index);
449
450 i2c_bus_offset = fdt_add_subnode(fdt, offset, name);
451 _FDT(i2c_bus_offset);
452
453 _FDT((fdt_setprop_cell(fdt, i2c_bus_offset, "reg", index)));
454 _FDT((fdt_setprop_cell(fdt, i2c_bus_offset, "#address-cells", 1)));
455 _FDT((fdt_setprop_cell(fdt, i2c_bus_offset, "#size-cells", 0)));
456 _FDT(fdt_setprop(fdt, i2c_bus_offset, "compatible", i2c_compat,
457 sizeof(i2c_compat)));
458 _FDT((fdt_setprop_cell(fdt, i2c_bus_offset, "bus-frequency", 400000)));
459
460 i2c_port_name = g_strdup_printf("p8_%08x_e%dp%d", i2c->chip->chip_id,
461 i2c->engine, index);
462 _FDT(fdt_setprop_string(fdt, i2c_bus_offset, "ibm,port-name",
463 i2c_port_name));
464 return 0;
465 }
466
467 #define XSCOM_BUS_FREQUENCY 466500000
468 #define I2C_CLOCK_FREQUENCY (XSCOM_BUS_FREQUENCY / 4)
469
470 static int pnv_i2c_dt_xscom(PnvXScomInterface *dev, void *fdt,
471 int offset)
472 {
473 PnvI2C *i2c = PNV_I2C(dev);
474 int i2c_offset;
475 const char i2c_compat[] = "ibm,power8-i2cm\0ibm,power9-i2cm";
476 uint32_t i2c_pcba = PNV9_XSCOM_I2CM_BASE +
477 (i2c->engine - 1) * PNV9_XSCOM_I2CM_SIZE;
478 uint32_t reg[2] = {
479 cpu_to_be32(i2c_pcba),
480 cpu_to_be32(PNV9_XSCOM_I2CM_SIZE)
481 };
482 int i;
483 g_autofree char *name = g_strdup_printf("i2cm@%x", i2c_pcba);
484
485 i2c_offset = fdt_add_subnode(fdt, offset, name);
486 _FDT(i2c_offset);
487
488 _FDT(fdt_setprop(fdt, i2c_offset, "reg", reg, sizeof(reg)));
489
490 _FDT((fdt_setprop_cell(fdt, i2c_offset, "#address-cells", 1)));
491 _FDT((fdt_setprop_cell(fdt, i2c_offset, "#size-cells", 0)));
492 _FDT(fdt_setprop(fdt, i2c_offset, "compatible", i2c_compat,
493 sizeof(i2c_compat)));
494 _FDT((fdt_setprop_cell(fdt, i2c_offset, "chip-engine#", i2c->engine)));
495 _FDT((fdt_setprop_cell(fdt, i2c_offset, "clock-frequency",
496 I2C_CLOCK_FREQUENCY)));
497
498 for (i = 0; i < i2c->num_busses; i++) {
499 pnv_i2c_bus_dt_xscom(i2c, fdt, i2c_offset, i);
500 }
501 return 0;
502 }
503
504 static void pnv_i2c_sys_reset(void *dev)
505 {
506 int port;
507 PnvI2C *i2c = PNV_I2C(dev);
508
509 pnv_i2c_reset(dev);
510
511 /* reset all buses connected to this i2c controller */
512 for (port = 0; port < i2c->num_busses; port++) {
513 bus_cold_reset(BUS(i2c->busses[port]));
514 }
515 }
516
517 static void pnv_i2c_realize(DeviceState *dev, Error **errp)
518 {
519 PnvI2C *i2c = PNV_I2C(dev);
520 int i;
521
522 assert(i2c->chip);
523
524 if (i2c->num_busses > PNV_I2C_MAX_BUSSES) {
525 error_setg(errp, "Invalid number of busses: %u", i2c->num_busses);
526 return;
527 }
528
529 pnv_xscom_region_init(&i2c->xscom_regs, OBJECT(i2c), &pnv_i2c_xscom_ops,
530 i2c, "xscom-i2c", PNV9_XSCOM_I2CM_SIZE);
531
532 i2c->busses = g_new(I2CBus *, i2c->num_busses);
533 for (i = 0; i < i2c->num_busses; i++) {
534 char name[32];
535
536 snprintf(name, sizeof(name), TYPE_PNV_I2C ".%d", i);
537 i2c->busses[i] = i2c_init_bus(dev, name);
538 }
539
540 fifo8_create(&i2c->fifo, PNV_I2C_FIFO_SIZE);
541
542 qemu_register_reset(pnv_i2c_sys_reset, dev);
543
544 qdev_init_gpio_out(DEVICE(dev), &i2c->psi_irq, 1);
545 }
546
547 static const Property pnv_i2c_properties[] = {
548 DEFINE_PROP_LINK("chip", PnvI2C, chip, TYPE_PNV_CHIP, PnvChip *),
549 DEFINE_PROP_UINT32("engine", PnvI2C, engine, 1),
550 DEFINE_PROP_UINT32("num-busses", PnvI2C, num_busses, 1),
551 };
552
553 static const VMStateDescription pnv_i2c_vmstate = {
554 .name = TYPE_PNV_I2C,
555 .version_id = 1,
556 .fields = (const VMStateField[]) {
557 VMSTATE_UINT64_ARRAY(regs, PnvI2C, PNV_I2C_REGS),
558 VMSTATE_END_OF_LIST(),
559 },
560 };
561
562 static void pnv_i2c_class_init(ObjectClass *klass, const void *data)
563 {
564 DeviceClass *dc = DEVICE_CLASS(klass);
565 PnvXScomInterfaceClass *xscomc = PNV_XSCOM_INTERFACE_CLASS(klass);
566
567 xscomc->dt_xscom = pnv_i2c_dt_xscom;
568
569 /* Reason: This device is part of the CPU and cannot be used separately */
570 dc->user_creatable = false;
571
572 dc->desc = "PowerNV I2C";
573 dc->realize = pnv_i2c_realize;
574 dc->vmsd = &pnv_i2c_vmstate;
575 device_class_set_props(dc, pnv_i2c_properties);
576 }
577
578 static const TypeInfo pnv_i2c_info = {
579 .name = TYPE_PNV_I2C,
580 .parent = TYPE_DEVICE,
581 .instance_size = sizeof(PnvI2C),
582 .class_init = pnv_i2c_class_init,
583 .interfaces = (const InterfaceInfo[]) {
584 { TYPE_PNV_XSCOM_INTERFACE },
585 { }
586 }
587 };
588
589 static void pnv_i2c_register_types(void)
590 {
591 type_register_static(&pnv_i2c_info);
592 }
593
594 type_init(pnv_i2c_register_types);