aspeed_i3c.c (4ba253763710dd997c1b6590ba70344d60e082e5) aspeed_i3c.c (93ec69491130ed0a9daa6a9107bb3bbdfc7e9e23)
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.

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

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"
22
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.

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

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"
22
23/*
24 * Disable event command values. sent along with a DISEC CCC to disable certain
25 * events on targets.
26 */
27#define DISEC_HJ 0x08
28#define DISEC_CR 0x02
29#define DISEC_INT 0x01
30
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)
30 FIELD(I3C1_REG1, SA, 8, 7)

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

439 !ARRAY_FIELD_EX32(s->regs, DEVICE_CTRL, I3C_RESUME);
440}
441
442static inline uint8_t aspeed_i3c_device_fifo_threshold_from_reg(uint8_t regval)
443{
444 return regval = regval ? (2 << regval) : 1;
445}
446
31/* I3C Controller Registers */
32REG32(I3C1_REG0, 0x10)
33REG32(I3C1_REG1, 0x14)
34 FIELD(I3C1_REG1, I2C_MODE, 0, 1)
35 FIELD(I3C1_REG1, SLV_TEST_MODE, 1, 1)
36 FIELD(I3C1_REG1, ACT_MODE, 2, 2)
37 FIELD(I3C1_REG1, PENDING_INT, 4, 4)
38 FIELD(I3C1_REG1, SA, 8, 7)

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

