xref: /openbmc/qemu/include/hw/i3c/i3c.h (revision da2f5fea)
1 /*
2  * QEMU I3C bus interface.
3  *
4  * Copyright 2023 Google LLC
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14  * for more details.
15  */
16 
17 #ifndef QEMU_INCLUDE_HW_I3C_I3C_H_
18 #define QEMU_INCLUDE_HW_I3C_I3C_H_
19 
20 #include "hw/qdev-core.h"
21 #include "qom/object.h"
22 #include "hw/i2c/i2c.h"
23 
24 #define TYPE_I3C_TARGET "i3c-target"
25 OBJECT_DECLARE_TYPE(I3CTarget, I3CTargetClass, I3C_TARGET)
26 
27 typedef enum I3CEvent {
28     I3C_START_RECV,
29     I3C_START_SEND,
30     I3C_STOP,
31     I3C_NACK,
32 } I3CEvent;
33 
34 typedef enum I3CCCC {
35     /* Broadcast CCCs */
36     I3C_CCC_ENEC      = 0x00,
37     I3C_CCC_DISEC     = 0x01,
38     I3C_CCC_ENTAS0    = 0x02,
39     I3C_CCC_ENTAS1    = 0x03,
40     I3C_CCC_ENTAS2    = 0x04,
41     I3C_CCC_ENTAS3    = 0x05,
42     I3C_CCC_RSTDAA    = 0x06,
43     I3C_CCC_ENTDAA    = 0x07,
44     I3C_CCC_DEFTGTS   = 0x08,
45     I3C_CCC_SETMWL    = 0x09,
46     I3C_CCC_SETMRL    = 0x0a,
47     I3C_CCC_ENTTM     = 0x0b,
48     I3C_CCC_SETBUSCON = 0x0c,
49     I3C_CCC_ENDXFER   = 0x12,
50     I3C_CCC_ENTHDR0   = 0x20,
51     I3C_CCC_ENTHDR1   = 0x21,
52     I3C_CCC_ENTHDR2   = 0x22,
53     I3C_CCC_ENTHDR3   = 0x23,
54     I3C_CCC_ENTHDR4   = 0x24,
55     I3C_CCC_ENTHDR5   = 0x25,
56     I3C_CCC_ENTHDR6   = 0x26,
57     I3C_CCC_ENTHDR7   = 0x27,
58     I3C_CCC_SETXTIME  = 0x28,
59     I3C_CCC_SETAASA   = 0x29,
60     I3C_CCC_RSTACT    = 0x2a,
61     I3C_CCC_DEFGRPA   = 0x2b,
62     I3C_CCC_RSTGRPA   = 0x2c,
63     I3C_CCC_MLANE     = 0x2d,
64     /* Direct CCCs */
65     I3C_CCCD_ENEC       = 0x80,
66     I3C_CCCD_DISEC      = 0x81,
67     I3C_CCCD_ENTAS0     = 0x82,
68     I3C_CCCD_ENTAS1     = 0x83,
69     I3C_CCCD_ENTAS2     = 0x84,
70     I3C_CCCD_ENTAS3     = 0x85,
71     I3C_CCCD_SETDASA    = 0x87,
72     I3C_CCCD_SETNEWDA   = 0x88,
73     I3C_CCCD_SETMWL     = 0x89,
74     I3C_CCCD_SETMRL     = 0x8a,
75     I3C_CCCD_GETMWL     = 0x8b,
76     I3C_CCCD_GETMRL     = 0x8c,
77     I3C_CCCD_GETPID     = 0x8d,
78     I3C_CCCD_GETBCR     = 0x8e,
79     I3C_CCCD_GETDCR     = 0x8f,
80     I3C_CCCD_GETSTATUS  = 0x90,
81     I3C_CCCD_GETACCCR   = 0x91,
82     I3C_CCCD_ENDXFER    = 0x92,
83     I3C_CCCD_SETBRGTGT  = 0x93,
84     I3C_CCCD_GETMXDS    = 0x94,
85     I3C_CCCD_GETCAPS    = 0x95,
86     I3C_CCCD_SETROUTE   = 0x96,
87     I3C_CCCD_SETXTIME   = 0x98,
88     I3C_CCCD_GETXTIME   = 0x99,
89     I3C_CCCD_RSTACT     = 0x9a,
90     I3C_CCCD_SETGRPA    = 0x9b,
91     I3C_CCCD_RSTGRPA    = 0x9c,
92     I3C_CCCD_MLANE      = 0x9d,
93 } I3CCCC;
94 
95 #define CCC_IS_DIRECT(_ccc) (_ccc & 0x80)
96 
97 #define I3C_BROADCAST 0x7e
98 #define I3C_HJ_ADDR 0x02
99 #define I3C_ENTDAA_SIZE 8
100 
101 struct I3CTargetClass {
102     DeviceClass parent;
103 
104     /*
105      * Controller to target. Returns 0 for success, non-zero for NAK or other
106      * error.
107      */
108     int (*send)(I3CTarget *s, const uint8_t *data, uint32_t num_to_send,
109                 uint32_t *num_sent);
110     /*
111      * Target to controller. I3C targets are able to terminate reads early, so
112      * this returns the number of bytes read from the target.
113      */
114     uint32_t (*recv)(I3CTarget *s, uint8_t *data, uint32_t num_to_read);
115     /* Notify the target of a bus state change. */
116     int (*event)(I3CTarget *s, enum I3CEvent event);
117     /*
118      * Handle a read CCC transmitted from a controller.
119      * CCCs are I3C commands that I3C targets support.
120      * The target can NACK the CCC if it does not support it.
121      */
122     int (*handle_ccc_read)(I3CTarget *s, uint8_t *data, uint32_t num_to_read,
123                            uint32_t *num_read);
124     /*
125      * Handle a write CCC transmitted from a controller.
126      * CCCs are I3C commands that I3C targets support.
127      * The target can NACK the CCC if it does not support it.
128      */
129     int (*handle_ccc_write)(I3CTarget *s, const uint8_t *data,
130                             uint32_t num_to_send, uint32_t *num_sent);
131 };
132 
133 struct I3CTarget {
134     DeviceState qdev;
135 
136     uint8_t address;
137     uint8_t static_address;
138     uint8_t dcr;
139     uint8_t bcr;
140     uint64_t pid;
141 
142     /* CCC State tracking. */
143     I3CCCC curr_ccc;
144     uint8_t ccc_byte_offset;
145     bool in_ccc;
146 };
147 
148 struct I3CNode {
149     I3CTarget *target;
150     QLIST_ENTRY(I3CNode) next;
151 };
152 
153 typedef struct I3CNode I3CNode;
154 
155 typedef QLIST_HEAD(I3CNodeList, I3CNode) I3CNodeList;
156 
157 #define TYPE_I3C_BUS "i3c-bus"
158 OBJECT_DECLARE_TYPE(I3CBus, I3CBusClass, I3C_BUS)
159 
160 struct I3CBus {
161     BusState qbus;
162 
163     /* Legacy I2C. */
164     I2CBus *i2c_bus;
165 
166     I3CNodeList current_devs;
167     bool broadcast;
168     uint8_t ccc;
169     bool in_ccc;
170     bool in_entdaa;
171     uint8_t saved_address;
172 };
173 
174 struct I3CBusClass {
175     DeviceClass parent;
176 
177     /* Handle an incoming IBI request from a target */
178     int (*ibi_handle) (I3CBus *bus, I3CTarget *target, uint8_t addr,
179                        bool is_recv);
180     /* Receive data from an IBI request */
181     int (*ibi_recv) (I3CBus *bus, uint8_t data);
182     /* Do anything that needs to be done, since the IBI is finished. */
183     int (*ibi_finish) (I3CBus *bus);
184 };
185 
186 I3CBus *i3c_init_bus(DeviceState *parent, const char *name);
187 I3CBus *i3c_init_bus_type(const char *type, DeviceState *parent,
188                           const char *name);
189 void i3c_set_target_address(I3CTarget *dev, uint8_t address);
190 bool i3c_bus_busy(I3CBus *bus);
191 
192 /*
193  * Start a transfer on an I3C bus.
194  * If is_recv is known at compile-time (i.e. a device will always be sending or
195  * will always be receiving at a certain point), prefer to use i3c_start_recv or
196  * i3c_start_send instead.
197  *
198  * Returns 0 on success, non-zero on an error.
199  */
200 int i3c_start_transfer(I3CBus *bus, uint8_t address, bool is_recv);
201 
202 /*
203  * Start a receive transfer on an I3C bus.
204  *
205  * Returns 0 on success, non-zero on an error
206  */
207 int i3c_start_recv(I3CBus *bus, uint8_t address);
208 
209 /*
210  * Start a send transfer on an I3C bus.
211  *
212  * Returns 0 on success, non-zero on an error
213  */
214 int i3c_start_send(I3CBus *bus, uint8_t address);
215 
216 void i3c_end_transfer(I3CBus *bus);
217 void i3c_nack(I3CBus *bus);
218 int i3c_send_byte(I3CBus *bus, uint8_t data);
219 int i3c_send(I3CBus *bus, const uint8_t *data, uint32_t num_to_send,
220              uint32_t *num_sent);
221 /*
222  * I3C receives can only NACK on a CCC. The target should NACK a CCC it does not
223  * support.
224  */
225 int i3c_recv_byte(I3CBus *bus, uint8_t *data);
226 int i3c_recv(I3CBus *bus, uint8_t *data, uint32_t num_to_read,
227              uint32_t *num_read);
228 bool i3c_scan_bus(I3CBus *bus, uint8_t address);
229 int i3c_do_entdaa(I3CBus *bus, uint8_t address, uint64_t *pid, uint8_t *bcr,
230                   uint8_t *dcr);
231 int i3c_start_device_transfer(I3CTarget *dev, int send_length);
232 bool i3c_target_match(I3CBus *bus, I3CTarget *target, uint8_t address);
233 int i3c_target_send_ibi(I3CTarget *t, uint8_t addr, bool is_recv);
234 int i3c_target_send_ibi_bytes(I3CTarget *t, uint8_t data);
235 int i3c_target_ibi_finish(I3CTarget *t, uint8_t data);
236 
237 /*
238  * Legacy I2C functions.
239  *
240  * These are wrapper for I2C functions that take in an I3C bus instead of an I2C
241  * bus. Internally they use the I2C bus (and devices attached to it) that's a
242  * part of the I3C bus
243  */
244 void legacy_i2c_nack(I3CBus *bus);
245 uint8_t legacy_i2c_recv(I3CBus *bus);
246 int legacy_i2c_send(I3CBus *bus, uint8_t data);
247 int legacy_i2c_start_transfer(I3CBus *bus, uint8_t address, bool is_recv);
248 int legacy_i2c_start_recv(I3CBus *bus, uint8_t address);
249 int legacy_i2c_start_send(I3CBus *bus, uint8_t address);
250 void legacy_i2c_end_transfer(I3CBus *bus);
251 I2CSlave *legacy_i2c_device_create_simple(I3CBus *bus, const char *name,
252                                           uint8_t addr);
253 
254 /**
255  * Create an I3C Target.
256  *
257  * The target returned from this function still needs to be realized.
258  */
259 I3CTarget *i3c_target_new(const char *name, uint8_t addr, uint8_t dcr,
260                           uint8_t bcr, uint64_t pid);
261 
262 /**
263  * Create and realize an I3C target.
264  *
265  * Create the target, initialize it, put it on the specified I3C bus, and
266  * realize it.
267  */
268 I3CTarget *i3c_target_create_simple(I3CBus *bus, const char *name,
269                                     uint8_t addr, uint8_t dcr, uint8_t bcr,
270                                     uint64_t pid);
271 
272 /* Realize and drop the reference count on an I3C target. */
273 bool i3c_target_realize_and_unref(I3CTarget *dev, I3CBus *bus, Error **errp);
274 
275 #endif  /* QEMU_INCLUDE_HW_I3C_I3C_H_ */
276