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