447 !ARRAY_FIELD_EX32(s->regs, DEVICE_CTRL, I3C_RESUME);
448}
449
450static inline uint8_t aspeed_i3c_device_fifo_threshold_from_reg(uint8_t regval)
451{
452 return regval = regval ? (2 << regval) : 1;
453}
454
455static inline uint8_t aspeed_i3c_device_ibi_slice_size(AspeedI3CDevice *s)
456{
457 uint8_t ibi_slice_size = ARRAY_FIELD_EX32(s->regs, QUEUE_THLD_CTRL,
458 IBI_DATA_THLD);
459 /* The minimum supported slice size is 4 bytes. */
460 if (ibi_slice_size == 0) {
461 ibi_slice_size = 1;
462 }
463 ibi_slice_size *= sizeof(uint32_t);
464 /* maximum supported size is 63 bytes. */
465 if (ibi_slice_size >= 64) {
466 ibi_slice_size = 63;
467 }
468
469 return ibi_slice_size;
470}
471
447static void aspeed_i3c_device_update_irq(AspeedI3CDevice *s)
448{
449 bool level = !!(s->regs[R_INTR_SIGNAL_EN] & s->regs[R_INTR_STATUS]);
450 qemu_set_irq(s->irq, level);
451}
452
453static void aspeed_i3c_device_end_transfer(AspeedI3CDevice *s, bool is_i2c)
454{

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

586 if (aspeed_i3c_device_target_is_i2c(s, offset)) {
587 return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1,
588 DEV_STATIC_ADDR);
589 }
590 return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1,
591 DEV_DYNAMIC_ADDR);
592}
593
472static void aspeed_i3c_device_update_irq(AspeedI3CDevice *s)
473{
474 bool level = !!(s->regs[R_INTR_SIGNAL_EN] & s->regs[R_INTR_STATUS]);
475 qemu_set_irq(s->irq, level);
476}
477
478static void aspeed_i3c_device_end_transfer(AspeedI3CDevice *s, bool is_i2c)
479{

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

611 if (aspeed_i3c_device_target_is_i2c(s, offset)) {
612 return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1,
613 DEV_STATIC_ADDR);
614 }
615 return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1,
616 DEV_DYNAMIC_ADDR);
617}
618
619static int aspeed_i3c_device_addr_table_index_from_addr(AspeedI3CDevice *s,
620 uint8_t addr)
621{
622 uint8_t table_size = ARRAY_FIELD_EX32(s->regs, DEVICE_ADDR_TABLE_POINTER,
623 DEPTH);
624 for (uint8_t i = 0; i < table_size; i++) {
625 if (aspeed_i3c_device_target_addr(s, i) == addr) {
626 return i;
627 }
628 }
629 return -1;
630}
631
632static void aspeed_i3c_device_send_disec(AspeedI3CDevice *s)
633{
634 uint8_t ccc = I3C_CCC_DISEC;
635 if (s->ibi_data.send_direct_disec) {
636 ccc = I3C_CCCD_DISEC;
637 }
638
639 aspeed_i3c_device_send_start(s, I3C_BROADCAST, /*is_recv=*/false,
640 /*is_i2c=*/false);
641 aspeed_i3c_device_send_byte(s, ccc, /*is_i2c=*/false);
642 if (s->ibi_data.send_direct_disec) {
643 aspeed_i3c_device_send_start(s, s->ibi_data.disec_addr,
644 /*is_recv=*/false, /*is_i2c=*/false);
645 }
646 aspeed_i3c_device_send_byte(s, s->ibi_data.disec_byte, /*is_i2c=*/false);
647}
648
649static int aspeed_i3c_device_handle_hj(AspeedI3CDevice *s)
650{
651 if (ARRAY_FIELD_EX32(s->regs, IBI_QUEUE_CTRL, NOTIFY_REJECTED_HOT_JOIN)) {
652 s->ibi_data.notify_ibi_nack = true;
653 }
654
655 bool nack_and_disable = ARRAY_FIELD_EX32(s->regs, DEVICE_CTRL,
656 HOT_JOIN_ACK_NACK_CTRL);
657 if (nack_and_disable) {
658 s->ibi_data.ibi_queue_status = FIELD_DP32(s->ibi_data.ibi_queue_status,
659 IBI_QUEUE_STATUS,
660 IBI_STATUS, 1);
661 s->ibi_data.ibi_nacked = true;
662 s->ibi_data.disec_byte = DISEC_HJ;
663 return -1;
664 }
665 return 0;
666}
667
668static int aspeed_i3c_device_handle_ctlr_req(AspeedI3CDevice *s, uint8_t addr)
669{
670 if (ARRAY_FIELD_EX32(s->regs, IBI_QUEUE_CTRL, NOTIFY_REJECTED_MASTER_REQ)) {
671 s->ibi_data.notify_ibi_nack = true;
672 }
673
674 int table_offset = aspeed_i3c_device_addr_table_index_from_addr(s, addr);
675 /* Doesn't exist in the table, NACK it, don't DISEC. */
676 if (table_offset < 0) {
677 return -1;
678 }
679
680 table_offset += R_DEVICE_ADDR_TABLE_LOC1;
681 if (FIELD_EX32(s->regs[table_offset], DEVICE_ADDR_TABLE_LOC1, MR_REJECT)) {
682 s->ibi_data.ibi_queue_status = FIELD_DP32(s->ibi_data.ibi_queue_status,
683 IBI_QUEUE_STATUS,
684 IBI_STATUS, 1);
685 s->ibi_data.ibi_nacked = true;
686 s->ibi_data.disec_addr = addr;
687 /* Tell the requester to disable controller role requests. */
688 s->ibi_data.disec_byte = DISEC_CR;
689 s->ibi_data.send_direct_disec = true;
690 return -1;
691 }
692 return 0;
693}
694
695static int aspeed_i3c_device_handle_targ_irq(AspeedI3CDevice *s, uint8_t addr)
696{
697 if (ARRAY_FIELD_EX32(s->regs, IBI_QUEUE_CTRL, NOTIFY_REJECTED_SLAVE_IRQ)) {
698 s->ibi_data.notify_ibi_nack = true;
699 }
700
701 int table_offset = aspeed_i3c_device_addr_table_index_from_addr(s, addr);
702 /* Doesn't exist in the table, NACK it, don't DISEC. */
703 if (table_offset < 0) {
704 return -1;
705 }
706
707 table_offset += R_DEVICE_ADDR_TABLE_LOC1;
708 if (FIELD_EX32(s->regs[table_offset], DEVICE_ADDR_TABLE_LOC1, SIR_REJECT)) {
709 s->ibi_data.ibi_queue_status = FIELD_DP32(s->ibi_data.ibi_queue_status,
710 IBI_QUEUE_STATUS,
711 IBI_STATUS, 1);
712 s->ibi_data.ibi_nacked = true;
713 s->ibi_data.disec_addr = addr;
714 /* Tell the requester to disable interrupts. */
715 s->ibi_data.disec_byte = DISEC_INT;
716 s->ibi_data.send_direct_disec = true;
717 return -1;
718 }
719 return 0;
720}
721
722static int aspeed_i3c_device_ibi_handle(I3CBus *bus, I3CTarget *target,
723 uint8_t addr, bool is_recv)
724{
725 AspeedI3CDevice *s = ASPEED_I3C_DEVICE(bus->qbus.parent);
726
727 trace_aspeed_i3c_device_ibi_handle(s->id, addr, is_recv);
728 s->ibi_data.ibi_queue_status = FIELD_DP32(s->ibi_data.ibi_queue_status,
729 IBI_QUEUE_STATUS, IBI_ID,
730 (addr << 1) | is_recv);
731 /* Is this a hot join request? */
732 if (addr == I3C_HJ_ADDR) {
733 return aspeed_i3c_device_handle_hj(s);
734 }
735 /* Is secondary controller requesting access? */
736 if (addr == target->address && !is_recv) {
737 return aspeed_i3c_device_handle_ctlr_req(s, addr);
738 }
739 /* Is this a target IRQ? */
740 if (addr == target->address && is_recv) {
741 return aspeed_i3c_device_handle_targ_irq(s, addr);
742 }
743
744 /* Not sure what this is, NACK it. */
745 return -1;
746}
747
748static int aspeed_i3c_device_ibi_recv(I3CBus *bus, uint8_t data)
749{
750 AspeedI3CDevice *s = ASPEED_I3C_DEVICE(bus->qbus.parent);
751 if (fifo8_is_full(&s->ibi_data.ibi_intermediate_queue)) {
752 return -1;
753 }
754
755 fifo8_push(&s->ibi_data.ibi_intermediate_queue, data);
756 trace_aspeed_i3c_device_ibi_recv(s->id, data);
757 return 0;
758}
759
760static void aspeed_i3c_device_ibi_queue_push(AspeedI3CDevice *s)
761{
762 /* Stored value is in 32-bit chunks, convert it to byte chunks. */
763 uint8_t ibi_slice_size = aspeed_i3c_device_ibi_slice_size(s);
764 uint8_t num_slices = fifo8_num_used(&s->ibi_data.ibi_intermediate_queue) /
765 ibi_slice_size;
766 uint8_t ibi_status_count = num_slices;
767 union {
768 uint8_t b[sizeof(uint32_t)];
769 uint32_t val32;
770 } ibi_data = {
771 .val32 = 0
772 };
773
774 /* The report was suppressed, do nothing. */
775 if (s->ibi_data.ibi_nacked && !s->ibi_data.notify_ibi_nack) {
776 ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
777 ASPEED_I3C_TRANSFER_STATE_IDLE);
778 ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_STATUS,
779 ASPEED_I3C_TRANSFER_STATUS_IDLE);
780 return;
781 }
782
783 /* If we don't have any slices to push, just push the status. */
784 if (num_slices == 0) {
785 s->ibi_data.ibi_queue_status =
786 FIELD_DP32(s->ibi_data.ibi_queue_status, IBI_QUEUE_STATUS,
787 LAST_STATUS, 1);
788 fifo32_push(&s->ibi_queue, s->ibi_data.ibi_queue_status);
789 ibi_status_count = 1;
790 }
791
792 for (uint8_t i = 0; i < num_slices; i++) {
793 /* If this is the last slice, set LAST_STATUS. */
794 if (fifo8_num_used(&s->ibi_data.ibi_intermediate_queue) <
795 ibi_slice_size) {
796 s->ibi_data.ibi_queue_status =
797 FIELD_DP32(s->ibi_data.ibi_queue_status, IBI_QUEUE_STATUS,
798 IBI_DATA_LEN,
799 fifo8_num_used(&s->ibi_data.ibi_intermediate_queue));
800 s->ibi_data.ibi_queue_status =
801 FIELD_DP32(s->ibi_data.ibi_queue_status, IBI_QUEUE_STATUS,
802 LAST_STATUS, 1);
803 } else {
804 s->ibi_data.ibi_queue_status =
805 FIELD_DP32(s->ibi_data.ibi_queue_status, IBI_QUEUE_STATUS,
806 IBI_DATA_LEN, ibi_slice_size);
807 }
808
809 /* Push the IBI status header. */
810 fifo32_push(&s->ibi_queue, s->ibi_data.ibi_queue_status);
811 /* Move each IBI byte into a 32-bit word and push it into the queue. */
812 for (uint8_t j = 0; j < ibi_slice_size; ++j) {
813 if (fifo8_is_empty(&s->ibi_data.ibi_intermediate_queue)) {
814 break;
815 }
816
817 ibi_data.b[j & 3] = fifo8_pop(&s->ibi_data.ibi_intermediate_queue);
818 /* We have 32-bits, push it to the IBI FIFO. */
819 if ((j & 0x03) == 0x03) {
820 fifo32_push(&s->ibi_queue, ibi_data.val32);
821 ibi_data.val32 = 0;
822 }
823 }
824 /* If the data isn't 32-bit aligned, push the leftover bytes. */
825 if (ibi_slice_size & 0x03) {
826 fifo32_push(&s->ibi_queue, ibi_data.val32);
827 }
828
829 /* Clear out the data length for the next iteration. */
830 s->ibi_data.ibi_queue_status = FIELD_DP32(s->ibi_data.ibi_queue_status,
831 IBI_QUEUE_STATUS, IBI_DATA_LEN, 0);
832 }
833
834 ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, IBI_BUF_BLR,
835 fifo32_num_used(&s->ibi_queue));
836 ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, IBI_STATUS_CNT,
837 ibi_status_count);
838 /* Threshold is the register value + 1. */
839 uint8_t threshold = ARRAY_FIELD_EX32(s->regs, QUEUE_THLD_CTRL,
840 IBI_STATUS_THLD) + 1;
841 if (fifo32_num_used(&s->ibi_queue) >= threshold) {
842 ARRAY_FIELD_DP32(s->regs, INTR_STATUS, IBI_THLD, 1);
843 aspeed_i3c_device_update_irq(s);
844 }
845
846 /* State update. */
847 ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
848 ASPEED_I3C_TRANSFER_STATE_IDLE);
849 ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_STATUS,
850 ASPEED_I3C_TRANSFER_STATUS_IDLE);
851}
852
853static int aspeed_i3c_device_ibi_finish(I3CBus *bus)
854{
855 AspeedI3CDevice *s = ASPEED_I3C_DEVICE(bus->qbus.parent);
856 bool nack_and_disable_hj = ARRAY_FIELD_EX32(s->regs, DEVICE_CTRL,
857 HOT_JOIN_ACK_NACK_CTRL);
858 if (nack_and_disable_hj || s->ibi_data.send_direct_disec) {
859 aspeed_i3c_device_send_disec(s);
860 }
861 aspeed_i3c_device_ibi_queue_push(s);
862
863 /* Clear out the intermediate values. */
864 s->ibi_data.ibi_queue_status = 0;
865 s->ibi_data.disec_addr = 0;
866 s->ibi_data.disec_byte = 0;
867 s->ibi_data.send_direct_disec = false;
868 s->ibi_data.notify_ibi_nack = false;
869 s->ibi_data.ibi_nacked = false;
870
871 return 0;
872}
873
594static uint32_t aspeed_i3c_device_intr_status_r(AspeedI3CDevice *s)
595{
596 /* Only return the status whose corresponding EN bits are set. */
597 return s->regs[R_INTR_STATUS] & s->regs[R_INTR_STATUS_EN];
598}
599
600static void aspeed_i3c_device_intr_status_w(AspeedI3CDevice *s, uint32_t val)
601{

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

645 ARRAY_FIELD_DP32(s->regs, INTR_STATUS, RX_THLD, 0);
646 aspeed_i3c_device_update_irq(s);
647 }
648
649 trace_aspeed_i3c_device_pop_rx(s->id, val);
650 return val;
651}
652
874static uint32_t aspeed_i3c_device_intr_status_r(AspeedI3CDevice *s)
875{
876 /* Only return the status whose corresponding EN bits are set. */
877 return s->regs[R_INTR_STATUS] & s->regs[R_INTR_STATUS_EN];
878}
879
880static void aspeed_i3c_device_intr_status_w(AspeedI3CDevice *s, uint32_t val)
881{

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

925 ARRAY_FIELD_DP32(s->regs, INTR_STATUS, RX_THLD, 0);
926 aspeed_i3c_device_update_irq(s);
927 }
928
929 trace_aspeed_i3c_device_pop_rx(s->id, val);
930 return val;
931}
932
933static uint32_t aspeed_i3c_device_ibi_queue_r(AspeedI3CDevice *s)
934{
935 if (fifo32_is_empty(&s->ibi_queue)) {
936 return 0;
937 }
938
939 uint32_t val = fifo32_pop(&s->ibi_queue);
940 ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, IBI_BUF_BLR,
941 fifo32_num_used(&s->ibi_queue));
942 /* Threshold is the register value + 1. */
943 uint8_t threshold = ARRAY_FIELD_EX32(s->regs, QUEUE_THLD_CTRL,
944 IBI_STATUS_THLD) + 1;
945 if (fifo32_num_used(&s->ibi_queue) < threshold) {
946 ARRAY_FIELD_DP32(s->regs, INTR_STATUS, IBI_THLD, 0);
947 aspeed_i3c_device_update_irq(s);
948 }
949 return val;
950}
951
653static uint32_t aspeed_i3c_device_resp_queue_port_r(AspeedI3CDevice *s)
654{
655 if (fifo32_is_empty(&s->resp_queue)) {
656 qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to read response FIFO when "
657 "empty\n", object_get_canonical_path(OBJECT(s)));
658 return 0;
659 }
660

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

