aspeed_i3c.c (97fb7498129500fba37f90a3b9f088c884509028) aspeed_i3c.c (3816beda39596621ffabe6b9ea482aacdc63c1bc)
1/*
2 * ASPEED I3C Controller
3 *
4 * Copyright (C) 2021 ASPEED Technology Inc.
5 * Copyright (C) 2023 Google LLC
6 *
7 * This code is licensed under the GPL version 2 or later. See
8 * the COPYING file in the top-level directory.
9 */
10
11#include "qemu/osdep.h"
12#include "qemu/log.h"
13#include "qemu/error-report.h"
14#include "hw/i3c/aspeed_i3c.h"
15#include "hw/registerfields.h"
16#include "hw/qdev-properties.h"
17#include "qapi/error.h"
18#include "migration/vmstate.h"
19#include "trace.h"
1/*
2 * ASPEED I3C Controller
3 *
4 * Copyright (C) 2021 ASPEED Technology Inc.
5 * Copyright (C) 2023 Google LLC
6 *
7 * This code is licensed under the GPL version 2 or later. See
8 * the COPYING file in the top-level directory.
9 */
10
11#include "qemu/osdep.h"
12#include "qemu/log.h"
13#include "qemu/error-report.h"
14#include "hw/i3c/aspeed_i3c.h"
15#include "hw/registerfields.h"
16#include "hw/qdev-properties.h"
17#include "qapi/error.h"
18#include "migration/vmstate.h"
19#include "trace.h"
20#include "hw/i3c/i3c.h"
21#include "hw/irq.h"
20
21/* I3C Controller Registers */
22REG32(I3C1_REG0, 0x10)
23REG32(I3C1_REG1, 0x14)
24 FIELD(I3C1_REG1, I2C_MODE, 0, 1)
25 FIELD(I3C1_REG1, SLV_TEST_MODE, 1, 1)
26 FIELD(I3C1_REG1, ACT_MODE, 2, 2)
27 FIELD(I3C1_REG1, PENDING_INT, 4, 4)

--- 379 unchanged lines hidden (view full) ---

407 [R_SCL_I3C_PP_TIMING] = 0xff00ff00,
408 [R_SCL_I2C_FMP_TIMING] = 0xff000000,
409 [R_SCL_EXT_TERMN_LCNT_TIMING] = 0x0000fff0,
410 [R_BUS_IDLE_TIMING] = 0xfff00000,
411 [R_EXTENDED_CAPABILITY] = 0xffffffff,
412 [R_SLAVE_CONFIG] = 0xffffffff,
413};
414
22
23/* I3C Controller Registers */
24REG32(I3C1_REG0, 0x10)
25REG32(I3C1_REG1, 0x14)
26 FIELD(I3C1_REG1, I2C_MODE, 0, 1)
27 FIELD(I3C1_REG1, SLV_TEST_MODE, 1, 1)
28 FIELD(I3C1_REG1, ACT_MODE, 2, 2)
29 FIELD(I3C1_REG1, PENDING_INT, 4, 4)

--- 379 unchanged lines hidden (view full) ---

