1 /*
2  * Copyright (C) 2020 Samsung Electronics Co., Ltd.
3  * Copyright (C) 2023 Meta Platforms
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/logging/log.h>
9 #include <zephyr/drivers/i3c.h>
10 #include <zephyr/drivers/clock_control.h>
11 #include <zephyr/pm/device.h>
12 #include <zephyr/sys/util.h>
13 #include <assert.h>
14 
15 #if defined(CONFIG_PINCTRL)
16 #include <zephyr/drivers/pinctrl.h>
17 #endif
18 
19 #define NANO_SEC        1000000000ULL
20 #define BYTES_PER_DWORD 4
21 
22 LOG_MODULE_REGISTER(i3c_dw, CONFIG_I3C_DW_LOG_LEVEL);
23 
24 #define DEVICE_CTRL                0x0
25 #define DEV_CTRL_ENABLE            BIT(31)
26 #define DEV_CTRL_RESUME            BIT(30)
27 #define DEV_CTRL_HOT_JOIN_NACK     BIT(8)
28 #define DEV_CTRL_I2C_SLAVE_PRESENT BIT(7)
29 #define DEV_CTRL_IBA_INCLUDE       BIT(0)
30 
31 #define DEVICE_ADDR                    0x4
32 #define DEVICE_ADDR_DYNAMIC_ADDR_VALID BIT(31)
33 #define DEVICE_ADDR_DYNAMIC(x)         (((x) << 16) & GENMASK(22, 16))
34 #define DEVICE_ADDR_STATIC_ADDR_VALID  BIT(15)
35 #define DEVICE_ADDR_STATIC_MASK        GENMASK(6, 0)
36 #define DEVICE_ADDR_STATIC(x)          ((x) & DEVICE_ADDR_STATIC_MASK)
37 
38 #define HW_CAPABILITY                         0x8
39 #define HW_CAPABILITY_SLV_IBI_CAP             BIT(19)
40 #define HW_CAPABILITY_SLV_HJ_CAP              BIT(18)
41 #define HW_CAPABILITY_HDR_TS_EN               BIT(4)
42 #define HW_CAPABILITY_HDR_DDR_EN              BIT(3)
43 #define HW_CAPABILITY_DEVICE_ROLE_CONFIG_MASK GENMASK(2, 0)
44 
45 #define COMMAND_QUEUE_PORT         0xc
46 #define COMMAND_PORT_TOC           BIT(30)
47 #define COMMAND_PORT_READ_TRANSFER BIT(28)
48 #define COMMAND_PORT_SDAP          BIT(27)
49 #define COMMAND_PORT_ROC           BIT(26)
50 #define COMMAND_PORT_DBP           BIT(25)
51 #define COMMAND_PORT_SPEED(x)      (((x) << 21) & GENMASK(23, 21))
52 #define COMMAND_PORT_SPEED_I2C_FM  0
53 #define COMMAND_PORT_SPEED_I2C_FMP 1
54 #define COMMAND_PORT_SPEED_I3C_DDR 6
55 #define COMMAND_PORT_SPEED_I3C_TS  7
56 #define COMMAND_PORT_DEV_INDEX(x)  (((x) << 16) & GENMASK(20, 16))
57 #define COMMAND_PORT_CP            BIT(15)
58 #define COMMAND_PORT_CMD(x)        (((x) << 7) & GENMASK(14, 7))
59 #define COMMAND_PORT_TID(x)        (((x) << 3) & GENMASK(6, 3))
60 
61 #define COMMAND_PORT_ARG_DATA_LEN(x)  (((x) << 16) & GENMASK(31, 16))
62 #define COMMAND_PORT_ARG_DB(x)        (((x) << 8) & GENMASK(15, 8))
63 #define COMMAND_PORT_ARG_DATA_LEN_MAX 65536
64 #define COMMAND_PORT_TRANSFER_ARG     0x01
65 
66 #define COMMAND_PORT_SDA_DATA_BYTE_3(x) (((x) << 24) & GENMASK(31, 24))
67 #define COMMAND_PORT_SDA_DATA_BYTE_2(x) (((x) << 16) & GENMASK(23, 16))
68 #define COMMAND_PORT_SDA_DATA_BYTE_1(x) (((x) << 8) & GENMASK(15, 8))
69 #define COMMAND_PORT_SDA_BYTE_STRB_3    BIT(5)
70 #define COMMAND_PORT_SDA_BYTE_STRB_2    BIT(4)
71 #define COMMAND_PORT_SDA_BYTE_STRB_1    BIT(3)
72 #define COMMAND_PORT_SHORT_DATA_ARG     0x02
73 
74 #define COMMAND_PORT_DEV_COUNT(x)   (((x) << 21) & GENMASK(25, 21))
75 #define COMMAND_PORT_ADDR_ASSGN_CMD 0x03
76 
77 #define RESPONSE_QUEUE_PORT            0x10
78 #define RESPONSE_PORT_ERR_STATUS(x)    (((x) & GENMASK(31, 28)) >> 28)
79 #define RESPONSE_NO_ERROR              0
80 #define RESPONSE_ERROR_CRC             1
81 #define RESPONSE_ERROR_PARITY          2
82 #define RESPONSE_ERROR_FRAME           3
83 #define RESPONSE_ERROR_IBA_NACK        4
84 #define RESPONSE_ERROR_ADDRESS_NACK    5
85 #define RESPONSE_ERROR_OVER_UNDER_FLOW 6
86 #define RESPONSE_ERROR_TRANSF_ABORT    8
87 #define RESPONSE_ERROR_I2C_W_NACK_ERR  9
88 #define RESPONSE_PORT_TID(x)           (((x) & GENMASK(27, 24)) >> 24)
89 #define RESPONSE_PORT_DATA_LEN(x)      ((x) & GENMASK(15, 0))
90 
91 #define RX_TX_DATA_PORT              0x14
92 #define IBI_QUEUE_STATUS             0x18
93 #define IBI_QUEUE_STATUS_IBI_STS(x)  (((x) & GENMASK(31, 28)) >> 28)
94 #define IBI_QUEUE_STATUS_IBI_ID(x)   (((x) & GENMASK(15, 8)) >> 8)
95 #define IBI_QUEUE_STATUS_DATA_LEN(x) ((x) & GENMASK(7, 0))
96 #define IBI_QUEUE_IBI_ADDR(x)        (IBI_QUEUE_STATUS_IBI_ID(x) >> 1)
97 #define IBI_QUEUE_IBI_RNW(x)         (IBI_QUEUE_STATUS_IBI_ID(x) & BIT(0))
98 #define IBI_TYPE_MR(x) \
99 	((IBI_QUEUE_IBI_ADDR(x) != I3C_HOT_JOIN_ADDR) && !IBI_QUEUE_IBI_RNW(x))
100 #define IBI_TYPE_HJ(x) \
101 	((IBI_QUEUE_IBI_ADDR(x) == I3C_HOT_JOIN_ADDR) && !IBI_QUEUE_IBI_RNW(x))
102 #define IBI_TYPE_SIRQ(x) \
103 	((IBI_QUEUE_IBI_ADDR(x) != I3C_HOT_JOIN_ADDR) && IBI_QUEUE_IBI_RNW(x))
104 
105 #define QUEUE_THLD_CTRL               0x1c
106 #define QUEUE_THLD_CTRL_IBI_STS_MASK  GENMASK(31, 24)
107 #define QUEUE_THLD_CTRL_RESP_BUF_MASK GENMASK(15, 8)
108 #define QUEUE_THLD_CTRL_RESP_BUF(x)   (((x) - 1) << 8)
109 
110 #define DATA_BUFFER_THLD_CTRL        0x20
111 #define DATA_BUFFER_THLD_CTRL_RX_BUF GENMASK(11, 8)
112 
113 #define IBI_QUEUE_CTRL     0x24
114 #define IBI_MR_REQ_REJECT  0x2C
115 #define IBI_SIR_REQ_REJECT 0x30
116 #define IBI_SIR_REQ_ID(x)  ((((x) & GENMASK(6, 5)) >> 5) + ((x) & GENMASK(4, 0)))
117 #define IBI_REQ_REJECT_ALL GENMASK(31, 0)
118 
119 #define RESET_CTRL            0x34
120 #define RESET_CTRL_IBI_QUEUE  BIT(5)
121 #define RESET_CTRL_RX_FIFO    BIT(4)
122 #define RESET_CTRL_TX_FIFO    BIT(3)
123 #define RESET_CTRL_RESP_QUEUE BIT(2)
124 #define RESET_CTRL_CMD_QUEUE  BIT(1)
125 #define RESET_CTRL_SOFT       BIT(0)
126 #define RESET_CTRL_ALL                                                                             \
127 	(RESET_CTRL_IBI_QUEUE | RESET_CTRL_RX_FIFO | RESET_CTRL_TX_FIFO | RESET_CTRL_RESP_QUEUE |  \
128 	 RESET_CTRL_CMD_QUEUE | RESET_CTRL_SOFT)
129 
130 #define SLV_EVENT_STATUS        0x38
131 #define SLV_EVENT_STATUS_HJ_EN  BIT(3)
132 #define SLV_EVENT_STATUS_MR_EN  BIT(1)
133 #define SLV_EVENT_STATUS_SIR_EN BIT(0)
134 
135 #define INTR_STATUS               0x3c
136 #define INTR_STATUS_EN            0x40
137 #define INTR_SIGNAL_EN            0x44
138 #define INTR_FORCE                0x48
139 #define INTR_BUSOWNER_UPDATE_STAT BIT(13)
140 #define INTR_IBI_UPDATED_STAT     BIT(12)
141 #define INTR_READ_REQ_RECV_STAT   BIT(11)
142 #define INTR_DEFSLV_STAT          BIT(10)
143 #define INTR_TRANSFER_ERR_STAT    BIT(9)
144 #define INTR_DYN_ADDR_ASSGN_STAT  BIT(8)
145 #define INTR_CCC_UPDATED_STAT     BIT(6)
146 #define INTR_TRANSFER_ABORT_STAT  BIT(5)
147 #define INTR_RESP_READY_STAT      BIT(4)
148 #define INTR_CMD_QUEUE_READY_STAT BIT(3)
149 #define INTR_IBI_THLD_STAT        BIT(2)
150 #define INTR_RX_THLD_STAT         BIT(1)
151 #define INTR_TX_THLD_STAT         BIT(0)
152 #define INTR_ALL                                                                                   \
153 	(INTR_BUSOWNER_UPDATE_STAT | INTR_IBI_UPDATED_STAT | INTR_READ_REQ_RECV_STAT |             \
154 	 INTR_DEFSLV_STAT | INTR_TRANSFER_ERR_STAT | INTR_DYN_ADDR_ASSGN_STAT |                    \
155 	 INTR_CCC_UPDATED_STAT | INTR_TRANSFER_ABORT_STAT | INTR_RESP_READY_STAT |                 \
156 	 INTR_CMD_QUEUE_READY_STAT | INTR_IBI_THLD_STAT | INTR_TX_THLD_STAT | INTR_RX_THLD_STAT)
157 
158 #ifdef CONFIG_I3C_USE_IBI
159 #define INTR_MASTER_MASK (INTR_TRANSFER_ERR_STAT | INTR_RESP_READY_STAT | INTR_IBI_THLD_STAT)
160 #else
161 #define INTR_MASTER_MASK (INTR_TRANSFER_ERR_STAT | INTR_RESP_READY_STAT)
162 #endif
163 #define INTR_SLAVE_MASK                                                                            \
164 	(INTR_TRANSFER_ERR_STAT | INTR_IBI_UPDATED_STAT | INTR_READ_REQ_RECV_STAT |                \
165 	 INTR_DYN_ADDR_ASSGN_STAT | INTR_RESP_READY_STAT)
166 
167 #define QUEUE_STATUS_LEVEL             0x4c
168 #define QUEUE_STATUS_IBI_STATUS_CNT(x) (((x) & GENMASK(28, 24)) >> 24)
169 #define QUEUE_STATUS_IBI_BUF_BLR(x)    (((x) & GENMASK(23, 16)) >> 16)
170 #define QUEUE_STATUS_LEVEL_RESP(x)     (((x) & GENMASK(15, 8)) >> 8)
171 #define QUEUE_STATUS_LEVEL_CMD(x)      ((x) & GENMASK(7, 0))
172 
173 #define DATA_BUFFER_STATUS_LEVEL       0x50
174 #define DATA_BUFFER_STATUS_LEVEL_RX(x) (((x) & GENMASK(23, 16)) >> 16)
175 #define DATA_BUFFER_STATUS_LEVEL_TX(x) ((x) & GENMASK(7, 0))
176 
177 #define PRESENT_STATE                0x54
178 #define PRESENT_STATE_CURRENT_MASTER BIT(2)
179 
180 #define CCC_DEVICE_STATUS          0x58
181 #define DEVICE_ADDR_TABLE_POINTER  0x5c
182 #define DEVICE_ADDR_TABLE_DEPTH(x) (((x) & GENMASK(31, 16)) >> 16)
183 #define DEVICE_ADDR_TABLE_ADDR(x)  ((x) & GENMASK(15, 0))
184 
185 #define DEV_CHAR_TABLE_POINTER      0x60
186 #define DEVICE_CHAR_TABLE_ADDR(x)   ((x) & GENMASK(11, 0))
187 #define VENDOR_SPECIFIC_REG_POINTER 0x6c
188 
189 #define SLV_MIPI_ID_VALUE                      0x70
190 #define SLV_MIPI_ID_VALUE_SLV_MIPI_MFG_ID_MASK GENMASK(15, 1)
191 #define SLV_MIPI_ID_VALUE_SLV_MIPI_MFG_ID(x)   ((x) & SLV_MIPI_ID_VALUE_SLV_MIPI_MFG_ID_MASK)
192 #define SLV_MIPI_ID_VALUE_SLV_PROV_ID_SEL      BIT(0)
193 
194 #define SLV_PID_VALUE 0x74
195 
196 #define SLV_CHAR_CTRL                      0x78
197 #define SLV_CHAR_CTRL_MAX_DATA_SPEED_LIMIT BIT(0)
198 #define SLV_CHAR_CTRL_IBI_REQUEST_CAPABLE  BIT(1)
199 #define SLV_CHAR_CTRL_IBI_PAYLOAD          BIT(2)
200 #define SLV_CHAR_CTRL_BCR_MASK             GENMASK(7, 0)
201 #define SLV_CHAR_CTRL_BCR(x)               ((x) & SLV_CHAR_CTRL_BCR_MASK)
202 #define SLV_CHAR_CTRL_DCR_MASK             GENMASK(15, 8)
203 #define SLV_CHAR_CTRL_DCR(x)               (((x) & SLV_CHAR_CTRL_DCR_MASK) >> 8)
204 #define SLV_CHAR_CTRL_HDR_CAP_MASK         GENMASK(23, 16)
205 #define SLV_CHAR_CTRL_HDR_CAP(x)           (((x) & SLV_CHAR_CTRL_HDR_CAP_MASK) >> 16)
206 
207 #define SLV_MAX_LEN        0x7c
208 #define SLV_MAX_LEN_MRL(x) (((x) & GENMASK(31, 16)) >> 16)
209 #define SLV_MAX_LEN_MWL(x) ((x) & GENMASK(15, 0))
210 
211 #define MAX_READ_TURNAROUND                     0x80
212 #define MAX_READ_TURNAROUND_MXDX_MAX_RD_TURN(x) ((x) & GENMASK(23, 0))
213 
214 #define MAX_DATA_SPEED   0x84
215 #define SLV_DEBUG_STATUS 0x88
216 
217 #define SLV_INTR_REQ                        0x8c
218 #define SLV_INTR_REQ_SIR_DATA_LENGTH(x)     (((x) << 16) & GENMASK(23, 16))
219 #define SLV_INTR_REQ_MDB(x)                 (((x) << 8) & GENMASK(15, 8))
220 #define SLV_INTR_REQ_IBI_STS(x)             (((x) & GENMASK(9, 8)) >> 8)
221 #define SLV_INTR_REQ_IBI_STS_IBI_ACCEPT     0x01
222 #define SLV_INTR_REQ_IBI_STS_IBI_NO_ATTEMPT 0x03
223 #define SLV_INTR_REQ_TS                     BIT(4)
224 #define SLV_INTR_REQ_MR                     BIT(3)
225 #define SLV_INTR_REQ_SIR_CTRL(x)            (((x) & GENMASK(2, 1)) >> 1)
226 #define SLV_INTR_REQ_SIR                    BIT(0)
227 
228 #define SLV_SIR_DATA          0x94
229 #define SLV_SIR_DATA_BYTE3(x) (((x) << 24) & GENMASK(31, 24))
230 #define SLV_SIR_DATA_BYTE2(x) (((x) << 16) & GENMASK(23, 16))
231 #define SLV_SIR_DATA_BYTE1(x) (((x) << 8) & GENMASK(15, 8))
232 #define SLV_SIR_DATA_BYTE0(x) ((x) & GENMASK(7, 0))
233 
234 #define SLV_IBI_RESP                         0x98
235 #define SLV_IBI_RESP_DATA_LENGTH(x)          (((x) & GENMASK(23, 8)) >> 8)
236 #define SLV_IBI_RESP_IBI_STS(x)              ((x) & GENMASK(1, 0))
237 #define SLV_IBI_RESP_IBI_STS_ACK             0x01
238 #define SLV_IBI_RESP_IBI_STS_EARLY_TERMINATE 0x02
239 #define SLV_IBI_RESP_IBI_STS_NACK            0x03
240 
241 #define SLV_NACK_REQ               0x9c
242 #define SLV_NACK_REQ_NACK_REQ(x)   ((x) & GENMASK(1, 0))
243 #define SLV_NACK_REQ_NACK_REQ_ACK  0x00
244 #define SLV_NACK_REQ_NACK_REQ_NACK 0x01
245 
246 #define DEVICE_CTRL_EXTENDED                           0xb0
247 #define DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE(x)     ((x) & GENMASK(1, 0))
248 #define DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE_MASTER 0
249 #define DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE_SLAVE  1
250 
251 #define SCL_I3C_OD_TIMING      0xb4
252 #define SCL_I3C_PP_TIMING      0xb8
253 #define SCL_I3C_TIMING_HCNT(x) (((x) << 16) & GENMASK(23, 16))
254 #define SCL_I3C_TIMING_LCNT(x) ((x) & GENMASK(7, 0))
255 #define SCL_I3C_TIMING_CNT_MIN 5
256 #define SCL_I3C_TIMING_CNT_MAX 255
257 
258 #define SCL_I2C_FM_TIMING         0xbc
259 #define SCL_I2C_FM_TIMING_HCNT(x) (((x) << 16) & GENMASK(31, 16))
260 #define SCL_I2C_FM_TIMING_LCNT(x) ((x) & GENMASK(15, 0))
261 
262 #define SCL_I2C_FMP_TIMING         0xc0
263 #define SCL_I2C_FMP_TIMING_HCNT(x) (((x) << 16) & GENMASK(23, 16))
264 #define SCL_I2C_FMP_TIMING_LCNT(x) ((x) & GENMASK(15, 0))
265 
266 #define SCL_EXT_LCNT_TIMING 0xc8
267 #define SCL_EXT_LCNT_4(x)   (((x) << 24) & GENMASK(31, 24))
268 #define SCL_EXT_LCNT_3(x)   (((x) << 16) & GENMASK(23, 16))
269 #define SCL_EXT_LCNT_2(x)   (((x) << 8) & GENMASK(15, 8))
270 #define SCL_EXT_LCNT_1(x)   ((x) & GENMASK(7, 0))
271 
272 #define SCL_EXT_TERMN_LCNT_TIMING 0xcc
273 
274 #define SDA_HOLD_SWITCH_DLY_TIMING                         0xd0
275 #define SDA_HOLD_SWITCH_DLY_TIMING_SDA_TX_HOLD(x)          (((x)&GENMASK(18, 16)) >> 16)
276 #define SDA_HOLD_SWITCH_DLY_TIMING_SDA_PP_OD_SWITCH_DLY(x) (((x)&GENMASK(10, 8)) >> 8)
277 #define SDA_HOLD_SWITCH_DLY_TIMING_SDA_OD_PP_SWITCH_DLY(x) ((x)&GENMASK(2, 0))
278 
279 #define BUS_FREE_TIMING           0xd4
280 /* Bus available time of 1us in ns */
281 #define I3C_BUS_AVAILABLE_TIME_NS 1000U
282 #define BUS_I3C_MST_FREE(x)       ((x) & GENMASK(15, 0))
283 #define BUS_I3C_AVAIL_TIME(x)     ((x << 16) & GENMASK(31, 16))
284 
285 #define BUS_IDLE_TIMING      0xd8
286 /* Bus Idle time of 1ms in ns */
287 #define I3C_BUS_IDLE_TIME_NS 1000000U
288 #define BUS_I3C_IDLE_TIME(x) ((x) & GENMASK(19, 0))
289 
290 #define I3C_VER_ID          0xe0
291 #define I3C_VER_TYPE        0xe4
292 #define EXTENDED_CAPABILITY 0xe8
293 #define SLAVE_CONFIG        0xec
294 
295 #define QUEUE_SIZE_CAPABILITY                        0xe8
296 #define QUEUE_SIZE_CAPABILITY_IBI_BUF_DWORD_SIZE(x)  (2 << (((x) & GENMASK(19, 16)) >> 16))
297 #define QUEUE_SIZE_CAPABILITY_RESP_BUF_DWORD_SIZE(x) (2 << (((x) & GENMASK(15, 12)) >> 12))
298 #define QUEUE_SIZE_CAPABILITY_CMD_BUF_DWORD_SIZE(x)  (2 << (((x) & GENMASK(11, 8)) >> 8))
299 #define QUEUE_SIZE_CAPABILITY_RX_BUF_DWORD_SIZE(x)   (2 << (((x) & GENMASK(7, 4)) >> 4))
300 #define QUEUE_SIZE_CAPABILITY_TX_BUF_DWORD_SIZE(x)   (2 << ((x) & GENMASK(3, 0)))
301 
302 #define DEV_ADDR_TABLE_LEGACY_I2C_DEV    BIT(31)
303 #define DEV_ADDR_TABLE_DYNAMIC_ADDR_MASK GENMASK(23, 16)
304 #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x)   (((x) << 16) & GENMASK(23, 16))
305 #define DEV_ADDR_TABLE_SIR_REJECT        BIT(13)
306 #define DEV_ADDR_TABLE_IBI_WITH_DATA     BIT(12)
307 #define DEV_ADDR_TABLE_STATIC_ADDR(x)    ((x) & GENMASK(6, 0))
308 #define DEV_ADDR_TABLE_LOC(start, idx)   ((start) + ((idx) << 2))
309 
310 #define DEV_CHAR_TABLE_LOC1(start, idx) ((start) + ((idx) << 4))
311 #define DEV_CHAR_TABLE_MSB_PID(x)       ((x) & GENMASK(31, 16))
312 #define DEV_CHAR_TABLE_LSB_PID(x)       ((x) & GENMASK(15, 0))
313 #define DEV_CHAR_TABLE_LOC2(start, idx) ((DEV_CHAR_TABLE_LOC1(start, idx)) + 4)
314 #define DEV_CHAR_TABLE_LOC3(start, idx) ((DEV_CHAR_TABLE_LOC1(start, idx)) + 8)
315 #define DEV_CHAR_TABLE_DCR(x)           ((x) & GENMASK(7, 0))
316 #define DEV_CHAR_TABLE_BCR(x)           (((x) & GENMASK(15, 8)) >> 8)
317 
318 #define I3C_BUS_SDR1_SCL_RATE       8000000
319 #define I3C_BUS_SDR2_SCL_RATE       6000000
320 #define I3C_BUS_SDR3_SCL_RATE       4000000
321 #define I3C_BUS_SDR4_SCL_RATE       2000000
322 #define I3C_BUS_I2C_FM_TLOW_MIN_NS  1300
323 #define I3C_BUS_I2C_FMP_TLOW_MIN_NS 500
324 #define I3C_BUS_THIGH_MAX_NS        41
325 #define I3C_PERIOD_NS               1000000000ULL
326 
327 #define I3C_BUS_MAX_I3C_SCL_RATE     12900000
328 #define I3C_BUS_TYP_I3C_SCL_RATE     12500000
329 #define I3C_BUS_I2C_FM_PLUS_SCL_RATE 1000000
330 #define I3C_BUS_I2C_FM_SCL_RATE      400000
331 #define I3C_BUS_TLOW_OD_MIN_NS       200
332 
333 #define I3C_HOT_JOIN_ADDR 0x02
334 
335 #define DW_I3C_MAX_DEVS         32
336 #define DW_I3C_MAX_CMD_BUF_SIZE 16
337 
338 /* Snps I3C/I2C Device Private Data */
339 struct dw_i3c_i2c_dev_data {
340 	/* Device id within the retaining registers. This is set after bus initialization by the
341 	 * controller.
342 	 */
343 	uint8_t id;
344 };
345 
346 struct dw_i3c_cmd {
347 	uint32_t cmd_lo;
348 	uint32_t cmd_hi;
349 	void *buf;
350 	uint16_t tx_len;
351 	uint16_t rx_len;
352 	uint8_t error;
353 };
354 
355 struct dw_i3c_xfer {
356 	int32_t ret;
357 	uint32_t ncmds;
358 	struct dw_i3c_cmd cmds[DW_I3C_MAX_CMD_BUF_SIZE];
359 };
360 
361 struct dw_i3c_config {
362 	struct i3c_driver_config common;
363 	const struct device *clock;
364 	uint32_t regs;
365 
366 	/* Initial clk configuration */
367 	/* Maximum OD high clk pulse length */
368 	uint32_t od_thigh_max_ns;
369 	/* Minimum OD low clk pulse length */
370 	uint32_t od_tlow_min_ns;
371 
372 	void (*irq_config_func)();
373 
374 #if defined(CONFIG_PINCTRL)
375 	const struct pinctrl_dev_config *pcfg;
376 #endif
377 };
378 
379 struct dw_i3c_data {
380 	struct i3c_driver_data common;
381 	uint32_t free_pos;
382 
383 	uint16_t datstartaddr;
384 	uint16_t dctstartaddr;
385 	uint16_t maxdevs;
386 
387 	/* fifo depth is in words (32b) */
388 	uint8_t ibififodepth;
389 	uint8_t respfifodepth;
390 	uint8_t cmdfifodepth;
391 	uint8_t rxfifodepth;
392 	uint8_t txfifodepth;
393 
394 	enum i3c_bus_mode mode;
395 
396 	struct i3c_target_config *target_config;
397 
398 	struct k_sem sem_xfer;
399 	struct k_mutex mt;
400 
401 #ifdef CONFIG_I3C_USE_IBI
402 	struct k_sem ibi_sts_sem;
403 	struct k_sem sem_hj;
404 #endif
405 
406 	struct dw_i3c_xfer xfer;
407 
408 	struct dw_i3c_i2c_dev_data dw_i3c_i2c_priv_data[DW_I3C_MAX_DEVS];
409 };
410 
get_free_pos(uint32_t free_pos)411 static uint8_t get_free_pos(uint32_t free_pos)
412 {
413 	return find_lsb_set(free_pos) - 1;
414 }
415 
416 /**
417  * @brief Read data from the Receive FIFO of the I3C device.
418  *
419  * This function reads data from the Receive FIFO of the I3C device specified by
420  * the given device structure and stores it in the provided buffer.
421  *
422  * @param dev Pointer to the I3C device structure.
423  * @param buf Pointer to the buffer where the received data will be stored.
424  * @param nbytes Number of bytes to read from the Receive FIFO.
425  */
read_rx_fifo(const struct device * dev,uint8_t * buf,int32_t nbytes)426 static void read_rx_fifo(const struct device *dev, uint8_t *buf, int32_t nbytes)
427 {
428 	__ASSERT((buf != NULL), "Rx buffer should not be NULL");
429 
430 	const struct dw_i3c_config *config = dev->config;
431 	int32_t i;
432 	uint32_t tmp;
433 
434 	if (nbytes >= 4) {
435 		for (i = 0; i <= nbytes - 4; i += 4) {
436 			tmp = sys_read32(config->regs + RX_TX_DATA_PORT);
437 			memcpy(buf + i, &tmp, 4);
438 		}
439 	}
440 	if (nbytes & 3) {
441 		tmp = sys_read32(config->regs + RX_TX_DATA_PORT);
442 		memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3);
443 	}
444 }
445 
446 /**
447  * @brief Write data to the Transmit FIFO of the I3C device.
448  *
449  * This function writes data to the Transmit FIFO of the I3C device specified by
450  * the given device structure from the provided buffer.
451  *
452  * @param dev Pointer to the I3C device structure.
453  * @param buf Pointer to the buffer containing the data to be written.
454  * @param nbytes Number of bytes to write to the Transmit FIFO.
455  */
write_tx_fifo(const struct device * dev,const uint8_t * buf,int32_t nbytes)456 static void write_tx_fifo(const struct device *dev, const uint8_t *buf, int32_t nbytes)
457 {
458 	__ASSERT((buf != NULL), "Tx buffer should not be NULL");
459 
460 	const struct dw_i3c_config *config = dev->config;
461 	int32_t i;
462 	uint32_t tmp;
463 
464 	if (nbytes >= 4) {
465 		for (i = 0; i <= nbytes - 4; i += 4) {
466 			memcpy(&tmp, buf + i, 4);
467 			sys_write32(tmp, config->regs + RX_TX_DATA_PORT);
468 		}
469 	}
470 
471 	if (nbytes & 3) {
472 		tmp = 0;
473 		memcpy(&tmp, buf + (nbytes & ~3), nbytes & 3);
474 		sys_write32(tmp, config->regs + RX_TX_DATA_PORT);
475 	}
476 }
477 
478 #ifdef CONFIG_I3C_USE_IBI
479 /**
480  * @brief Read data from the In-Band Interrupt (IBI) FIFO of the I3C device.
481  *
482  * This function reads data from the In-Band Interrupt (IBI) FIFO of the I3C device
483  * specified by the given device structure and stores it in the provided buffer.
484  *
485  * @param dev Pointer to the I3C device structure.
486  * @param buf Pointer to the buffer where the received IBI data will be stored.
487  * @param nbytes Number of bytes to read from the IBI FIFO.
488  */
read_ibi_fifo(const struct device * dev,uint8_t * buf,int32_t nbytes)489 static void read_ibi_fifo(const struct device *dev, uint8_t *buf, int32_t nbytes)
490 {
491 	__ASSERT((buf != NULL), "Rx IBI buffer should not be NULL");
492 
493 	const struct dw_i3c_config *config = dev->config;
494 	int32_t i;
495 	uint32_t tmp;
496 
497 	if (nbytes >= 4) {
498 		for (i = 0; i <= nbytes - 4; i += 4) {
499 			tmp = sys_read32(config->regs + IBI_QUEUE_STATUS);
500 			memcpy(buf + i, &tmp, 4);
501 		}
502 	}
503 	if (nbytes & 3) {
504 		tmp = sys_read32(config->regs + IBI_QUEUE_STATUS);
505 		memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3);
506 	}
507 }
508 #endif
509 
510 /**
511  * @brief End the I3C transfer and process responses.
512  *
513  * This function is responsible for ending the I3C transfer on the specified
514  * I3C device. It processes the responses received from the I3C bus, updating the
515  * status and error information in the transfer structure.
516  *
517  * @param dev Pointer to the I3C device structure.
518  */
dw_i3c_end_xfer(const struct device * dev)519 static void dw_i3c_end_xfer(const struct device *dev)
520 {
521 	const struct dw_i3c_config *config = dev->config;
522 	struct dw_i3c_data *data = dev->data;
523 	struct dw_i3c_xfer *xfer = &data->xfer;
524 	struct dw_i3c_cmd *cmd;
525 	uint32_t nresp, resp, rx_data;
526 	int32_t i, j, k, ret = 0;
527 
528 	nresp = QUEUE_STATUS_LEVEL_RESP(sys_read32(config->regs + QUEUE_STATUS_LEVEL));
529 	for (i = 0; i < nresp; i++) {
530 		uint8_t tid;
531 
532 		resp = sys_read32(config->regs + RESPONSE_QUEUE_PORT);
533 		tid = RESPONSE_PORT_TID(resp);
534 		if (tid == 0xf) {
535 			/* TODO: handle vendor extension ccc or hdr header in target mode */
536 			continue;
537 		}
538 
539 		cmd = &xfer->cmds[tid];
540 		cmd->rx_len = RESPONSE_PORT_DATA_LEN(resp);
541 		cmd->error = RESPONSE_PORT_ERR_STATUS(resp);
542 
543 		/* if we are in target mode */
544 		if (!(sys_read32(config->regs + PRESENT_STATE) & PRESENT_STATE_CURRENT_MASTER)) {
545 			const struct i3c_target_callbacks *target_cb =
546 				data->target_config->callbacks;
547 
548 			for (j = 0; j < cmd->rx_len; j += 4) {
549 				rx_data = sys_read32(config->regs + RX_TX_DATA_PORT);
550 				/* Call write received cb for each remaining byte  */
551 				for (k = 0; k < MIN(4, cmd->rx_len - j); k++) {
552 					target_cb->write_received_cb(data->target_config,
553 								    (rx_data >> (8 * k)) & 0xff);
554 				}
555 			}
556 
557 			if (target_cb != NULL && target_cb->stop_cb != NULL) {
558 				/*
559 				 * TODO: modify API to include status, such as success or aborted
560 				 * transfer
561 				 */
562 				target_cb->stop_cb(data->target_config);
563 			}
564 		}
565 	}
566 
567 	for (i = 0; i < nresp; i++) {
568 		switch (xfer->cmds[i].error) {
569 		case RESPONSE_NO_ERROR:
570 			break;
571 		case RESPONSE_ERROR_PARITY:
572 		case RESPONSE_ERROR_IBA_NACK:
573 		case RESPONSE_ERROR_TRANSF_ABORT:
574 		case RESPONSE_ERROR_CRC:
575 		case RESPONSE_ERROR_FRAME:
576 			ret = -EIO;
577 			break;
578 		case RESPONSE_ERROR_OVER_UNDER_FLOW:
579 			ret = -ENOSPC;
580 			break;
581 		case RESPONSE_ERROR_I2C_W_NACK_ERR:
582 		case RESPONSE_ERROR_ADDRESS_NACK:
583 			ret = -ENXIO;
584 			break;
585 		default:
586 			ret = -EINVAL;
587 			break;
588 		}
589 	}
590 	xfer->ret = ret;
591 
592 	if (ret < 0) {
593 		sys_write32(RESET_CTRL_RX_FIFO | RESET_CTRL_TX_FIFO | RESET_CTRL_RESP_QUEUE |
594 			    RESET_CTRL_CMD_QUEUE,
595 			    config->regs + RESET_CTRL);
596 		sys_write32(sys_read32(config->regs + DEVICE_CTRL) | DEV_CTRL_RESUME,
597 			    config->regs + DEVICE_CTRL);
598 	}
599 	k_sem_give(&data->sem_xfer);
600 }
601 
602 /**
603  * @brief Start an I3C transfer on the specified device.
604  *
605  * This function initiates an I3C transfer on the specified I3C device by pushing
606  * data to the Transmit FIFO (TXFIFO) and enqueuing commands to the command queue.
607  *
608  * @param dev Pointer to the I3C device structure.
609  */
start_xfer(const struct device * dev)610 static void start_xfer(const struct device *dev)
611 {
612 	const struct dw_i3c_config *config = dev->config;
613 	struct dw_i3c_data *data = dev->data;
614 	struct dw_i3c_xfer *xfer = &data->xfer;
615 	struct dw_i3c_cmd *cmd;
616 	uint32_t thld_ctrl, present_state;
617 	int32_t i;
618 
619 	present_state = sys_read32(config->regs + PRESENT_STATE);
620 
621 	/* Push data to TXFIFO */
622 	for (i = 0; i < xfer->ncmds; i++) {
623 		cmd = &xfer->cmds[i];
624 		/* Not all the commands use write_tx_fifo function */
625 		if (cmd->buf != NULL) {
626 			write_tx_fifo(dev, cmd->buf, cmd->tx_len);
627 		}
628 	}
629 
630 	thld_ctrl = sys_read32(config->regs + QUEUE_THLD_CTRL);
631 	thld_ctrl &= ~QUEUE_THLD_CTRL_RESP_BUF_MASK;
632 	thld_ctrl |= QUEUE_THLD_CTRL_RESP_BUF(xfer->ncmds);
633 	sys_write32(thld_ctrl, config->regs + QUEUE_THLD_CTRL);
634 
635 	/* Enqueue CMD */
636 	for (i = 0; i < xfer->ncmds; i++) {
637 		cmd = &xfer->cmds[i];
638 		/* Only cmd_lo is used when it is a target */
639 		if (present_state & PRESENT_STATE_CURRENT_MASTER) {
640 			sys_write32(cmd->cmd_hi, config->regs + COMMAND_QUEUE_PORT);
641 		}
642 		sys_write32(cmd->cmd_lo, config->regs + COMMAND_QUEUE_PORT);
643 	}
644 }
645 
646 /**
647  * @brief Get the position of an I3C device with the specified address.
648  *
649  * This function retrieves the position (ID) of an I3C device with the specified
650  * address on the I3C bus associated with the provided I3C device structure. This
651  * utilizes the controller private data for where the id reg is stored.
652  *
653  * @param dev Pointer to the I3C device structure.
654  * @param addr I3C address of the device whose position is to be retrieved.
655  * @param sa True if looking up by Static Address, False if by Dynamic Address
656  *
657  * @return The position (ID) of the device on success, or a negative error code
658  *         if the device with the given address is not found.
659  */
get_i3c_addr_pos(const struct device * dev,uint8_t addr,bool sa)660 static int get_i3c_addr_pos(const struct device *dev, uint8_t addr, bool sa)
661 {
662 	struct dw_i3c_i2c_dev_data *dw_i3c_device_data;
663 	struct i3c_device_desc *desc = sa ? i3c_dev_list_i3c_static_addr_find(dev, addr)
664 					  : i3c_dev_list_i3c_addr_find(dev, addr);
665 
666 	if (desc == NULL) {
667 		return -ENODEV;
668 	}
669 
670 	dw_i3c_device_data = desc->controller_priv;
671 
672 	return dw_i3c_device_data->id;
673 }
674 
675 /**
676  * @brief Transfer messages in I3C mode.
677  *
678  * @param dev Pointer to device driver instance.
679  * @param target Pointer to target device descriptor.
680  * @param msgs Pointer to I3C messages.
681  * @param num_msgs Number of messages to transfers.
682  *
683  * @retval 0 If successful.
684  * @retval -EIO General input / output error.
685  * @retval -EINVAL Address not registered
686  */
dw_i3c_xfers(const struct device * dev,struct i3c_device_desc * target,struct i3c_msg * msgs,uint8_t num_msgs)687 static int dw_i3c_xfers(const struct device *dev, struct i3c_device_desc *target,
688 			struct i3c_msg *msgs, uint8_t num_msgs)
689 {
690 	const struct dw_i3c_config *config = dev->config;
691 	struct dw_i3c_data *data = dev->data;
692 	struct dw_i3c_xfer *xfer = &data->xfer;
693 	int32_t ret, i, pos, nrxwords = 0, ntxwords = 0;
694 	uint32_t present_state;
695 
696 	present_state = sys_read32(config->regs + PRESENT_STATE);
697 	if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) {
698 		return -EACCES;
699 	}
700 
701 	if (num_msgs > data->cmdfifodepth) {
702 		return -ENOTSUP;
703 	}
704 
705 	pos = get_i3c_addr_pos(dev, target->dynamic_addr, false);
706 	if (pos < 0) {
707 		LOG_ERR("%s: Invalid slave device", dev->name);
708 		return -EINVAL;
709 	}
710 
711 	for (i = 0; i < num_msgs; i++) {
712 		if (msgs[i].flags & I2C_MSG_READ) {
713 			nrxwords += DIV_ROUND_UP(msgs[i].len, 4);
714 		} else {
715 			ntxwords += DIV_ROUND_UP(msgs[i].len, 4);
716 		}
717 	}
718 
719 	if (ntxwords > data->txfifodepth || nrxwords > data->rxfifodepth) {
720 		return -ENOTSUP;
721 	}
722 
723 	ret = k_mutex_lock(&data->mt, K_MSEC(1000));
724 	if (ret) {
725 		LOG_ERR("%s: Mutex err (%d)", dev->name, ret);
726 		return ret;
727 	}
728 
729 	pm_device_busy_set(dev);
730 
731 	memset(xfer, 0, sizeof(struct dw_i3c_xfer));
732 
733 	xfer->ncmds = num_msgs;
734 	xfer->ret = -1;
735 
736 	for (i = 0; i < num_msgs; i++) {
737 		struct dw_i3c_cmd *cmd = &xfer->cmds[i];
738 
739 		cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(msgs[i].len) | COMMAND_PORT_TRANSFER_ARG;
740 		cmd->cmd_lo = COMMAND_PORT_TID(i) | COMMAND_PORT_DEV_INDEX(pos) | COMMAND_PORT_ROC;
741 
742 		cmd->buf = msgs[i].buf;
743 
744 		if (msgs[i].flags & I3C_MSG_NBCH) {
745 			sys_write32(sys_read32(config->regs + DEVICE_CTRL) & ~DEV_CTRL_IBA_INCLUDE,
746 				    config->regs + DEVICE_CTRL);
747 		} else {
748 			sys_write32(sys_read32(config->regs + DEVICE_CTRL) | DEV_CTRL_IBA_INCLUDE,
749 				    config->regs + DEVICE_CTRL);
750 		}
751 
752 		if (msgs[i].flags & I3C_MSG_READ) {
753 			uint8_t rd_speed;
754 
755 			if (msgs[i].flags & I3C_MSG_HDR) {
756 				/* Set read command bit for DDR and TS */
757 				cmd->cmd_lo |= COMMAND_PORT_CP |
758 					       COMMAND_PORT_CMD(BIT(7) | (msgs[i].hdr_cmd_code &
759 									  GENMASK(6, 0)));
760 				if (msgs[i].hdr_mode & I3C_MSG_HDR_DDR) {
761 					if (data->common.ctrl_config.supported_hdr &
762 					    I3C_MSG_HDR_DDR) {
763 						rd_speed = COMMAND_PORT_SPEED_I3C_DDR;
764 					} else {
765 						/* DDR support not configured with this */
766 						LOG_ERR("%s: HDR-DDR not supported", dev->name);
767 						ret = -ENOTSUP;
768 						goto error;
769 					}
770 				} else if (msgs[i].hdr_mode & I3C_MSG_HDR_TSP ||
771 					   msgs[i].hdr_mode & I3C_MSG_HDR_TSL) {
772 					if (data->common.ctrl_config.supported_hdr &
773 					    (I3C_MSG_HDR_TSP | I3C_MSG_HDR_TSL)) {
774 						rd_speed = COMMAND_PORT_SPEED_I3C_TS;
775 					} else {
776 						/* TS support not configured with this */
777 						LOG_ERR("%s: HDR-TS not supported", dev->name);
778 						ret = -ENOTSUP;
779 						goto error;
780 					}
781 				} else {
782 					LOG_ERR("%s: HDR %d not supported", dev->name,
783 						msgs[i].hdr_mode);
784 					ret = -ENOTSUP;
785 					goto error;
786 				}
787 			} else {
788 				rd_speed = I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL(
789 					target->data_speed.maxrd);
790 			}
791 
792 			cmd->cmd_lo |= (COMMAND_PORT_READ_TRANSFER | COMMAND_PORT_SPEED(rd_speed));
793 			cmd->rx_len = msgs[i].len;
794 		} else {
795 			uint8_t wr_speed;
796 
797 			if (msgs[i].flags & I3C_MSG_HDR) {
798 				cmd->cmd_lo |=
799 					COMMAND_PORT_CP |
800 					COMMAND_PORT_CMD(msgs[i].hdr_cmd_code & GENMASK(6, 0));
801 				if (msgs[i].hdr_mode & I3C_MSG_HDR_DDR) {
802 					if (data->common.ctrl_config.supported_hdr &
803 					    I3C_MSG_HDR_DDR) {
804 						wr_speed = COMMAND_PORT_SPEED_I3C_DDR;
805 					} else {
806 						/* DDR support not configured with this */
807 						LOG_ERR("%s: HDR-DDR not supported", dev->name);
808 						ret = -ENOTSUP;
809 						goto error;
810 					}
811 				} else if (msgs[i].hdr_mode & I3C_MSG_HDR_TSP ||
812 					   msgs[i].hdr_mode & I3C_MSG_HDR_TSL) {
813 					if (data->common.ctrl_config.supported_hdr &
814 					    (I3C_MSG_HDR_TSP | I3C_MSG_HDR_TSL)) {
815 						wr_speed = COMMAND_PORT_SPEED_I3C_TS;
816 					} else {
817 						/* TS support not configured with this */
818 						LOG_ERR("%s: HDR-TS not supported", dev->name);
819 						ret = -ENOTSUP;
820 						goto error;
821 					}
822 				} else {
823 					LOG_ERR("%s: HDR %d not supported", dev->name,
824 						msgs[i].hdr_mode);
825 					ret = -ENOTSUP;
826 					goto error;
827 				}
828 			} else {
829 				wr_speed = I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL(
830 					target->data_speed.maxwr);
831 			}
832 
833 			cmd->cmd_lo |= COMMAND_PORT_SPEED(wr_speed);
834 			cmd->tx_len = msgs[i].len;
835 		}
836 
837 		if (i == (num_msgs - 1)) {
838 			cmd->cmd_lo |= COMMAND_PORT_TOC;
839 		}
840 	}
841 
842 	start_xfer(dev);
843 
844 	ret = k_sem_take(&data->sem_xfer, K_MSEC(CONFIG_I3C_DW_RW_TIMEOUT_MS));
845 	if (ret) {
846 		LOG_ERR("%s: Semaphore err (%d)", dev->name, ret);
847 		goto error;
848 	}
849 
850 	for (i = 0; i < xfer->ncmds; i++) {
851 		msgs[i].num_xfer = (msgs[i].flags & I3C_MSG_READ) ? xfer->cmds[i].rx_len
852 								  : xfer->cmds[i].tx_len;
853 		if (xfer->cmds[i].rx_len && !xfer->cmds[i].error) {
854 			read_rx_fifo(dev, xfer->cmds[i].buf, xfer->cmds[i].rx_len);
855 		}
856 	}
857 
858 	ret = xfer->ret;
859 
860 error:
861 	pm_device_busy_clear(dev);
862 	k_mutex_unlock(&data->mt);
863 
864 	return ret;
865 }
866 
dw_i3c_i2c_attach_device(const struct device * dev,struct i3c_i2c_device_desc * desc)867 static int dw_i3c_i2c_attach_device(const struct device *dev, struct i3c_i2c_device_desc *desc)
868 {
869 	const struct dw_i3c_config *config = dev->config;
870 	struct dw_i3c_data *data = dev->data;
871 	uint8_t pos;
872 
873 	pos = get_free_pos(data->free_pos);
874 	if (pos < 0) {
875 		return -ENOSPC;
876 	}
877 
878 	data->dw_i3c_i2c_priv_data[pos].id = pos;
879 	desc->controller_priv = &(data->dw_i3c_i2c_priv_data[pos]);
880 	data->free_pos &= ~BIT(pos);
881 
882 	sys_write32(DEV_ADDR_TABLE_LEGACY_I2C_DEV | DEV_ADDR_TABLE_STATIC_ADDR(desc->addr),
883 		    config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos));
884 
885 	return 0;
886 }
887 
dw_i3c_i2c_detach_device(const struct device * dev,struct i3c_i2c_device_desc * desc)888 static void dw_i3c_i2c_detach_device(const struct device *dev, struct i3c_i2c_device_desc *desc)
889 {
890 	const struct dw_i3c_config *config = dev->config;
891 	struct dw_i3c_data *data = dev->data;
892 	struct dw_i3c_i2c_dev_data *dw_i2c_device_data = desc->controller_priv;
893 
894 	__ASSERT_NO_MSG(dw_i2c_device_data != NULL);
895 
896 	sys_write32(0,
897 		    config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, dw_i2c_device_data->id));
898 	data->free_pos |= BIT(dw_i2c_device_data->id);
899 	desc->controller_priv = NULL;
900 }
901 
902 /**
903  * @brief Transfer messages in I2C mode.
904  *
905  * @param dev Pointer to device driver instance.
906  * @param target Pointer to target device descriptor.
907  * @param msgs Pointer to I2C messages.
908  * @param num_msgs Number of messages to transfers.
909  *
910  * @retval 0 If successful.
911  * @retval -EIO General input / output error.
912  * @retval -EINVAL Address not registered
913  */
dw_i3c_i2c_transfer(const struct device * dev,struct i3c_i2c_device_desc * target,struct i2c_msg * msgs,uint8_t num_msgs)914 static int dw_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device_desc *target,
915 			       struct i2c_msg *msgs, uint8_t num_msgs)
916 {
917 	const struct dw_i3c_config *config = dev->config;
918 	struct dw_i3c_data *data = dev->data;
919 	struct dw_i3c_xfer *xfer = &data->xfer;
920 	int32_t ret, i, pos, nrxwords = 0, ntxwords = 0;
921 	uint32_t present_state;
922 
923 	present_state = sys_read32(config->regs + PRESENT_STATE);
924 	if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) {
925 		return -EACCES;
926 	}
927 
928 	if (num_msgs > data->cmdfifodepth) {
929 		return -ENOTSUP;
930 	}
931 
932 	for (i = 0; i < num_msgs; i++) {
933 		if (msgs[i].flags & I2C_MSG_READ) {
934 			nrxwords += DIV_ROUND_UP(msgs[i].len, 4);
935 		} else {
936 			ntxwords += DIV_ROUND_UP(msgs[i].len, 4);
937 		}
938 	}
939 
940 	if (ntxwords > data->txfifodepth || nrxwords > data->rxfifodepth) {
941 		return -ENOTSUP;
942 	}
943 
944 	ret = k_mutex_lock(&data->mt, K_MSEC(1000));
945 	if (ret) {
946 		LOG_ERR("%s: Mutex err (%d)", dev->name, ret);
947 		return ret;
948 	}
949 
950 	pm_device_busy_set(dev);
951 
952 	/* In order limit the number of retaining registers occupied by connected devices,
953 	 * I2C devices are only configured during transfers. This allows the number of devices
954 	 * to be larger than the number of retaining registers on mixed buses.
955 	 */
956 	ret = dw_i3c_i2c_attach_device(dev, target);
957 	if (ret != 0) {
958 		LOG_ERR("%s: Failed to attach I2C device (%d)", dev->name, ret);
959 		goto error_attach;
960 	}
961 	pos = ((struct dw_i3c_i2c_dev_data *)target->controller_priv)->id;
962 
963 	memset(xfer, 0, sizeof(struct dw_i3c_xfer));
964 
965 	xfer->ncmds = num_msgs;
966 	xfer->ret = -1;
967 
968 	for (i = 0; i < num_msgs; i++) {
969 		struct dw_i3c_cmd *cmd = &xfer->cmds[i];
970 
971 		cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(msgs[i].len) | COMMAND_PORT_TRANSFER_ARG;
972 		cmd->cmd_lo = COMMAND_PORT_TID(i) | COMMAND_PORT_DEV_INDEX(pos) | COMMAND_PORT_ROC;
973 
974 		cmd->buf = msgs[i].buf;
975 
976 		if (msgs[i].flags & I2C_MSG_READ) {
977 			uint8_t rd_speed = I3C_LVR_I2C_MODE(target->lvr) == I3C_LVR_I2C_FM_MODE
978 						   ? COMMAND_PORT_SPEED_I2C_FM
979 						   : COMMAND_PORT_SPEED_I2C_FMP;
980 
981 			cmd->cmd_lo |= (COMMAND_PORT_READ_TRANSFER | COMMAND_PORT_SPEED(rd_speed));
982 			cmd->rx_len = msgs[i].len;
983 		} else {
984 			uint8_t wr_speed = I3C_LVR_I2C_MODE(target->lvr) == I3C_LVR_I2C_FM_MODE
985 						   ? COMMAND_PORT_SPEED_I2C_FM
986 						   : COMMAND_PORT_SPEED_I2C_FMP;
987 
988 			cmd->cmd_lo |= COMMAND_PORT_SPEED(wr_speed);
989 			cmd->tx_len = msgs[i].len;
990 		}
991 
992 		if (i == (num_msgs - 1)) {
993 			cmd->cmd_lo |= COMMAND_PORT_TOC;
994 		}
995 	}
996 
997 	/* Do not send broadcast address (0x7E) with I2C transfers */
998 	sys_write32(sys_read32(config->regs + DEVICE_CTRL) & ~DEV_CTRL_IBA_INCLUDE,
999 		    config->regs + DEVICE_CTRL);
1000 
1001 	start_xfer(dev);
1002 
1003 	ret = k_sem_take(&data->sem_xfer, K_MSEC(CONFIG_I3C_DW_RW_TIMEOUT_MS));
1004 	if (ret) {
1005 		LOG_ERR("%s: Semaphore err (%d)", dev->name, ret);
1006 		goto error;
1007 	}
1008 
1009 	for (i = 0; i < xfer->ncmds; i++) {
1010 		if (xfer->cmds[i].rx_len && !xfer->cmds[i].error) {
1011 			read_rx_fifo(dev, xfer->cmds[i].buf, xfer->cmds[i].rx_len);
1012 		}
1013 	}
1014 
1015 	ret = xfer->ret;
1016 
1017 error:
1018 	dw_i3c_i2c_detach_device(dev, target);
1019 error_attach:
1020 	pm_device_busy_clear(dev);
1021 	k_mutex_unlock(&data->mt);
1022 
1023 	return ret;
1024 }
1025 
1026 /**
1027  * Find a registered I2C target device.
1028  *
1029  * Controller only API.
1030  *
1031  * This returns the I2C device descriptor of the I2C device
1032  * matching the device address @p addr.
1033  *
1034  * @param dev Pointer to controller device driver instance.
1035  * @param id I2C target device address.
1036  *
1037  * @return @see i3c_i2c_device_find.
1038  */
dw_i3c_i2c_device_find(const struct device * dev,uint16_t addr)1039 static struct i3c_i2c_device_desc *dw_i3c_i2c_device_find(const struct device *dev, uint16_t addr)
1040 {
1041 	return i3c_dev_list_i2c_addr_find(dev, addr);
1042 }
1043 
1044 /**
1045  * @brief Transfer messages in I2C mode.
1046  *
1047  * @see i2c_transfer
1048  *
1049  * @param dev Pointer to device driver instance.
1050  * @param msgs Pointer to I2C messages.
1051  * @param num_msgs Number of messages to transfers.
1052  * @param addr Address of the I2C target device.
1053  *
1054  * @return @see i2c_transfer
1055  */
dw_i3c_i2c_api_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)1056 static int dw_i3c_i2c_api_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs,
1057 				   uint16_t addr)
1058 {
1059 	struct i3c_i2c_device_desc *i2c_dev = dw_i3c_i2c_device_find(dev, addr);
1060 
1061 	if (i2c_dev == NULL) {
1062 		return -ENODEV;
1063 	}
1064 
1065 	return dw_i3c_i2c_transfer(dev, i2c_dev, msgs, num_msgs);
1066 }
1067 
1068 #ifdef CONFIG_I3C_USE_IBI
dw_i3c_controller_ibi_hj_response(const struct device * dev,bool ack)1069 static int dw_i3c_controller_ibi_hj_response(const struct device *dev, bool ack)
1070 {
1071 	const struct dw_i3c_config *config = dev->config;
1072 	uint32_t ctrl = sys_read32(config->regs + DEVICE_CTRL);
1073 
1074 	if (ack) {
1075 		ctrl &= ~DEV_CTRL_HOT_JOIN_NACK;
1076 	} else {
1077 		ctrl |= DEV_CTRL_HOT_JOIN_NACK;
1078 	}
1079 
1080 	sys_write32(ctrl, config->regs + DEVICE_CTRL);
1081 
1082 	return 0;
1083 }
1084 
i3c_dw_endis_ibi(const struct device * dev,struct i3c_device_desc * target,bool en)1085 static int i3c_dw_endis_ibi(const struct device *dev, struct i3c_device_desc *target, bool en)
1086 {
1087 	struct dw_i3c_data *data = dev->data;
1088 	const struct dw_i3c_config *config = dev->config;
1089 	uint32_t bitpos, sir_con;
1090 	struct i3c_ccc_events i3c_events;
1091 	int ret;
1092 	int pos;
1093 
1094 	pos = get_i3c_addr_pos(dev, target->dynamic_addr, false);
1095 	if (pos < 0) {
1096 		LOG_ERR("%s: Invalid Slave address", dev->name);
1097 		return pos;
1098 	}
1099 
1100 	uint32_t reg = sys_read32(config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos));
1101 
1102 	if (i3c_ibi_has_payload(target)) {
1103 		reg |= DEV_ADDR_TABLE_IBI_WITH_DATA;
1104 	} else {
1105 		reg &= ~DEV_ADDR_TABLE_IBI_WITH_DATA;
1106 	}
1107 	if (en) {
1108 		reg &= ~DEV_ADDR_TABLE_SIR_REJECT;
1109 	} else {
1110 		reg |= DEV_ADDR_TABLE_SIR_REJECT;
1111 	}
1112 	sys_write32(reg, config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos));
1113 
1114 	sir_con = sys_read32(config->regs + IBI_SIR_REQ_REJECT);
1115 	/* TODO: what is this macro doing?? */
1116 	bitpos = IBI_SIR_REQ_ID(target->dynamic_addr);
1117 
1118 	if (en) {
1119 		sir_con &= ~BIT(bitpos);
1120 	} else {
1121 		sir_con |= BIT(bitpos);
1122 	}
1123 	sys_write32(sir_con, config->regs + IBI_SIR_REQ_REJECT);
1124 
1125 	/* Tell target to enable IBI */
1126 	i3c_events.events = I3C_CCC_EVT_INTR;
1127 	ret = i3c_ccc_do_events_set(target, en, &i3c_events);
1128 	if (ret != 0) {
1129 		LOG_ERR("%s: Error sending IBI ENEC for 0x%02x (%d)", dev->name,
1130 			target->dynamic_addr, ret);
1131 		return ret;
1132 	}
1133 
1134 	return 0;
1135 }
1136 
dw_i3c_controller_enable_ibi(const struct device * dev,struct i3c_device_desc * target)1137 static int dw_i3c_controller_enable_ibi(const struct device *dev, struct i3c_device_desc *target)
1138 {
1139 	return i3c_dw_endis_ibi(dev, target, true);
1140 }
1141 
dw_i3c_controller_disable_ibi(const struct device * dev,struct i3c_device_desc * target)1142 static int dw_i3c_controller_disable_ibi(const struct device *dev, struct i3c_device_desc *target)
1143 {
1144 	return i3c_dw_endis_ibi(dev, target, false);
1145 }
1146 
dw_i3c_handle_tir(const struct device * dev,uint32_t ibi_status)1147 static void dw_i3c_handle_tir(const struct device *dev, uint32_t ibi_status)
1148 {
1149 	uint8_t ibi_data[CONFIG_I3C_IBI_MAX_PAYLOAD_SIZE];
1150 	uint8_t addr, len;
1151 	int pos;
1152 
1153 	addr = IBI_QUEUE_IBI_ADDR(ibi_status);
1154 	len = IBI_QUEUE_STATUS_DATA_LEN(ibi_status);
1155 
1156 	pos = get_i3c_addr_pos(dev, addr, false);
1157 	if (pos < 0) {
1158 		LOG_ERR("%s: Invalid Slave address", dev->name);
1159 		return;
1160 	}
1161 
1162 	struct i3c_device_desc *desc = i3c_dev_list_i3c_addr_find(dev, addr);
1163 
1164 	if (desc == NULL) {
1165 		return;
1166 	}
1167 
1168 	if (len > 0) {
1169 		read_ibi_fifo(dev, ibi_data, len);
1170 	}
1171 
1172 	if (i3c_ibi_work_enqueue_target_irq(desc, ibi_data, len) != 0) {
1173 		LOG_ERR("%s: Error enqueue IBI IRQ work", dev->name);
1174 	}
1175 }
1176 
dw_i3c_handle_hj(const struct device * dev,uint32_t ibi_status)1177 static void dw_i3c_handle_hj(const struct device *dev, uint32_t ibi_status)
1178 {
1179 	if (IBI_QUEUE_STATUS_IBI_STS(ibi_status) & BIT(3)) {
1180 		LOG_DBG("%s: NAK for HJ", dev->name);
1181 		return;
1182 	}
1183 
1184 	if (i3c_ibi_work_enqueue_hotjoin(dev) != 0) {
1185 		LOG_ERR("%s: Error enqueue IBI HJ work", dev->name);
1186 	}
1187 }
1188 
ibis_handle(const struct device * dev)1189 static void ibis_handle(const struct device *dev)
1190 {
1191 	const struct dw_i3c_config *config = dev->config;
1192 	uint32_t nibis, ibi_stat;
1193 	int32_t i;
1194 
1195 	nibis = sys_read32(config->regs + QUEUE_STATUS_LEVEL);
1196 	nibis = QUEUE_STATUS_IBI_BUF_BLR(nibis);
1197 	for (i = 0; i < nibis; i++) {
1198 		ibi_stat = sys_read32(config->regs + IBI_QUEUE_STATUS);
1199 		if (IBI_TYPE_SIRQ(ibi_stat)) {
1200 			dw_i3c_handle_tir(dev, ibi_stat);
1201 		} else if (IBI_TYPE_HJ(ibi_stat)) {
1202 			dw_i3c_handle_hj(dev, ibi_stat);
1203 		} else {
1204 			LOG_DBG("%s: Secondary Master Request Not implemented", dev->name);
1205 		}
1206 	}
1207 }
1208 
dw_i3c_target_ibi_raise_hj(const struct device * dev)1209 static int dw_i3c_target_ibi_raise_hj(const struct device *dev)
1210 {
1211 	const struct dw_i3c_config *config = dev->config;
1212 	struct dw_i3c_data *data = dev->data;
1213 	int ret;
1214 
1215 	if (!(sys_read32(config->regs + HW_CAPABILITY) & HW_CAPABILITY_SLV_HJ_CAP)) {
1216 		LOG_ERR("%s: HJ not supported", dev->name);
1217 		return -ENOTSUP;
1218 	}
1219 	if (sys_read32(config->regs + DEVICE_ADDR) & DEVICE_ADDR_DYNAMIC_ADDR_VALID) {
1220 		LOG_ERR("%s: HJ not available, DA already assigned", dev->name);
1221 		return -EACCES;
1222 	}
1223 	/* if this is set, then it is assumed it is already trying */
1224 	if ((sys_read32(config->regs + SLV_EVENT_STATUS) & SLV_EVENT_STATUS_HJ_EN)) {
1225 		LOG_ERR("%s: HJ requests are currently disabled by DISEC", dev->name);
1226 		return -EAGAIN;
1227 	}
1228 
1229 	/*
1230 	 * This is issued auto-magically by the IP when certain conditions are meet.
1231 	 * These include:
1232 	 * 1. SLV_EVENT_STATUS[HJ_EN] = 1 (or a controller issues Enables HJ events with
1233 	 * the CCC ENEC, This can be set to 0 with CCC DISEC from a controller)
1234 	 * 2. The Dynamic address is invalid. (not assigned yet)
1235 	 * 3. Bus Idle condition is met (1ms) as programmed in the Bus Timing Register
1236 	 */
1237 
1238 	/* enable HJ */
1239 	sys_write32(sys_read32(config->regs + SLV_EVENT_STATUS) | SLV_EVENT_STATUS_HJ_EN,
1240 		    config->regs + SLV_EVENT_STATUS);
1241 
1242 	ret = k_sem_take(&data->sem_hj, K_MSEC(CONFIG_I3C_DW_RW_TIMEOUT_MS));
1243 	if (ret) {
1244 		return ret;
1245 	}
1246 
1247 	return 0;
1248 }
1249 
dw_i3c_target_ibi_raise_tir(const struct device * dev,struct i3c_ibi * request)1250 static int dw_i3c_target_ibi_raise_tir(const struct device *dev, struct i3c_ibi *request)
1251 {
1252 	const struct dw_i3c_config *config = dev->config;
1253 	struct dw_i3c_data *data = dev->data;
1254 	int status;
1255 	uint32_t slv_intr_req, slv_ibi_resp;
1256 
1257 	if (!(sys_read32(config->regs + HW_CAPABILITY) & HW_CAPABILITY_SLV_IBI_CAP)) {
1258 		LOG_ERR("%s: IBI TIR not supported", dev->name);
1259 		return -ENOTSUP;
1260 	}
1261 
1262 	if (!(sys_read32(config->regs + DEVICE_ADDR) & DEVICE_ADDR_DYNAMIC_ADDR_VALID)) {
1263 		LOG_ERR("%s: IBI TIR not available, DA not assigned", dev->name);
1264 		return -EACCES;
1265 	}
1266 
1267 	if (!(sys_read32(config->regs + SLV_EVENT_STATUS) & SLV_EVENT_STATUS_SIR_EN)) {
1268 		LOG_ERR("%s: IBI TIR requests are currently disabled by DISEC", dev->name);
1269 		return -EAGAIN;
1270 	}
1271 
1272 	slv_intr_req = sys_read32(config->regs + SLV_INTR_REQ);
1273 	if (sys_read32(config->regs + SLV_CHAR_CTRL) & SLV_CHAR_CTRL_IBI_PAYLOAD) {
1274 		uint32_t tir_data = 0;
1275 
1276 		/* max support length is DA + MDB (1 byte) + 4 data bytes, MDB must be at least
1277 		 * included
1278 		 */
1279 		if ((request->payload_len > 5) || (request->payload_len == 0)) {
1280 			return -EINVAL;
1281 		}
1282 
1283 		/* MDB should be the first byte of the payload */
1284 		slv_intr_req |= SLV_INTR_REQ_MDB(request->payload[0]) |
1285 				SLV_INTR_REQ_SIR_DATA_LENGTH(request->payload_len - 1);
1286 
1287 		/* program the tir data packet */
1288 		tir_data |=
1289 			SLV_SIR_DATA_BYTE0((request->payload_len > 1) ? request->payload[1] : 0);
1290 		tir_data |=
1291 			SLV_SIR_DATA_BYTE1((request->payload_len > 2) ? request->payload[2] : 0);
1292 		tir_data |=
1293 			SLV_SIR_DATA_BYTE2((request->payload_len > 3) ? request->payload[3] : 0);
1294 		tir_data |=
1295 			SLV_SIR_DATA_BYTE3((request->payload_len > 4) ? request->payload[4] : 0);
1296 		sys_write32(tir_data, config->regs + SLV_SIR_DATA);
1297 	}
1298 
1299 	/* kick off the ibi tir request */
1300 	slv_intr_req |= SLV_INTR_REQ_SIR;
1301 	sys_write32(slv_intr_req, config->regs + SLV_INTR_REQ);
1302 
1303 	/* wait for SLV_IBI_RESP update */
1304 	status = k_sem_take(&data->ibi_sts_sem, K_MSEC(100));
1305 	if (status != 0) {
1306 		return -ETIMEDOUT;
1307 	}
1308 
1309 	slv_ibi_resp = sys_read32(config->regs + SLV_INTR_REQ);
1310 	switch (SLV_IBI_RESP_IBI_STS(slv_ibi_resp)) {
1311 	case SLV_IBI_RESP_IBI_STS_ACK:
1312 		LOG_DBG("%s: Controller ACKed IBI TIR", dev->name);
1313 		return 0;
1314 	case SLV_IBI_RESP_IBI_STS_NACK:
1315 		LOG_ERR("%s: Controller NACKed IBI TIR", dev->name);
1316 		return -EAGAIN;
1317 	case SLV_IBI_RESP_IBI_STS_EARLY_TERMINATE:
1318 		LOG_ERR("%s: Controller aborted IBI TIR with %lu remaining", dev->name,
1319 			SLV_IBI_RESP_DATA_LENGTH(slv_ibi_resp));
1320 		return -EIO;
1321 	default:
1322 		return -EIO;
1323 	}
1324 }
1325 
dw_i3c_target_ibi_raise(const struct device * dev,struct i3c_ibi * request)1326 static int dw_i3c_target_ibi_raise(const struct device *dev, struct i3c_ibi *request)
1327 {
1328 	if (request == NULL) {
1329 		return -EINVAL;
1330 	}
1331 
1332 	switch (request->ibi_type) {
1333 	case I3C_IBI_TARGET_INTR:
1334 		return dw_i3c_target_ibi_raise_tir(dev, request);
1335 	case I3C_IBI_CONTROLLER_ROLE_REQUEST:
1336 		/* TODO: Synopsys I3C can support CR, but not implemented yet */
1337 		return -ENOTSUP;
1338 	case I3C_IBI_HOTJOIN:
1339 		return dw_i3c_target_ibi_raise_hj(dev);
1340 	default:
1341 		return -EINVAL;
1342 	}
1343 }
1344 
1345 #endif /* CONFIG_I3C_USE_IBI */
1346 
i3c_dw_irq(const struct device * dev)1347 static int i3c_dw_irq(const struct device *dev)
1348 {
1349 	const struct dw_i3c_config *config = dev->config;
1350 	struct dw_i3c_data *data = dev->data;
1351 	uint32_t status;
1352 	uint32_t present_state;
1353 
1354 	status = sys_read32(config->regs + INTR_STATUS);
1355 	if (status & (INTR_TRANSFER_ERR_STAT | INTR_RESP_READY_STAT)) {
1356 		dw_i3c_end_xfer(dev);
1357 
1358 		if (status & INTR_TRANSFER_ERR_STAT) {
1359 			sys_write32(INTR_TRANSFER_ERR_STAT, config->regs + INTR_STATUS);
1360 		}
1361 	}
1362 
1363 	if (status & INTR_IBI_THLD_STAT) {
1364 #ifdef CONFIG_I3C_USE_IBI
1365 		ibis_handle(dev);
1366 #endif /* CONFIG_I3C_USE_IBI */
1367 	}
1368 
1369 	/* target mode related interrupts */
1370 	present_state = sys_read32(config->regs + PRESENT_STATE);
1371 	if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) {
1372 		const struct i3c_target_callbacks *target_cb =
1373 			data->target_config ? data->target_config->callbacks : NULL;
1374 
1375 		/* Read Requested when the CMDQ is empty*/
1376 		if (status & INTR_READ_REQ_RECV_STAT) {
1377 			if (target_cb != NULL && target_cb->read_requested_cb != NULL) {
1378 				/* Inform app so that it can send data. */
1379 				target_cb->read_requested_cb(data->target_config, NULL);
1380 			}
1381 			sys_write32(INTR_READ_REQ_RECV_STAT, config->regs + INTR_STATUS);
1382 		}
1383 #ifdef CONFIG_I3C_USE_IBI
1384 		/* IBI TIR request register is addressed and status is updated*/
1385 		if (status & INTR_IBI_UPDATED_STAT) {
1386 			k_sem_give(&data->ibi_sts_sem);
1387 			sys_write32(INTR_IBI_UPDATED_STAT, config->regs + INTR_STATUS);
1388 		}
1389 		/* DA has been assigned, could happen after a IBI HJ request */
1390 		if (status & INTR_DYN_ADDR_ASSGN_STAT) {
1391 			/* TODO: handle IBI HJ with semaphore */
1392 			sys_write32(INTR_DYN_ADDR_ASSGN_STAT, config->regs + INTR_STATUS);
1393 		}
1394 #endif /* CONFIG_I3C_USE_IBI */
1395 	}
1396 
1397 	return 0;
1398 }
1399 
init_scl_timing(const struct device * dev)1400 static int init_scl_timing(const struct device *dev)
1401 {
1402 	const struct dw_i3c_config *config = dev->config;
1403 	struct dw_i3c_data *data = dev->data;
1404 	uint32_t scl_timing, hcnt, lcnt, core_rate;
1405 
1406 	if (clock_control_get_rate(config->clock, NULL, &core_rate) != 0) {
1407 		LOG_ERR("%s: get clock rate failed", dev->name);
1408 		return -EINVAL;
1409 	}
1410 
1411 	/* I3C_OD */
1412 	hcnt = DIV_ROUND_UP(config->od_thigh_max_ns * (uint64_t)core_rate, I3C_PERIOD_NS) - 1;
1413 	hcnt = CLAMP(hcnt, SCL_I3C_TIMING_CNT_MIN, SCL_I3C_TIMING_CNT_MAX);
1414 
1415 	lcnt = DIV_ROUND_UP(config->od_tlow_min_ns * (uint64_t)core_rate, I3C_PERIOD_NS);
1416 	lcnt = CLAMP(lcnt, SCL_I3C_TIMING_CNT_MIN, SCL_I3C_TIMING_CNT_MAX);
1417 
1418 	scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | SCL_I3C_TIMING_LCNT(lcnt);
1419 	sys_write32(scl_timing, config->regs + SCL_I3C_OD_TIMING);
1420 
1421 	/* Set bus free timing to match tlow setting for OD clk config. */
1422 	sys_write32(BUS_I3C_MST_FREE(lcnt), config->regs + BUS_FREE_TIMING);
1423 
1424 	/* I3C_PP */
1425 	hcnt = DIV_ROUND_UP(I3C_BUS_THIGH_MAX_NS * (uint64_t)core_rate, I3C_PERIOD_NS) - 1;
1426 	hcnt = CLAMP(hcnt, SCL_I3C_TIMING_CNT_MIN, SCL_I3C_TIMING_CNT_MAX);
1427 
1428 	lcnt = DIV_ROUND_UP(core_rate, data->common.ctrl_config.scl.i3c) - hcnt;
1429 	lcnt = CLAMP(lcnt, SCL_I3C_TIMING_CNT_MIN, SCL_I3C_TIMING_CNT_MAX);
1430 
1431 	scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | SCL_I3C_TIMING_LCNT(lcnt);
1432 	sys_write32(scl_timing, config->regs + SCL_I3C_PP_TIMING);
1433 
1434 	/* I3C */
1435 	lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR1_SCL_RATE) - hcnt;
1436 	scl_timing = SCL_EXT_LCNT_1(lcnt);
1437 	lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR2_SCL_RATE) - hcnt;
1438 	scl_timing |= SCL_EXT_LCNT_2(lcnt);
1439 	lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR3_SCL_RATE) - hcnt;
1440 	scl_timing |= SCL_EXT_LCNT_3(lcnt);
1441 	lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR4_SCL_RATE) - hcnt;
1442 	scl_timing |= SCL_EXT_LCNT_4(lcnt);
1443 	sys_write32(scl_timing, config->regs + SCL_EXT_LCNT_TIMING);
1444 
1445 	/* I2C FM+ */
1446 	lcnt = DIV_ROUND_UP(I3C_BUS_I2C_FMP_TLOW_MIN_NS * (uint64_t)core_rate, I3C_PERIOD_NS);
1447 	hcnt = DIV_ROUND_UP(core_rate, I3C_BUS_I2C_FM_PLUS_SCL_RATE) - lcnt;
1448 	scl_timing = SCL_I2C_FMP_TIMING_HCNT(hcnt) | SCL_I2C_FMP_TIMING_LCNT(lcnt);
1449 	sys_write32(scl_timing, config->regs + SCL_I2C_FMP_TIMING);
1450 
1451 	/* I2C FM */
1452 	lcnt = DIV_ROUND_UP(I3C_BUS_I2C_FM_TLOW_MIN_NS * (uint64_t)core_rate, I3C_PERIOD_NS);
1453 	hcnt = DIV_ROUND_UP(core_rate, I3C_BUS_I2C_FM_SCL_RATE) - lcnt;
1454 	scl_timing = SCL_I2C_FM_TIMING_HCNT(hcnt) | SCL_I2C_FM_TIMING_LCNT(lcnt);
1455 	sys_write32(scl_timing, config->regs + SCL_I2C_FM_TIMING);
1456 
1457 	if (data->mode != I3C_BUS_MODE_PURE) {
1458 		sys_write32(BUS_I3C_MST_FREE(lcnt), config->regs + BUS_FREE_TIMING);
1459 		sys_write32(sys_read32(config->regs + DEVICE_CTRL) | DEV_CTRL_I2C_SLAVE_PRESENT,
1460 			    config->regs + DEVICE_CTRL);
1461 	}
1462 	/* I3C Bus Available Time */
1463 	scl_timing = DIV_ROUND_UP(I3C_BUS_AVAILABLE_TIME_NS * (uint64_t)core_rate,
1464 					I3C_PERIOD_NS);
1465 	sys_write32(BUS_I3C_AVAIL_TIME(scl_timing), config->regs + BUS_FREE_TIMING);
1466 
1467 	/* I3C Bus Idle Time */
1468 	scl_timing =
1469 		DIV_ROUND_UP(I3C_BUS_IDLE_TIME_NS * (uint64_t)core_rate, I3C_PERIOD_NS);
1470 	sys_write32(BUS_I3C_IDLE_TIME(scl_timing), config->regs + BUS_IDLE_TIMING);
1471 
1472 	return 0;
1473 }
1474 
1475 /**
1476  * Determine I3C bus mode from the i2c devices on the bus
1477  *
1478  * Reads the LVR of all I2C devices and returns the I3C bus
1479  * Mode
1480  *
1481  * @param dev_list Pointer to device list
1482  *
1483  * @return @see enum i3c_bus_mode.
1484  */
i3c_bus_mode(const struct i3c_dev_list * dev_list)1485 static enum i3c_bus_mode i3c_bus_mode(const struct i3c_dev_list *dev_list)
1486 {
1487 	enum i3c_bus_mode mode = I3C_BUS_MODE_PURE;
1488 
1489 	for (int i = 0; i < dev_list->num_i2c; i++) {
1490 		switch (I3C_LVR_I2C_DEV_IDX(dev_list->i2c[i].lvr)) {
1491 		case I3C_LVR_I2C_DEV_IDX_0:
1492 			if (mode < I3C_BUS_MODE_MIXED_FAST) {
1493 				mode = I3C_BUS_MODE_MIXED_FAST;
1494 			}
1495 			break;
1496 		case I3C_LVR_I2C_DEV_IDX_1:
1497 			if (mode < I3C_BUS_MODE_MIXED_LIMITED) {
1498 				mode = I3C_BUS_MODE_MIXED_LIMITED;
1499 			}
1500 			break;
1501 		case I3C_LVR_I2C_DEV_IDX_2:
1502 			if (mode < I3C_BUS_MODE_MIXED_SLOW) {
1503 				mode = I3C_BUS_MODE_MIXED_SLOW;
1504 			}
1505 			break;
1506 		default:
1507 			mode = I3C_BUS_MODE_INVALID;
1508 			break;
1509 		}
1510 	}
1511 	return mode;
1512 }
1513 
dw_i3c_attach_device(const struct device * dev,struct i3c_device_desc * desc)1514 static int dw_i3c_attach_device(const struct device *dev, struct i3c_device_desc *desc)
1515 {
1516 	const struct dw_i3c_config *config = dev->config;
1517 	struct dw_i3c_data *data = dev->data;
1518 	uint8_t pos = get_free_pos(data->free_pos);
1519 	uint8_t addr = desc->dynamic_addr ? desc->dynamic_addr : desc->static_addr;
1520 
1521 	if (pos < 0) {
1522 		LOG_ERR("%s: no space for i3c device: %s", dev->name, desc->dev->name);
1523 		return -ENOSPC;
1524 	}
1525 
1526 	data->dw_i3c_i2c_priv_data[pos].id = pos;
1527 	desc->controller_priv = &(data->dw_i3c_i2c_priv_data[pos]);
1528 	data->free_pos &= ~BIT(pos);
1529 
1530 	LOG_DBG("%s: Attaching %s", dev->name, desc->dev->name);
1531 
1532 	sys_write32(DEV_ADDR_TABLE_DYNAMIC_ADDR(addr),
1533 		    config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos));
1534 
1535 	return 0;
1536 }
1537 
dw_i3c_reattach_device(const struct device * dev,struct i3c_device_desc * desc,uint8_t old_dyn_addr)1538 static int dw_i3c_reattach_device(const struct device *dev, struct i3c_device_desc *desc,
1539 				  uint8_t old_dyn_addr)
1540 {
1541 	ARG_UNUSED(old_dyn_addr);
1542 
1543 	const struct dw_i3c_config *config = dev->config;
1544 	struct dw_i3c_data *data = dev->data;
1545 	struct dw_i3c_i2c_dev_data *dw_i3c_device_data = desc->controller_priv;
1546 	uint32_t dat;
1547 
1548 	if (dw_i3c_device_data == NULL) {
1549 		LOG_ERR("%s: %s: device not attached", dev->name, desc->dev->name);
1550 		return -EINVAL;
1551 	}
1552 	/* TODO: investigate clearing table beforehand */
1553 
1554 	LOG_DBG("Reattaching %s", desc->dev->name);
1555 
1556 	dat = sys_read32(config->regs +
1557 			 DEV_ADDR_TABLE_LOC(data->datstartaddr, dw_i3c_device_data->id));
1558 	dat &= ~DEV_ADDR_TABLE_DYNAMIC_ADDR_MASK;
1559 	sys_write32(DEV_ADDR_TABLE_DYNAMIC_ADDR(desc->dynamic_addr) | dat,
1560 		    config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, dw_i3c_device_data->id));
1561 
1562 	return 0;
1563 }
1564 
dw_i3c_detach_device(const struct device * dev,struct i3c_device_desc * desc)1565 static int dw_i3c_detach_device(const struct device *dev, struct i3c_device_desc *desc)
1566 {
1567 	const struct dw_i3c_config *config = dev->config;
1568 	struct dw_i3c_data *data = dev->data;
1569 	struct dw_i3c_i2c_dev_data *dw_i3c_device_data = desc->controller_priv;
1570 
1571 	if (dw_i3c_device_data == NULL) {
1572 		LOG_ERR("%s: %s: device not attached", dev->name, desc->dev->name);
1573 		return -EINVAL;
1574 	}
1575 
1576 	LOG_DBG("%s: Detaching %s", dev->name, desc->dev->name);
1577 
1578 	sys_write32(0,
1579 		    config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, dw_i3c_device_data->id));
1580 	data->free_pos |= BIT(dw_i3c_device_data->id);
1581 	desc->controller_priv = NULL;
1582 
1583 	return 0;
1584 }
1585 
set_controller_info(const struct device * dev)1586 static int set_controller_info(const struct device *dev)
1587 {
1588 	const struct dw_i3c_config *config = dev->config;
1589 	struct dw_i3c_data *data = dev->data;
1590 
1591 	uint8_t controller_da =
1592 		i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots, 0);
1593 	LOG_DBG("%s: 0x%02x DA selected for controller", dev->name, controller_da);
1594 
1595 	sys_write32(DEVICE_ADDR_DYNAMIC_ADDR_VALID | DEVICE_ADDR_DYNAMIC(controller_da),
1596 		    config->regs + DEVICE_ADDR);
1597 	/* Mark the address as I3C device */
1598 	i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, controller_da);
1599 
1600 	return 0;
1601 }
1602 
enable_interrupts(const struct device * dev)1603 static void enable_interrupts(const struct device *dev)
1604 {
1605 	const struct dw_i3c_config *config = dev->config;
1606 	uint32_t thld_ctrl;
1607 
1608 	config->irq_config_func();
1609 
1610 	thld_ctrl = sys_read32(config->regs + QUEUE_THLD_CTRL);
1611 	thld_ctrl &= (~QUEUE_THLD_CTRL_RESP_BUF_MASK & ~QUEUE_THLD_CTRL_IBI_STS_MASK);
1612 	sys_write32(thld_ctrl, config->regs + QUEUE_THLD_CTRL);
1613 
1614 	thld_ctrl = sys_read32(config->regs + DATA_BUFFER_THLD_CTRL);
1615 	thld_ctrl &= ~DATA_BUFFER_THLD_CTRL_RX_BUF;
1616 	sys_write32(thld_ctrl, config->regs + DATA_BUFFER_THLD_CTRL);
1617 
1618 	sys_write32(INTR_ALL, config->regs + INTR_STATUS);
1619 
1620 	sys_write32(INTR_SLAVE_MASK | INTR_MASTER_MASK, config->regs + INTR_STATUS_EN);
1621 	sys_write32(INTR_SLAVE_MASK | INTR_MASTER_MASK, config->regs + INTR_SIGNAL_EN);
1622 }
1623 
1624 /**
1625  * @brief Calculate the odd parity of a byte.
1626  *
1627  * This function calculates the odd parity of the input byte, returning 1 if the
1628  * number of set bits is odd and 0 otherwise.
1629  *
1630  * @param p The byte for which odd parity is to be calculated.
1631  *
1632  * @return The odd parity result (1 if odd, 0 if even).
1633  */
odd_parity(uint8_t p)1634 static uint8_t odd_parity(uint8_t p)
1635 {
1636 	p ^= p >> 4;
1637 	p &= 0xf;
1638 	return (0x9669 >> p) & 1;
1639 }
1640 
1641 /**
1642  * @brief Send Common Command Code (CCC).
1643  *
1644  * @see i3c_do_ccc
1645  *
1646  * @param dev Pointer to controller device driver instance.
1647  * @param payload Pointer to CCC payload.
1648  *
1649  * @return @see i3c_do_ccc
1650  */
dw_i3c_do_ccc(const struct device * dev,struct i3c_ccc_payload * payload)1651 static int dw_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *payload)
1652 {
1653 	const struct dw_i3c_config *config = dev->config;
1654 	struct dw_i3c_data *data = dev->data;
1655 	struct dw_i3c_xfer *xfer = &data->xfer;
1656 	struct dw_i3c_cmd *cmd;
1657 	int ret, i, pos;
1658 	uint32_t present_state;
1659 
1660 	present_state = sys_read32(config->regs + PRESENT_STATE);
1661 	if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) {
1662 		return -EACCES;
1663 	}
1664 
1665 	ret = k_mutex_lock(&data->mt, K_MSEC(1000));
1666 	if (ret) {
1667 		LOG_DBG("%s: Mutex err (%d)", dev->name, ret);
1668 		return ret;
1669 	}
1670 
1671 	pm_device_busy_set(dev);
1672 
1673 	memset(xfer, 0, sizeof(struct dw_i3c_xfer));
1674 	xfer->ret = -1;
1675 
1676 	/* in the case of multiple targets in a CCC, each command queue must have the same CCC ID
1677 	 * loaded along with different dev index fields pointing to the targets
1678 	 */
1679 	if (i3c_ccc_is_payload_broadcast(payload)) {
1680 		xfer->ncmds = 1;
1681 		cmd = &xfer->cmds[0];
1682 		cmd->buf = payload->ccc.data;
1683 
1684 		cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(payload->ccc.data_len) |
1685 			      COMMAND_PORT_TRANSFER_ARG;
1686 		cmd->cmd_lo = COMMAND_PORT_CP | COMMAND_PORT_TOC | COMMAND_PORT_ROC |
1687 			      COMMAND_PORT_CMD(payload->ccc.id);
1688 
1689 		if ((payload->targets.payloads) && (payload->targets.payloads[0].rnw)) {
1690 			cmd->cmd_lo |= COMMAND_PORT_READ_TRANSFER;
1691 			cmd->rx_len = payload->ccc.data_len;
1692 		} else {
1693 			cmd->tx_len = payload->ccc.data_len;
1694 		}
1695 	} else {
1696 		if (!(payload->targets.payloads)) {
1697 			LOG_ERR("%s: Direct CCC Payload structure Empty", dev->name);
1698 			ret = -EINVAL;
1699 			goto error;
1700 		}
1701 		xfer->ncmds = payload->targets.num_targets;
1702 		for (i = 0; i < payload->targets.num_targets; i++) {
1703 			cmd = &xfer->cmds[i];
1704 			/* Look up position, SETDASA will perform the look up by static addr */
1705 			pos = get_i3c_addr_pos(dev, payload->targets.payloads[i].addr,
1706 					       payload->ccc.id == I3C_CCC_SETDASA);
1707 			if (pos < 0) {
1708 				LOG_ERR("%s: Invalid Slave address with pos %d", dev->name, pos);
1709 				ret = -ENOSPC;
1710 				goto error;
1711 			}
1712 			cmd->buf = payload->targets.payloads[i].data;
1713 
1714 			cmd->cmd_hi =
1715 				COMMAND_PORT_ARG_DATA_LEN(payload->targets.payloads[i].data_len) |
1716 				COMMAND_PORT_TRANSFER_ARG;
1717 			cmd->cmd_lo = COMMAND_PORT_CP | COMMAND_PORT_DEV_INDEX(pos) |
1718 				      COMMAND_PORT_ROC | COMMAND_PORT_CMD(payload->ccc.id);
1719 			/* last command queue with multiple targets must have TOC set */
1720 			if (i == (payload->targets.num_targets - 1)) {
1721 				cmd->cmd_lo |= COMMAND_PORT_TOC;
1722 			}
1723 			/* If there is a defining byte for direct CCC */
1724 			if (payload->ccc.data_len == 1) {
1725 				cmd->cmd_lo |= COMMAND_PORT_DBP;
1726 				cmd->cmd_hi |= COMMAND_PORT_ARG_DB(payload->ccc.data[0]);
1727 			} else if (payload->ccc.data_len > 1) {
1728 				LOG_ERR("%s: direct CCCs defining byte >1", dev->name);
1729 				ret = -EINVAL;
1730 				goto error;
1731 			}
1732 
1733 			if (payload->targets.payloads[i].rnw) {
1734 				cmd->cmd_lo |= COMMAND_PORT_READ_TRANSFER;
1735 				cmd->rx_len = payload->targets.payloads[i].data_len;
1736 			} else {
1737 				cmd->tx_len = payload->targets.payloads[i].data_len;
1738 			}
1739 		}
1740 	}
1741 
1742 	start_xfer(dev);
1743 
1744 	ret = k_sem_take(&data->sem_xfer, K_MSEC(CONFIG_I3C_DW_RW_TIMEOUT_MS));
1745 	if (ret) {
1746 		LOG_ERR("%s: Semaphore err (%d)", dev->name, ret);
1747 		goto error;
1748 	}
1749 
1750 	/* the only way data_len would not equal num_xfer would be if an abort happened */
1751 	payload->ccc.num_xfer = payload->ccc.data_len;
1752 	for (i = 0; i < xfer->ncmds; i++) {
1753 		/* if this is a direct ccc, then write back the number of bytes tx or rx */
1754 		if (!i3c_ccc_is_payload_broadcast(payload)) {
1755 			payload->targets.payloads[i].num_xfer = payload->targets.payloads[i].rnw
1756 									? xfer->cmds[i].rx_len
1757 									: xfer->cmds[i].tx_len;
1758 		}
1759 		if (xfer->cmds[i].rx_len && !xfer->cmds[i].error) {
1760 			read_rx_fifo(dev, xfer->cmds[i].buf, xfer->cmds[i].rx_len);
1761 		}
1762 	}
1763 
1764 	ret = xfer->ret;
1765 error:
1766 	pm_device_busy_clear(dev);
1767 	k_mutex_unlock(&data->mt);
1768 
1769 	return ret;
1770 }
1771 
1772 /**
1773  * @brief Add a slave device from Dynamic Address Assignment (DAA) information.
1774  *
1775  * This function adds a slave device to the I3C controller based on the Dynamic
1776  * Address Assignment (DAA) information at the specified position. It retrieves
1777  * the dynamic address, PID (Provisional ID), and additional device characteristics
1778  * from the corresponding tables and associates the device with a registered device
1779  * descriptor if the PID is known.
1780  *
1781  * @param dev Pointer to the I3C device structure.
1782  * @param pos Position of the device in the DAA and DCT tables.
1783  *
1784  * @return 0 on success, or a negative error code on failure.
1785  */
add_slave_from_daa(const struct device * dev,int32_t pos)1786 static int add_slave_from_daa(const struct device *dev, int32_t pos)
1787 {
1788 	const struct dw_i3c_config *config = dev->config;
1789 	struct dw_i3c_data *data = dev->data;
1790 	uint32_t tmp;
1791 	uint64_t pid;
1792 	uint8_t dyn_addr;
1793 
1794 	/* retrieve dynamic address assigned */
1795 	tmp = sys_read32(config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos));
1796 	dyn_addr = (((tmp) & GENMASK(22, 16)) >> 16);
1797 
1798 	/* retrieve pid */
1799 	tmp = sys_read32(config->regs + DEV_CHAR_TABLE_LOC1(data->dctstartaddr, pos));
1800 	pid = ((uint64_t)DEV_CHAR_TABLE_MSB_PID(tmp) << 16) + (DEV_CHAR_TABLE_LSB_PID(tmp) << 16);
1801 	tmp = sys_read32(config->regs + DEV_CHAR_TABLE_LOC2(data->dctstartaddr, pos));
1802 	pid |= DEV_CHAR_TABLE_LSB_PID(tmp);
1803 
1804 	/* lookup known pids */
1805 	const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid);
1806 	struct i3c_device_desc *target = i3c_device_find(dev, &i3c_id);
1807 
1808 	if (target == NULL) {
1809 		LOG_INF("%s: PID 0x%012llx is not in registered device "
1810 			"list, given DA 0x%02x",
1811 			dev->name, pid, dyn_addr);
1812 	} else {
1813 		target->dynamic_addr = dyn_addr;
1814 		tmp = sys_read32(config->regs + DEV_CHAR_TABLE_LOC3(data->dctstartaddr, pos));
1815 		target->bcr = DEV_CHAR_TABLE_BCR(tmp);
1816 		target->dcr = DEV_CHAR_TABLE_DCR(tmp);
1817 
1818 		LOG_DBG("%s: PID 0x%012llx assigned dynamic address 0x%02x", dev->name, pid,
1819 			dyn_addr);
1820 	}
1821 	i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, dyn_addr);
1822 
1823 	return 0;
1824 }
1825 
1826 /**
1827  * @brief Perform Dynamic Address Assignment.
1828  *
1829  * @see i3c_do_daa
1830  *
1831  * @param dev Pointer to controller device driver instance.
1832  *
1833  * @return @see i3c_do_daa
1834  */
dw_i3c_do_daa(const struct device * dev)1835 static int dw_i3c_do_daa(const struct device *dev)
1836 {
1837 	const struct dw_i3c_config *config = dev->config;
1838 	struct dw_i3c_data *data = dev->data;
1839 	struct dw_i3c_xfer *xfer = &data->xfer;
1840 	struct dw_i3c_cmd *cmd;
1841 	uint32_t olddevs, newdevs;
1842 	uint8_t p, idx, last_addr = 0;
1843 	int32_t pos, addr, ret;
1844 	uint32_t present_state;
1845 
1846 	present_state = sys_read32(config->regs + PRESENT_STATE);
1847 	if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) {
1848 		return -EACCES;
1849 	}
1850 
1851 	olddevs = ~(data->free_pos);
1852 
1853 	/* Prepare DAT before launching DAA. */
1854 	for (pos = 0; pos < data->maxdevs; pos++) {
1855 		if (olddevs & BIT(pos)) {
1856 			continue;
1857 		}
1858 
1859 		addr = i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots,
1860 						     last_addr + 1);
1861 		if (addr == 0) {
1862 			return -ENOSPC;
1863 		}
1864 
1865 		p = odd_parity(addr);
1866 		last_addr = addr;
1867 		addr |= (p << 7);
1868 		sys_write32(DEV_ADDR_TABLE_DYNAMIC_ADDR(addr),
1869 			    config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos));
1870 	}
1871 
1872 	pos = get_free_pos(data->free_pos);
1873 	if (pos < 0) {
1874 		LOG_ERR("%s: find free pos failed", dev->name);
1875 		return -ENOSPC;
1876 	}
1877 
1878 	ret = k_mutex_lock(&data->mt, K_MSEC(1000));
1879 	if (ret) {
1880 		LOG_ERR("%s: Mutex err (%d)", dev->name, ret);
1881 		return ret;
1882 	}
1883 
1884 	pm_device_busy_set(dev);
1885 
1886 	memset(xfer, 0, sizeof(struct dw_i3c_xfer));
1887 
1888 	xfer->ncmds = 1;
1889 	xfer->ret = -1;
1890 
1891 	cmd = &xfer->cmds[0];
1892 	cmd->cmd_hi = COMMAND_PORT_TRANSFER_ARG;
1893 	cmd->cmd_lo = COMMAND_PORT_TOC | COMMAND_PORT_ROC |
1894 		      COMMAND_PORT_DEV_COUNT(data->maxdevs - pos) | COMMAND_PORT_DEV_INDEX(pos) |
1895 		      COMMAND_PORT_CMD(I3C_CCC_ENTDAA) | COMMAND_PORT_ADDR_ASSGN_CMD;
1896 
1897 	start_xfer(dev);
1898 	ret = k_sem_take(&data->sem_xfer, K_MSEC(CONFIG_I3C_DW_RW_TIMEOUT_MS));
1899 
1900 	pm_device_busy_clear(dev);
1901 	k_mutex_unlock(&data->mt);
1902 
1903 	if (ret) {
1904 		LOG_ERR("%s: Semaphore err (%d)", dev->name, ret);
1905 		return ret;
1906 	}
1907 
1908 	if (data->maxdevs == cmd->rx_len) {
1909 		newdevs = 0;
1910 	} else {
1911 		newdevs = GENMASK(data->maxdevs - cmd->rx_len - 1, 0);
1912 	}
1913 	newdevs &= ~olddevs;
1914 
1915 	for (pos = find_lsb_set(newdevs); pos <= find_msb_set(newdevs); pos++) {
1916 		idx = pos - 1;
1917 		if (newdevs & BIT(idx)) {
1918 			add_slave_from_daa(dev, idx);
1919 		}
1920 	}
1921 
1922 	return 0;
1923 }
1924 
dw_i3c_enable_controller(const struct dw_i3c_config * config,bool enable)1925 static void dw_i3c_enable_controller(const struct dw_i3c_config *config, bool enable)
1926 {
1927 	uint32_t reg = sys_read32(config->regs + DEVICE_CTRL);
1928 
1929 	if (enable) {
1930 		reg |= DEV_CTRL_ENABLE;
1931 	} else {
1932 		reg &= ~DEV_CTRL_ENABLE;
1933 	}
1934 
1935 	sys_write32(reg, config->regs + DEVICE_CTRL);
1936 }
1937 
1938 /**
1939  * @brief Get configuration of the I3C hardware.
1940  *
1941  * This provides a way to get the current configuration of the I3C hardware.
1942  *
1943  * This can return cached config or probed hardware parameters, but it has to
1944  * be up to date with current configuration.
1945  *
1946  * @param[in] dev Pointer to controller device driver instance.
1947  * @param[in] type Type of configuration parameters being passed
1948  *                 in @p config.
1949  * @param[in,out] config Pointer to the configuration parameters.
1950  *
1951  * Note that if @p type is @c I3C_CONFIG_CUSTOM, @p config must contain
1952  * the ID of the parameter to be retrieved.
1953  *
1954  * @retval 0 If successful.
1955  * @retval -EIO General Input/Output errors.
1956  * @retval -ENOSYS If not implemented.
1957  */
dw_i3c_config_get(const struct device * dev,enum i3c_config_type type,void * config)1958 static int dw_i3c_config_get(const struct device *dev, enum i3c_config_type type, void *config)
1959 {
1960 	const struct dw_i3c_config *dev_config = dev->config;
1961 	struct dw_i3c_data *data = dev->data;
1962 	int ret = 0;
1963 
1964 	if (type == I3C_CONFIG_CONTROLLER) {
1965 		(void)memcpy(config, &data->common.ctrl_config, sizeof(data->common.ctrl_config));
1966 	} else if (type == I3C_CONFIG_TARGET) {
1967 		struct i3c_config_target *target_config = config;
1968 		uint32_t reg;
1969 
1970 		reg = sys_read32(dev_config->regs + SLV_MAX_LEN);
1971 		target_config->max_read_len = SLV_MAX_LEN_MRL(reg);
1972 		target_config->max_write_len = SLV_MAX_LEN_MWL(reg);
1973 
1974 		reg = sys_read32(dev_config->regs + DEVICE_ADDR);
1975 		if (reg & DEVICE_ADDR_STATIC_ADDR_VALID) {
1976 			target_config->static_addr = DEVICE_ADDR_STATIC(reg);
1977 		} else {
1978 			target_config->static_addr = 0x00;
1979 		}
1980 
1981 		reg = sys_read32(dev_config->regs + SLV_CHAR_CTRL);
1982 		target_config->bcr = SLV_CHAR_CTRL_BCR(reg);
1983 		target_config->dcr = SLV_CHAR_CTRL_DCR(reg);
1984 		target_config->supported_hdr = SLV_CHAR_CTRL_HDR_CAP(reg);
1985 
1986 		reg = sys_read32(dev_config->regs + SLV_MIPI_ID_VALUE);
1987 		target_config->pid = ((uint64_t)reg) << 32;
1988 		target_config->pid_random = (bool)!!(reg & SLV_MIPI_ID_VALUE_SLV_PROV_ID_SEL);
1989 		reg = sys_read32(dev_config->regs + SLV_PID_VALUE);
1990 		target_config->pid |= reg;
1991 
1992 		if (!(sys_read32(dev_config->regs + PRESENT_STATE) &
1993 		      PRESENT_STATE_CURRENT_MASTER)) {
1994 			target_config->enabled = true;
1995 		} else {
1996 			target_config->enabled = false;
1997 		}
1998 	} else {
1999 		return -EINVAL;
2000 	}
2001 
2002 	return ret;
2003 }
2004 
2005 /**
2006  * @brief Configure I3C hardware.
2007  *
2008  * @param dev Pointer to controller device driver instance.
2009  * @param type Type of configuration parameters being passed
2010  *             in @p config.
2011  * @param config Pointer to the configuration parameters.
2012  *
2013  * @retval 0 If successful.
2014  * @retval -EINVAL If invalid configure parameters.
2015  * @retval -EIO General Input/Output errors.
2016  * @retval -ENOSYS If not implemented.
2017  */
dw_i3c_configure(const struct device * dev,enum i3c_config_type type,void * config)2018 static int dw_i3c_configure(const struct device *dev, enum i3c_config_type type, void *config)
2019 {
2020 	const struct dw_i3c_config *dev_config = dev->config;
2021 
2022 	if (type == I3C_CONFIG_CONTROLLER) {
2023 		/* struct i3c_config_controller *ctrl_cfg = config; */
2024 		/* TODO: somehow determine i3c rate? snps is complicated */
2025 		return -ENOTSUP;
2026 	} else if (type == I3C_CONFIG_TARGET) {
2027 		struct i3c_config_target *target_cfg = config;
2028 		uint32_t val;
2029 
2030 		/* TODO: some how randomly generate pid */
2031 		if (target_cfg->pid_random) {
2032 			return -EINVAL;
2033 		}
2034 
2035 		val = SLV_MAX_LEN_MWL(target_cfg->max_write_len) |
2036 		      (SLV_MAX_LEN_MRL(target_cfg->max_read_len) << 16);
2037 		sys_write32(val, dev_config->regs + SLV_MAX_LEN);
2038 
2039 		/* set static address */
2040 		val = sys_read32(dev_config->regs + DEVICE_ADDR);
2041 		/* if static address is set to 0x00, then disable static_addr_en */
2042 		if (target_cfg->static_addr != 0x00) {
2043 			val |= DEVICE_ADDR_STATIC_ADDR_VALID;
2044 		} else {
2045 			val &= ~DEVICE_ADDR_STATIC_ADDR_VALID;
2046 		}
2047 		val &= ~DEVICE_ADDR_STATIC_MASK;
2048 		val |= DEVICE_ADDR_STATIC(target_cfg->static_addr);
2049 		sys_write32(val, dev_config->regs + DEVICE_ADDR);
2050 
2051 		val = sys_read32(dev_config->regs + SLV_CHAR_CTRL);
2052 		val &= ~(SLV_CHAR_CTRL_BCR_MASK | SLV_CHAR_CTRL_DCR_MASK);
2053 		/* Bridge identifier, offline capable, ibi_payload, ibi_request_capable can not be
2054 		 * written to in bcr
2055 		 */
2056 		val |= SLV_CHAR_CTRL_BCR(target_cfg->bcr);
2057 		val |= SLV_CHAR_CTRL_DCR(target_cfg->dcr) << 8;
2058 		/* HDR CAPs is not settable */
2059 		sys_write32(val, dev_config->regs + SLV_CHAR_CTRL);
2060 
2061 		val = sys_read32(dev_config->regs + SLV_MIPI_ID_VALUE);
2062 		val &= ~(SLV_MIPI_ID_VALUE_SLV_MIPI_MFG_ID_MASK |
2063 			 SLV_MIPI_ID_VALUE_SLV_PROV_ID_SEL);
2064 		val |= (uint32_t)(target_cfg->pid >> 16);
2065 		sys_write32(val, dev_config->regs + SLV_MIPI_ID_VALUE);
2066 
2067 		val = (uint32_t)(target_cfg->pid & 0xFFFFFFFF);
2068 		sys_write32(val, dev_config->regs + SLV_PID_VALUE);
2069 	}
2070 
2071 	return 0;
2072 }
2073 
2074 /**
2075  * @brief Find a registered I3C target device.
2076  *
2077  * This returns the I3C device descriptor of the I3C device
2078  * matching the incoming @p id.
2079  *
2080  * @param dev Pointer to controller device driver instance.
2081  * @param id Pointer to I3C device ID.
2082  *
2083  * @return @see i3c_device_find.
2084  */
dw_i3c_device_find(const struct device * dev,const struct i3c_device_id * id)2085 static struct i3c_device_desc *dw_i3c_device_find(const struct device *dev,
2086 						  const struct i3c_device_id *id)
2087 {
2088 	const struct dw_i3c_config *config = dev->config;
2089 
2090 	return i3c_dev_list_find(&config->common.dev_list, id);
2091 }
2092 
2093 /**
2094  * @brief Writes to the Target's TX FIFO
2095  *
2096  * The Synopsys I3C will then ACK read requests to it's TX FIFO from a
2097  * Controller, if there is no tx cmd in cmd Q. Then it will NACK.
2098  *
2099  * @param dev Pointer to the device structure for an I3C controller
2100  *            driver configured in target mode.
2101  * @param buf Pointer to the buffer
2102  * @param len Length of the buffer
2103  *
2104  * @retval Total number of bytes written
2105  * @retval -EACCES Not in Target Mode
2106  * @retval -ENOSPC No space in Tx FIFO
2107  */
dw_i3c_target_tx_write(const struct device * dev,uint8_t * buf,uint16_t len,uint8_t hdr_mode)2108 static int dw_i3c_target_tx_write(const struct device *dev, uint8_t *buf, uint16_t len,
2109 				  uint8_t hdr_mode)
2110 {
2111 	const struct dw_i3c_config *config = dev->config;
2112 	struct dw_i3c_data *data = dev->data;
2113 	struct dw_i3c_xfer *xfer = &data->xfer;
2114 	uint32_t present_state;
2115 
2116 	/* check if we are in target mode */
2117 	present_state = sys_read32(config->regs + PRESENT_STATE);
2118 	if (present_state & PRESENT_STATE_CURRENT_MASTER) {
2119 		return -EACCES;
2120 	}
2121 
2122 	/*
2123 	 * TODO: if len is greater than fifo size, then it will need to be written to based
2124 	 * on the threshold interrupt
2125 	 */
2126 	if (len > (data->txfifodepth * BYTES_PER_DWORD)) {
2127 		return -ENOSPC;
2128 	}
2129 
2130 	k_mutex_lock(&data->mt, K_FOREVER);
2131 
2132 	if ((hdr_mode == 0) || (hdr_mode & data->common.ctrl_config.supported_hdr)) {
2133 		/* Write to CMD */
2134 		memset(xfer, 0, sizeof(struct dw_i3c_xfer));
2135 		xfer->ncmds = 1;
2136 
2137 		/* TODO: write_tx_fifo needs to check that the fifo doesn't fill up */
2138 		struct dw_i3c_cmd *cmd = &xfer->cmds[0];
2139 
2140 		cmd->cmd_hi = 0;
2141 		cmd->cmd_lo = COMMAND_PORT_TID(0) | COMMAND_PORT_ARG_DATA_LEN(len);
2142 		cmd->buf = buf;
2143 		cmd->tx_len = len;
2144 
2145 		start_xfer(dev);
2146 	} else {
2147 		k_mutex_unlock(&data->mt);
2148 		LOG_ERR("%s: Unsupported HDR Mode %d", dev->name, hdr_mode);
2149 		return -ENOTSUP;
2150 	}
2151 
2152 	k_mutex_unlock(&data->mt);
2153 
2154 	/* return total bytes written */
2155 	return (int)len;
2156 }
2157 
2158 /**
2159  * @brief Instructs the I3C Target device to register itself to the I3C Controller
2160  *
2161  * This routine instructs the I3C Target device to register itself to the I3C
2162  * Controller via its parent controller's i3c_target_register() API.
2163  *
2164  * @param dev Pointer to target device driver instance.
2165  * @param cfg Config struct with functions and parameters used by the I3C driver
2166  * to send bus events
2167  *
2168  * @return @see i3c_device_find.
2169  */
dw_i3c_target_register(const struct device * dev,struct i3c_target_config * cfg)2170 static int dw_i3c_target_register(const struct device *dev, struct i3c_target_config *cfg)
2171 {
2172 	struct dw_i3c_data *data = dev->data;
2173 
2174 	data->target_config = cfg;
2175 	return 0;
2176 }
2177 
2178 /**
2179  * @brief Unregisters the provided config as Target device
2180  *
2181  * This routine disables I3C target mode for the 'dev' I3C bus driver using
2182  * the provided 'config' struct containing the functions and parameters
2183  * to send bus events.
2184  *
2185  * @param dev Pointer to target device driver instance.
2186  * @param cfg Config struct with functions and parameters used by the I3C driver
2187  * to send bus events
2188  *
2189  * @return @see i3c_device_find.
2190  */
dw_i3c_target_unregister(const struct device * dev,struct i3c_target_config * cfg)2191 static int dw_i3c_target_unregister(const struct device *dev, struct i3c_target_config *cfg)
2192 {
2193 	/* no way to disable? maybe write DA to 0? */
2194 	return 0;
2195 }
2196 
dw_i3c_pinctrl_enable(const struct device * dev,bool enable)2197 static int dw_i3c_pinctrl_enable(const struct device *dev, bool enable)
2198 {
2199 #ifdef CONFIG_PINCTRL
2200 	const struct dw_i3c_config *config = dev->config;
2201 	uint8_t state = enable ? PINCTRL_STATE_DEFAULT : PINCTRL_STATE_SLEEP;
2202 	int ret;
2203 
2204 	ret = pinctrl_apply_state(config->pcfg, state);
2205 	if (ret == -ENOENT) {
2206 		/* State not defined; ignore and return success. */
2207 		ret = 0;
2208 	}
2209 
2210 	return ret;
2211 #else
2212 	ARG_UNUSED(dev);
2213 	ARG_UNUSED(enable);
2214 	return 0;
2215 #endif
2216 }
2217 
dw_i3c_init(const struct device * dev)2218 static int dw_i3c_init(const struct device *dev)
2219 {
2220 	const struct dw_i3c_config *config = dev->config;
2221 	struct dw_i3c_data *data = dev->data;
2222 	struct i3c_config_controller *ctrl_config = &data->common.ctrl_config;
2223 	int ret;
2224 	uint32_t hw_capabilities;
2225 	uint32_t queue_capability;
2226 	uint32_t device_ctrl_ext;
2227 
2228 	if (!device_is_ready(config->clock)) {
2229 		return -ENODEV;
2230 	}
2231 
2232 	ret = clock_control_on(config->clock, NULL);
2233 	if (ret < 0) {
2234 		return ret;
2235 	}
2236 
2237 #ifdef CONFIG_I3C_USE_IBI
2238 	k_sem_init(&data->ibi_sts_sem, 0, 1);
2239 #endif
2240 	k_sem_init(&data->sem_xfer, 0, 1);
2241 	k_mutex_init(&data->mt);
2242 
2243 	dw_i3c_pinctrl_enable(dev, true);
2244 
2245 	data->mode = i3c_bus_mode(&config->common.dev_list);
2246 
2247 	/* reset all */
2248 	sys_write32(RESET_CTRL_ALL, config->regs + RESET_CTRL);
2249 
2250 	/* get DAT, DCT pointer */
2251 	data->datstartaddr =
2252 		DEVICE_ADDR_TABLE_ADDR(sys_read32(config->regs + DEVICE_ADDR_TABLE_POINTER));
2253 	data->dctstartaddr =
2254 		DEVICE_CHAR_TABLE_ADDR(sys_read32(config->regs + DEV_CHAR_TABLE_POINTER));
2255 
2256 	/* get max devices based on table depth */
2257 	data->maxdevs =
2258 		DEVICE_ADDR_TABLE_DEPTH(sys_read32(config->regs + DEVICE_ADDR_TABLE_POINTER));
2259 	data->free_pos = GENMASK(data->maxdevs - 1, 0);
2260 
2261 	/* get fifo sizes */
2262 	queue_capability = sys_read32(config->regs + QUEUE_SIZE_CAPABILITY);
2263 	data->txfifodepth = QUEUE_SIZE_CAPABILITY_TX_BUF_DWORD_SIZE(queue_capability);
2264 	data->rxfifodepth = QUEUE_SIZE_CAPABILITY_RX_BUF_DWORD_SIZE(queue_capability);
2265 	data->cmdfifodepth = QUEUE_SIZE_CAPABILITY_CMD_BUF_DWORD_SIZE(queue_capability);
2266 	data->respfifodepth = QUEUE_SIZE_CAPABILITY_RESP_BUF_DWORD_SIZE(queue_capability);
2267 	data->ibififodepth = QUEUE_SIZE_CAPABILITY_IBI_BUF_DWORD_SIZE(queue_capability);
2268 
2269 	/* get HDR capabilities */
2270 	ctrl_config->supported_hdr = 0;
2271 	hw_capabilities = sys_read32(config->regs + HW_CAPABILITY);
2272 	if (hw_capabilities & HW_CAPABILITY_HDR_TS_EN) {
2273 		ctrl_config->supported_hdr |= I3C_MSG_HDR_TSP | I3C_MSG_HDR_TSL;
2274 	}
2275 	if (hw_capabilities & HW_CAPABILITY_HDR_DDR_EN) {
2276 		ctrl_config->supported_hdr |= I3C_MSG_HDR_DDR;
2277 	}
2278 
2279 	/* if the boot condition starts as a target, then it's a secondary controller */
2280 	device_ctrl_ext = sys_read32(config->regs + DEVICE_CTRL_EXTENDED);
2281 	if (DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE(device_ctrl_ext) &
2282 	    DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE_SLAVE) {
2283 		ctrl_config->is_secondary = true;
2284 	} else {
2285 		ctrl_config->is_secondary = false;
2286 	}
2287 
2288 	ret = init_scl_timing(dev);
2289 	if (ret != 0) {
2290 		return ret;
2291 	}
2292 
2293 	enable_interrupts(dev);
2294 
2295 	/* disable ibi */
2296 	sys_write32(IBI_REQ_REJECT_ALL, config->regs + IBI_SIR_REQ_REJECT);
2297 	sys_write32(IBI_REQ_REJECT_ALL, config->regs + IBI_MR_REQ_REJECT);
2298 
2299 	/* disable hot-join */
2300 	sys_write32(sys_read32(config->regs + DEVICE_CTRL) | (DEV_CTRL_HOT_JOIN_NACK),
2301 		    config->regs + DEVICE_CTRL);
2302 
2303 	ret = i3c_addr_slots_init(dev);
2304 	if (ret != 0) {
2305 		return ret;
2306 	}
2307 
2308 	dw_i3c_enable_controller(config, true);
2309 
2310 	if (!(ctrl_config->is_secondary)) {
2311 		ret = set_controller_info(dev);
2312 		if (ret) {
2313 			return ret;
2314 		}
2315 		/* Perform bus initialization - skip if no I3C devices are known. */
2316 		if (config->common.dev_list.num_i3c > 0) {
2317 			ret = i3c_bus_init(dev, &config->common.dev_list);
2318 		}
2319 		/* Bus Initialization Complete, allow HJ ACKs */
2320 		sys_write32(sys_read32(config->regs + DEVICE_CTRL) & ~(DEV_CTRL_HOT_JOIN_NACK),
2321 			    config->regs + DEVICE_CTRL);
2322 	}
2323 
2324 	return 0;
2325 }
2326 
2327 #if defined(CONFIG_PM_DEVICE)
dw_i3c_pm_ctrl(const struct device * dev,enum pm_device_action action)2328 static int dw_i3c_pm_ctrl(const struct device *dev, enum pm_device_action action)
2329 {
2330 	const struct dw_i3c_config *config = dev->config;
2331 
2332 	LOG_DBG("PM action: %d", (int)action);
2333 
2334 	switch (action) {
2335 	case PM_DEVICE_ACTION_SUSPEND:
2336 		dw_i3c_enable_controller(config, false);
2337 		dw_i3c_pinctrl_enable(dev, false);
2338 		break;
2339 
2340 	case PM_DEVICE_ACTION_RESUME:
2341 		dw_i3c_pinctrl_enable(dev, true);
2342 		dw_i3c_enable_controller(config, true);
2343 		break;
2344 
2345 	default:
2346 		return -ENOTSUP;
2347 	}
2348 
2349 	return 0;
2350 }
2351 #endif
2352 
2353 static DEVICE_API(i3c, dw_i3c_api) = {
2354 	.i2c_api.transfer = dw_i3c_i2c_api_transfer,
2355 
2356 	.configure = dw_i3c_configure,
2357 	.config_get = dw_i3c_config_get,
2358 
2359 	.attach_i3c_device = dw_i3c_attach_device,
2360 	.reattach_i3c_device = dw_i3c_reattach_device,
2361 	.detach_i3c_device = dw_i3c_detach_device,
2362 
2363 	.do_daa = dw_i3c_do_daa,
2364 	.do_ccc = dw_i3c_do_ccc,
2365 
2366 	.i3c_device_find = dw_i3c_device_find,
2367 
2368 	.i3c_xfers = dw_i3c_xfers,
2369 
2370 	.target_tx_write = dw_i3c_target_tx_write,
2371 	.target_register = dw_i3c_target_register,
2372 	.target_unregister = dw_i3c_target_unregister,
2373 
2374 #ifdef CONFIG_I3C_USE_IBI
2375 	.ibi_hj_response = dw_i3c_controller_ibi_hj_response,
2376 	.ibi_enable = dw_i3c_controller_enable_ibi,
2377 	.ibi_disable = dw_i3c_controller_disable_ibi,
2378 	.ibi_raise = dw_i3c_target_ibi_raise,
2379 #endif /* CONFIG_I3C_USE_IBI */
2380 };
2381 
2382 #define I3C_DW_IRQ_HANDLER(n)                                                                      \
2383 	static void i3c_dw_irq_config_##n(void)                                                    \
2384 	{                                                                                          \
2385 		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), i3c_dw_irq,                 \
2386 			    DEVICE_DT_INST_GET(n), 0);                                             \
2387 		irq_enable(DT_INST_IRQN(n));                                                       \
2388 	}
2389 
2390 #if defined(CONFIG_PINCTRL)
2391 #define I3C_DW_PINCTRL_DEFINE(n) PINCTRL_DT_INST_DEFINE(n)
2392 #define I3C_DW_PINCTRL_INIT(n)   .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),
2393 #else
2394 #define I3C_DW_PINCTRL_DEFINE(n)
2395 #define I3C_DW_PINCTRL_INIT(n)
2396 #endif
2397 
2398 #define DEFINE_DEVICE_FN(n)                                                                        \
2399 	I3C_DW_IRQ_HANDLER(n)                                                                      \
2400 	I3C_DW_PINCTRL_DEFINE(n);                                                                  \
2401 	static struct i3c_device_desc dw_i3c_device_array_##n[] = I3C_DEVICE_ARRAY_DT_INST(n);     \
2402 	static struct i3c_i2c_device_desc dw_i3c_i2c_device_array_##n[] =                          \
2403 		I3C_I2C_DEVICE_ARRAY_DT_INST(n);                                                   \
2404 	static struct dw_i3c_data dw_i3c_data_##n = {                                              \
2405 		.common.ctrl_config.scl.i3c =                                                      \
2406 			DT_INST_PROP_OR(n, i3c_scl_hz, I3C_BUS_TYP_I3C_SCL_RATE),                  \
2407 		.common.ctrl_config.scl.i2c = DT_INST_PROP_OR(n, i2c_scl_hz, 0),                   \
2408 	};                                                                                         \
2409 	static const struct dw_i3c_config dw_i3c_cfg_##n = {                                       \
2410 		.regs = DT_INST_REG_ADDR(n),                                                       \
2411 		.clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)),                                    \
2412 		.od_thigh_max_ns = DT_INST_PROP(n, od_thigh_max_ns),                               \
2413 		.od_tlow_min_ns = DT_INST_PROP(n, od_tlow_min_ns),                                 \
2414 		.irq_config_func = &i3c_dw_irq_config_##n,                                         \
2415 		.common.dev_list.i3c = dw_i3c_device_array_##n,                                    \
2416 		.common.dev_list.num_i3c = ARRAY_SIZE(dw_i3c_device_array_##n),                    \
2417 		.common.dev_list.i2c = dw_i3c_i2c_device_array_##n,                                \
2418 		.common.dev_list.num_i2c = ARRAY_SIZE(dw_i3c_i2c_device_array_##n),                \
2419 		I3C_DW_PINCTRL_INIT(n)};                                                           \
2420 	PM_DEVICE_DT_INST_DEFINE(n, dw_i3c_pm_action);                                             \
2421 	DEVICE_DT_INST_DEFINE(n, dw_i3c_init, PM_DEVICE_DT_INST_GET(n), &dw_i3c_data_##n,          \
2422 			      &dw_i3c_cfg_##n, POST_KERNEL, CONFIG_I3C_CONTROLLER_INIT_PRIORITY,   \
2423 			      &dw_i3c_api);
2424 
2425 #define DT_DRV_COMPAT snps_designware_i3c
2426 DT_INST_FOREACH_STATUS_OKAY(DEFINE_DEVICE_FN);
2427