682
683 switch (addr) {
684 /* RAZ */
685 case R_COMMAND_QUEUE_PORT:
686 case R_RESET_CTRL:
687 case R_INTR_FORCE:
688 value = 0;
689 break;
952static uint32_t aspeed_i3c_device_resp_queue_port_r(AspeedI3CDevice *s)
953{
954 if (fifo32_is_empty(&s->resp_queue)) {
955 qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to read response FIFO when "
956 "empty\n", object_get_canonical_path(OBJECT(s)));
957 return 0;
958 }
959

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

981
982 switch (addr) {
983 /* RAZ */
984 case R_COMMAND_QUEUE_PORT:
985 case R_RESET_CTRL:
986 case R_INTR_FORCE:
987 value = 0;
988 break;
989 case R_IBI_QUEUE_DATA:
990 value = aspeed_i3c_device_ibi_queue_r(s);
991 break;
690 case R_INTR_STATUS:
691 value = aspeed_i3c_device_intr_status_r(s);
692 break;
693 case R_RX_TX_DATA_PORT:
694 value = aspeed_i3c_device_pop_rx(s);
695 break;
696 case R_RESPONSE_QUEUE_PORT:
697 value = aspeed_i3c_device_resp_queue_port_r(s);

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

1407
1408 memory_region_init_io(&s->mr, OBJECT(s), &aspeed_i3c_device_ops,
1409 s, name, ASPEED_I3C_DEVICE_NR_REGS << 2);
1410
1411 fifo32_create(&s->cmd_queue, ASPEED_I3C_CMD_QUEUE_CAPACITY);
1412 fifo32_create(&s->resp_queue, ASPEED_I3C_RESP_QUEUE_CAPACITY);
1413 fifo32_create(&s->tx_queue, ASPEED_I3C_TX_QUEUE_CAPACITY);
1414 fifo32_create(&s->rx_queue, ASPEED_I3C_RX_QUEUE_CAPACITY);
992 case R_INTR_STATUS:
993 value = aspeed_i3c_device_intr_status_r(s);
994 break;
995 case R_RX_TX_DATA_PORT:
996 value = aspeed_i3c_device_pop_rx(s);
997 break;
998 case R_RESPONSE_QUEUE_PORT:
999 value = aspeed_i3c_device_resp_queue_port_r(s);

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

1709
1710 memory_region_init_io(&s->mr, OBJECT(s), &aspeed_i3c_device_ops,
1711 s, name, ASPEED_I3C_DEVICE_NR_REGS << 2);
1712
1713 fifo32_create(&s->cmd_queue, ASPEED_I3C_CMD_QUEUE_CAPACITY);
1714 fifo32_create(&s->resp_queue, ASPEED_I3C_RESP_QUEUE_CAPACITY);
1715 fifo32_create(&s->tx_queue, ASPEED_I3C_TX_QUEUE_CAPACITY);
1716 fifo32_create(&s->rx_queue, ASPEED_I3C_RX_QUEUE_CAPACITY);
1717 fifo32_create(&s->ibi_queue, ASPEED_I3C_IBI_QUEUE_CAPACITY);
1718 /* Arbitrarily large enough to not be an issue. */
1719 fifo8_create(&s->ibi_data.ibi_intermediate_queue,
1720 ASPEED_I3C_IBI_QUEUE_CAPACITY * 8);
1415
1416 s->bus = i3c_init_bus(DEVICE(s), name);
1721
1722 s->bus = i3c_init_bus(DEVICE(s), name);
1723 I3CBusClass *bc = I3C_BUS_GET_CLASS(s->bus);
1724 bc->ibi_handle = aspeed_i3c_device_ibi_handle;
1725 bc->ibi_recv = aspeed_i3c_device_ibi_recv;
1726 bc->ibi_finish = aspeed_i3c_device_ibi_finish;
1417}
1418
1419static uint64_t aspeed_i3c_read(void *opaque, hwaddr addr, unsigned int size)
1420{
1421 AspeedI3CState *s = ASPEED_I3C(opaque);
1422 uint64_t val = 0;
1423
1424 val = s->regs[addr >> 2];

--- 178 unchanged lines hidden ---
1727}
1728
1729static uint64_t aspeed_i3c_read(void *opaque, hwaddr addr, unsigned int size)
1730{
1731 AspeedI3CState *s = ASPEED_I3C(opaque);
1732 uint64_t val = 0;
1733
1734 val = s->regs[addr >> 2];

--- 178 unchanged lines hidden ---