409 [R_SCL_I3C_PP_TIMING] = 0xff00ff00,
410 [R_SCL_I2C_FMP_TIMING] = 0xff000000,
411 [R_SCL_EXT_TERMN_LCNT_TIMING] = 0x0000fff0,
412 [R_BUS_IDLE_TIMING] = 0xfff00000,
413 [R_EXTENDED_CAPABILITY] = 0xffffffff,
414 [R_SLAVE_CONFIG] = 0xffffffff,
415};
416
417static void aspeed_i3c_device_update_irq(AspeedI3CDevice *s)
418{
419 bool level = !!(s->regs[R_INTR_SIGNAL_EN] & s->regs[R_INTR_STATUS]);
420 qemu_set_irq(s->irq, level);
421}
422
423static uint32_t aspeed_i3c_device_intr_status_r(AspeedI3CDevice *s)
424{
425 /* Only return the status whose corresponding EN bits are set. */
426 return s->regs[R_INTR_STATUS] & s->regs[R_INTR_STATUS_EN];
427}
428
429static void aspeed_i3c_device_intr_status_w(AspeedI3CDevice *s, uint32_t val)
430{
431 /* INTR_STATUS[13:5] is w1c, other bits are RO. */
432 val &= 0x3fe0;
433 s->regs[R_INTR_STATUS] &= ~val;
434
435 aspeed_i3c_device_update_irq(s);
436}
437
438static void aspeed_i3c_device_intr_status_en_w(AspeedI3CDevice *s, uint32_t val)
439{
440 s->regs[R_INTR_STATUS_EN] = val;
441 aspeed_i3c_device_update_irq(s);
442}
443
444static void aspeed_i3c_device_intr_signal_en_w(AspeedI3CDevice *s, uint32_t val)
445{
446 s->regs[R_INTR_SIGNAL_EN] = val;
447 aspeed_i3c_device_update_irq(s);
448}
449
450static void aspeed_i3c_device_intr_force_w(AspeedI3CDevice *s, uint32_t val)
451{
452 /* INTR_FORCE is WO, just set the corresponding INTR_STATUS bits. */
453 s->regs[R_INTR_STATUS] = val;
454 aspeed_i3c_device_update_irq(s);
455}
456
415static uint64_t aspeed_i3c_device_read(void *opaque, hwaddr offset,
416 unsigned size)
417{
418 AspeedI3CDevice *s = ASPEED_I3C_DEVICE(opaque);
419 uint32_t addr = offset >> 2;
420 uint64_t value;
421
422 switch (addr) {
423 /* RAZ */
424 case R_COMMAND_QUEUE_PORT:
425 case R_RESET_CTRL:
426 case R_INTR_FORCE:
427 value = 0;
428 break;
457static uint64_t aspeed_i3c_device_read(void *opaque, hwaddr offset,
458 unsigned size)
459{
460 AspeedI3CDevice *s = ASPEED_I3C_DEVICE(opaque);
461 uint32_t addr = offset >> 2;
462 uint64_t value;
463
464 switch (addr) {
465 /* RAZ */
466 case R_COMMAND_QUEUE_PORT:
467 case R_RESET_CTRL:
468 case R_INTR_FORCE:
469 value = 0;
470 break;
471 case R_INTR_STATUS:
472 value = aspeed_i3c_device_intr_status_r(s);
473 break;
429 default:
430 value = s->regs[addr];
431 break;
432 }
433
434 trace_aspeed_i3c_device_read(s->id, offset, value);
435
436 return value;

--- 28 unchanged lines hidden (view full) ---

465 "%s: write to readonly register[0x%02" HWADDR_PRIx
466 "] = 0x%08" PRIx64 "\n",
467 __func__, offset, value);
468 break;
469 case R_RX_TX_DATA_PORT:
470 break;
471 case R_RESET_CTRL:
472 break;
474 default:
475 value = s->regs[addr];
476 break;
477 }
478
479 trace_aspeed_i3c_device_read(s->id, offset, value);
480
481 return value;

--- 28 unchanged lines hidden (view full) ---

510 "%s: write to readonly register[0x%02" HWADDR_PRIx
511 "] = 0x%08" PRIx64 "\n",
512 __func__, offset, value);
513 break;
514 case R_RX_TX_DATA_PORT:
515 break;
516 case R_RESET_CTRL:
517 break;
518 case R_INTR_STATUS:
519 aspeed_i3c_device_intr_status_w(s, val32);
520 break;
521 case R_INTR_STATUS_EN:
522 aspeed_i3c_device_intr_status_en_w(s, val32);
523 break;
524 case R_INTR_SIGNAL_EN:
525 aspeed_i3c_device_intr_signal_en_w(s, val32);
526 break;
527 case R_INTR_FORCE:
528 aspeed_i3c_device_intr_force_w(s, val32);
529 break;
473 default:
474 s->regs[addr] = val32;
475 break;
476 }
477}
478
479static const VMStateDescription aspeed_i3c_device_vmstate = {
480 .name = TYPE_ASPEED_I3C,

--- 217 unchanged lines hidden ---
530 default:
531 s->regs[addr] = val32;
532 break;
533 }
534}
535
536static const VMStateDescription aspeed_i3c_device_vmstate = {
537 .name = TYPE_ASPEED_I3C,

--- 217 unchanged lines hidden ---