xref: /openbmc/qemu/include/hw/i3c/aspeed_i3c.h (revision 4ba25376)
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 #ifndef ASPEED_I3C_H
12 #define ASPEED_I3C_H
13 
14 #include "qemu/fifo32.h"
15 #include "hw/i3c/i3c.h"
16 #include "hw/sysbus.h"
17 
18 #define TYPE_ASPEED_I3C "aspeed.i3c"
19 #define TYPE_ASPEED_I3C_DEVICE "aspeed.i3c.device"
20 OBJECT_DECLARE_TYPE(AspeedI3CState, AspeedI3CClass, ASPEED_I3C)
21 
22 #define ASPEED_I3C_NR_REGS (0x70 >> 2)
23 #define ASPEED_I3C_DEVICE_NR_REGS (0x300 >> 2)
24 #define ASPEED_I3C_NR_DEVICES 6
25 
26 #define ASPEED_I3C_CMD_QUEUE_CAPACITY  0x10
27 #define ASPEED_I3C_RESP_QUEUE_CAPACITY 0x10
28 #define ASPEED_I3C_TX_QUEUE_CAPACITY   0x40
29 #define ASPEED_I3C_RX_QUEUE_CAPACITY   0x40
30 
31 /* From datasheet. */
32 #define ASPEED_I3C_CMD_ATTR_TRANSFER_CMD 0
33 #define ASPEED_I3C_CMD_ATTR_TRANSFER_ARG 1
34 #define ASPEED_I3C_CMD_ATTR_SHORT_DATA_ARG 2
35 #define ASPEED_I3C_CMD_ATTR_ADDR_ASSIGN_CMD 3
36 
37 /* Enum values from datasheet. */
38 typedef enum AspeedI3CRespQueueErr {
39     ASPEED_I3C_RESP_QUEUE_ERR_NONE = 0,
40     ASPEED_I3C_RESP_QUEUE_ERR_CRC = 1,
41     ASPEED_I3C_RESP_QUEUE_ERR_PARITY = 2,
42     ASPEED_I3C_RESP_QUEUE_ERR_FRAME = 3,
43     ASPEED_I3C_RESP_QUEUE_ERR_BROADCAST_NACK = 4,
44     ASPEED_I3C_RESP_QUEUE_ERR_DAA_NACK = 5,
45     ASPEED_I3C_RESP_QUEUE_ERR_OVERFLOW = 6,
46     ASPEED_I3C_RESP_QUEUE_ERR_ABORTED = 8,
47     ASPEED_I3C_RESP_QUEUE_ERR_I2C_NACK = 9,
48 } AspeedI3CRespQueueErr;
49 
50 typedef enum AspeedI3CTransferState {
51     ASPEED_I3C_TRANSFER_STATE_IDLE = 0x00,
52     ASPEED_I3C_TRANSFER_STATE_START = 0x01,
53     ASPEED_I3C_TRANSFER_STATE_RESTART = 0x02,
54     ASPEED_I3C_TRANSFER_STATE_STOP = 0x03,
55     ASPEED_I3C_TRANSFER_STATE_START_HOLD = 0x04,
56     ASPEED_I3C_TRANSFER_STATE_BROADCAST_W = 0x05,
57     ASPEED_I3C_TRANSFER_STATE_BROADCAST_R = 0x06,
58     ASPEED_I3C_TRANSFER_STATE_DAA = 0x07,
59     ASPEED_I3C_TRANSFER_STATE_DAA_GEN = 0x08,
60     ASPEED_I3C_TRANSFER_STATE_CCC_BYTE = 0x0b,
61     ASPEED_I3C_TRANSFER_STATE_HDR_CMD = 0x0c,
62     ASPEED_I3C_TRANSFER_STATE_WRITE = 0x0d,
63     ASPEED_I3C_TRANSFER_STATE_READ = 0x0e,
64     ASPEED_I3C_TRANSFER_STATE_IBI_READ = 0x0f,
65     ASPEED_I3C_TRANSFER_STATE_IBI_DIS = 0x10,
66     ASPEED_I3C_TRANSFER_STATE_HDR_DDR_CRC = 0x11,
67     ASPEED_I3C_TRANSFER_STATE_CLK_STRETCH = 0x12,
68     ASPEED_I3C_TRANSFER_STATE_HALT = 0x13,
69 } AspeedI3CTransferState;
70 
71 typedef enum AspeedI3CTransferStatus {
72     ASPEED_I3C_TRANSFER_STATUS_IDLE = 0x00,
73     ASPEED_I3C_TRANSFER_STATUS_BROACAST_CCC = 0x01,
74     ASPEED_I3C_TRANSFER_STATUS_DIRECT_CCC_W = 0x02,
75     ASPEED_I3C_TRANSFER_STATUS_DIRECT_CCC_R = 0x03,
76     ASPEED_I3C_TRANSFER_STATUS_ENTDAA = 0x04,
77     ASPEED_I3C_TRANSFER_STATUS_SETDASA = 0x05,
78     ASPEED_I3C_TRANSFER_STATUS_I3C_SDR_W = 0x06,
79     ASPEED_I3C_TRANSFER_STATUS_I3C_SDR_R = 0x07,
80     ASPEED_I3C_TRANSFER_STATUS_I2C_SDR_W = 0x08,
81     ASPEED_I3C_TRANSFER_STATUS_I2C_SDR_R = 0x09,
82     ASPEED_I3C_TRANSFER_STATUS_HDR_TS_W = 0x0a,
83     ASPEED_I3C_TRANSFER_STATUS_HDR_TS_R = 0x0b,
84     ASPEED_I3C_TRANSFER_STATUS_HDR_DDR_W = 0x0c,
85     ASPEED_I3C_TRANSFER_STATUS_HDR_DDR_R = 0x0d,
86     ASPEED_I3C_TRANSFER_STATUS_IBI = 0x0e,
87     ASPEED_I3C_TRANSFER_STATUS_HALT = 0x0f,
88 } AspeedI3CTransferStatus;
89 
90 /*
91  * Transfer commands and arguments are 32-bit wide values that the user passes
92  * into the command queue. We interpret each 32-bit word based on the cmd_attr
93  * field.
94  */
95 typedef struct AspeedI3CTransferCmd {
96     uint8_t cmd_attr:3;
97     uint8_t tid:4; /* Transaction ID */
98     uint16_t cmd:8;
99     uint8_t cp:1; /* Command present */
100     uint8_t dev_index:5;
101     uint8_t speed:3;
102     uint8_t resv0:1;
103     uint8_t dbp:1; /* Defining byte present */
104     uint8_t roc:1; /* Response on completion */
105     uint8_t sdap:1; /* Short data argument present */
106     uint8_t rnw:1; /* Read not write */
107     uint8_t resv1:1;
108     uint8_t toc:1; /* Termination (I3C STOP) on completion */
109     uint8_t pec:1; /* Parity error check enabled */
110 } AspeedI3CTransferCmd;
111 
112 typedef struct AspeedI3CTransferArg {
113     uint8_t cmd_attr:3;
114     uint8_t resv:5;
115     uint8_t db; /* Defining byte */
116     uint16_t data_len;
117 } AspeedI3CTransferArg;
118 
119 typedef struct AspeedI3CShortArg {
120     uint8_t cmd_attr:3;
121     uint8_t byte_strb:3;
122     uint8_t resv:2;
123     uint8_t byte0;
124     uint8_t byte1;
125     uint8_t byte2;
126 } AspeedI3CShortArg;
127 
128 typedef struct AspeedI3CAddrAssignCmd {
129     uint8_t cmd_attr:3;
130     uint8_t tid:4; /* Transaction ID */
131     uint16_t cmd:8;
132     uint8_t resv0:1;
133     uint8_t dev_index:5;
134     uint16_t dev_count:5;
135     uint8_t roc:1; /* Response on completion */
136     uint8_t resv1:3;
137     uint8_t toc:1; /* Termination (I3C STOP) on completion */
138     uint8_t resv2:1;
139 } AspeedI3CAddrAssignCmd;
140 
141 typedef union AspeedI3CCmdQueueData {
142     uint32_t word;
143     AspeedI3CTransferCmd transfer_cmd;
144     AspeedI3CTransferArg transfer_arg;
145     AspeedI3CShortArg short_arg;
146     AspeedI3CAddrAssignCmd addr_assign_cmd;
147 } AspeedI3CCmdQueueData;
148 
149 OBJECT_DECLARE_SIMPLE_TYPE(AspeedI3CDevice, ASPEED_I3C_DEVICE)
150 typedef struct AspeedI3CDevice {
151     /* <private> */
152     SysBusDevice parent;
153 
154     /* <public> */
155     MemoryRegion mr;
156     qemu_irq irq;
157     I3CBus *bus;
158 
159     Fifo32 cmd_queue;
160     Fifo32 resp_queue;
161     Fifo32 tx_queue;
162     Fifo32 rx_queue;
163 
164     uint8_t id;
165     uint32_t regs[ASPEED_I3C_DEVICE_NR_REGS];
166 } AspeedI3CDevice;
167 
168 typedef struct AspeedI3CState {
169     /* <private> */
170     SysBusDevice parent;
171 
172     /* <public> */
173     MemoryRegion iomem;
174     MemoryRegion iomem_container;
175     qemu_irq irq;
176 
177     uint32_t regs[ASPEED_I3C_NR_REGS];
178     AspeedI3CDevice devices[ASPEED_I3C_NR_DEVICES];
179 } AspeedI3CState;
180 #endif /* ASPEED_I3C_H */
181