1 /*
2 * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stddef.h>
7 #include <stdint.h>
8
9 #include "mec_pcfg.h"
10 #include "mec_defs.h"
11 #include <device_mec5.h>
12
13 #include "mec_ecia_api.h"
14 #include "mec_pcr_api.h"
15 #include "mec_retval.h"
16 #include "mec_i3c_pvt.h"
17
18 #include "mec_i3c_api.h"
19
20 static uint8_t tid = 0;
21 static uint32_t targets_ibi_enable_sts = 0;
22
23 #define MEC_I3C_HOST0_ECIA_INFO MEC5_ECIA_INFO(13, 8, 5, MEC_I3C_HOST0_IRQn)
24 #define MEC_I3C_SEC_HOST0_ECIA_INFO MEC5_ECIA_INFO(13, 9, 5, MEC_I3C_SEC0_IRQn)
25
26 struct mec_i3c_info {
27 uintptr_t base_addr;
28 uint32_t devi;
29 uint16_t pcr_id;
30 };
31
32 static const struct mec_i3c_info i3c_instances[MEC5_I3C_CTRL_INSTANCES] = {
33 {MEC_I3C_SEC0_BASE, MEC_I3C_SEC_HOST0_ECIA_INFO, MEC_PCR_I3C_SEC },
34 {MEC_I3C_HOST0_BASE, MEC_I3C_HOST0_ECIA_INFO, MEC_PCR_I3C_HOST },
35 };
36
get_i3c_info(uintptr_t base)37 static struct mec_i3c_info const *get_i3c_info(uintptr_t base)
38 {
39 for (int i = 0; i < MEC5_I3C_CTRL_INSTANCES; i++) {
40 const struct mec_i3c_info *p = &i3c_instances[i];
41
42 if (p->base_addr == base) {
43 return p;
44 }
45 }
46
47 return NULL;
48 }
49
50
51 /**
52 * @brief Intiialize timing for i2c transfers
53 *
54 * @param regs Pointer to controller registers
55 */
MEC_HAL_I3C_Controller_Clk_I2C_Init(struct mec_i3c_ctx * ctx,uint32_t core_clk_rate_mhz)56 void MEC_HAL_I3C_Controller_Clk_I2C_Init(struct mec_i3c_ctx *ctx, uint32_t core_clk_rate_mhz)
57 {
58 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
59 uint32_t core_clk_freq_ns;
60
61 const struct mec_i3c_info *info = get_i3c_info(ctx->base);
62
63 if (info) {
64
65 ctx->devi = info->devi;
66
67 mec_hal_pcr_clr_blk_slp_en(info->pcr_id);
68 mec_hal_pcr_blk_reset(info->pcr_id);
69
70 core_clk_freq_ns = MEC_DIV_ROUND_UP(1000000000, core_clk_rate_mhz);
71
72 _i2c_fmp_timing_set(regs, core_clk_freq_ns);
73
74 _i2c_fm_timing_set(regs, core_clk_freq_ns);
75
76 _i2c_target_present_set(regs);
77 }
78 }
79
80 /**
81 * @brief Initialize timing for i3c transfers
82 *
83 * @param ctx Context structure containing Pointer to controller registers
84 * @param core_clk_rate_mhz Core Clock speed
85 * @param i3c_freq I3C Frequency
86 */
MEC_HAL_I3C_Controller_Clk_Init(struct mec_i3c_ctx * ctx,uint32_t core_clk_rate_mhz,uint32_t i3c_freq)87 void MEC_HAL_I3C_Controller_Clk_Init(struct mec_i3c_ctx *ctx, uint32_t core_clk_rate_mhz,
88 uint32_t i3c_freq)
89 {
90 const struct mec_i3c_info *info = get_i3c_info(ctx->base);
91
92 if (info) {
93
94 ctx->devi = info->devi;
95
96 mec_hal_pcr_clr_blk_slp_en(info->pcr_id);
97 mec_hal_pcr_blk_reset(info->pcr_id);
98
99 MEC_HAL_I3C_Controller_Clk_Cfg(ctx, core_clk_rate_mhz, i3c_freq);
100 }
101 }
102
103 /**
104 * @brief configure timing for i3c transfers
105 *
106 * @param ctx Context structure containing Pointer to controller registers
107 * @param core_clk_rate_mhz Core Clock speed
108 * @param i3c_freq I3C Frequency
109 */
MEC_HAL_I3C_Controller_Clk_Cfg(struct mec_i3c_ctx * ctx,uint32_t core_clk_rate_mhz,uint32_t i3c_freq)110 void MEC_HAL_I3C_Controller_Clk_Cfg(struct mec_i3c_ctx *ctx, uint32_t core_clk_rate_mhz,
111 uint32_t i3c_freq)
112 {
113 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
114 uint32_t core_clk_freq_ns, i3c_freq_ns;
115
116 core_clk_freq_ns = MEC_DIV_ROUND_UP(1000000000, core_clk_rate_mhz);
117
118 i3c_freq_ns = MEC_DIV_ROUND_UP(1000000000, i3c_freq);
119
120 /* Program the I3C Push Pull Timing Register */
121 _i3c_push_pull_timing_set(regs, core_clk_freq_ns, i3c_freq_ns);
122
123 /* Program the I3C Open Drain Timing Register */
124 _i3c_open_drain_timing_set(regs, core_clk_freq_ns, i3c_freq_ns);
125
126 _i3c_sda_hld_timing_set(regs, SDA_TX_HOLD_4);
127 _i3c_read_term_bit_low_count_set(regs, RD_TERM_BIT_LCNT_4);
128 }
129
130 /**
131 * @brief Initializes the target related registers
132 *
133 * @param regs Pointer to controller registers
134 */
MEC_HAL_I3C_Target_Init(struct mec_i3c_ctx * ctx,uint32_t core_clk_rate_mhz,uint16_t * max_rd_len,uint16_t * max_wr_len)135 void MEC_HAL_I3C_Target_Init(struct mec_i3c_ctx *ctx, uint32_t core_clk_rate_mhz,
136 uint16_t *max_rd_len, uint16_t *max_wr_len)
137 {
138 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
139 uint32_t core_clk_freq_ns;
140
141 const struct mec_i3c_info *info = get_i3c_info(ctx->base);
142
143 if (info) {
144
145 ctx->devi = info->devi;
146
147 mec_hal_pcr_clr_blk_slp_en(info->pcr_id);
148 mec_hal_pcr_blk_reset(info->pcr_id);
149
150 core_clk_freq_ns = MEC_DIV_ROUND_UP(1000000000, core_clk_rate_mhz);
151
152 /* Program the I3C Bus Free Avail Timing Register */
153 _i3c_bus_available_timing_set(regs, core_clk_freq_ns);
154
155 /* Program the I3C Bus Idle Timing Register */
156 _i3c_bus_idle_timing_set(regs, core_clk_freq_ns);
157
158 _i3c_bus_free_timing_set(regs, core_clk_freq_ns);
159 /* Get default max read and write length */
160 _i3c_tgt_MRL_get(regs, max_rd_len);
161 _i3c_tgt_MWL_get(regs, max_wr_len);
162
163 _i3c_sda_hld_switch_delay_timing_set(regs, SDA_OD_PP_SWITCH_DLY_0,
164 SDA_PP_OD_SWITCH_DLY_0, SDA_TX_HOLD_1);
165
166 _i3c_scl_low_mst_tout_set(regs, 0x003567E0);
167
168 _i3c_tgt_max_speed_update(regs, TGT_MAX_RD_DATA_SPEED, TGT_MAX_WR_DATA_SPEED);
169
170 _i3c_tgt_clk_to_data_turn_update(regs, TGT_CLK_TO_DATA_TURN);
171 /* Going with default values for TGT_TSX_SYMBL_TIMING register
172 * (params MXDS_CLK_DATA_TURN and MXDS_CLK_DATA_TURN)
173 * See section 8.1.4 in user guide; revisit later if we need to program
174 * these registers */
175
176 }
177 }
178
179 /**
180 * @brief Updates the Max read and write lengths if controller updates using CCC
181 *
182 * @param regs Pointer to controller registers
183 */
MEC_HAL_I3C_Target_MRL_MWL_update(struct mec_i3c_ctx * ctx,uint16_t * max_rd_len,uint16_t * max_wr_len)184 void MEC_HAL_I3C_Target_MRL_MWL_update(struct mec_i3c_ctx *ctx, uint16_t *max_rd_len,
185 uint16_t *max_wr_len)
186 {
187 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
188
189 if (_i3c_tgt_MRL_updated(regs)) {
190 _i3c_tgt_MRL_get(regs, max_rd_len);
191 }
192
193 if (_i3c_tgt_MWL_updated(regs)) {
194 _i3c_tgt_MWL_get(regs, max_wr_len);
195 }
196 }
197
198 /**
199 * @brief Sets the Max read and write lengths
200 *
201 * @param regs Pointer to controller registers
202 */
MEC_HAL_I3C_Target_MRL_MWL_set(struct mec_i3c_ctx * ctx,uint16_t max_rd_len,uint16_t max_wr_len)203 void MEC_HAL_I3C_Target_MRL_MWL_set(struct mec_i3c_ctx *ctx, uint16_t max_rd_len,
204 uint16_t max_wr_len)
205 {
206 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
207
208 _i3c_tgt_MRL_MWL_set(regs, max_rd_len, max_wr_len);
209 }
210
211 /**
212 * @brief Enable target controller interrupts
213 *
214 * @param regs Pointer to controller registers
215 */
MEC_HAL_I3C_Target_Interrupts_Init(struct mec_i3c_ctx * ctx)216 void MEC_HAL_I3C_Target_Interrupts_Init(struct mec_i3c_ctx *ctx)
217 {
218 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
219 uint32_t mask = 0xFFFFFFFFU;
220 const struct mec_i3c_info *info = get_i3c_info(ctx->base);
221
222 mec_hal_girq_ctrl(info->devi, 0);
223 mec_hal_pcr_clr_blk_slp_en(info->pcr_id);
224 /* Clear all interrupt status */
225 _i3c_intr_sts_clear(regs, mask);
226
227 /* Enable only necessary interrupts */
228 mask = sbit_RESP_READY_STS | sbit_CCC_UPDATED_STS | \
229 sbit_DYN_ADDR_ASSIGN_STS | sbit_DEFTGT_STS | \
230 sbit_READ_REQ_RECV_STS | sbit_IBI_UPDATED_STS | \
231 sbit_BUSOWNER_UPDATED_STS;
232
233 /* Enable required interrupt status */
234 _i3c_intr_sts_enable(regs, mask);
235
236 /* Enable required interrupt signals */
237 _i3c_intr_sgnl_enable(regs, mask);
238
239 /* Enable GIRQ */
240 mec_hal_girq_clr_src(info->devi);
241 mec_hal_girq_ctrl(info->devi, 1);
242 }
243
244 /**
245 * @brief Enable required controller interrupts
246 *
247 * @param regs Pointer to controller registers
248 */
MEC_HAL_I3C_Controller_Interrupts_Init(struct mec_i3c_ctx * ctx)249 void MEC_HAL_I3C_Controller_Interrupts_Init(struct mec_i3c_ctx *ctx)
250 {
251 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
252 uint32_t mask = 0xFFFFFFFFU;
253 const struct mec_i3c_info *info = get_i3c_info(ctx->base);
254
255 mec_hal_girq_ctrl(info->devi, 0);
256 mec_hal_pcr_clr_blk_slp_en(info->pcr_id);
257
258 /* Clear all interrupt status */
259 _i3c_intr_sts_clear(regs, mask);
260
261 /* Enable only necessary interrupts */
262 mask = sbit_RESP_READY_STS | sbit_TRANSFER_ABORT_STS | \
263 sbit_TRANSFER_ERR_STS | sbit_DEFTGT_STS | \
264 sbit_BUSOWNER_UPDATED_STS | sbit_BUS_RESET_DONE_STS;
265
266 /* Enable required interrupt status */
267 _i3c_intr_sts_enable(regs, mask);
268
269 /* Enable required interrupt signals */
270 _i3c_intr_sgnl_enable(regs, mask);
271
272 /* Enable GIRQ */
273 mec_hal_girq_clr_src(info->devi);
274 mec_hal_girq_ctrl(info->devi, 1);
275 }
276
277 /**
278 * @brief Initialize the Queue and Data buffer thresholds
279 *
280 * @param regs Pointer to controller registers
281 */
MEC_HAL_I3C_Thresholds_Init(struct mec_i3c_ctx * ctx)282 void MEC_HAL_I3C_Thresholds_Init(struct mec_i3c_ctx *ctx)
283 {
284 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
285
286 // Command Buffer Empty Threshold Value.
287 _i3c_cmd_queue_threshold_set(regs, 0x00);
288
289 // Response Buffer Threshold Value.
290 _i3c_resp_queue_threshold_set(regs, 0x00);
291
292 // IBI Data Threshold Value
293 _i3c_ibi_data_threshold_set(regs, 10);
294
295 // In-Band Interrupt Status Threshold Value.
296 _i3c_ibi_status_threshold_set(regs, 0x00);
297
298 // Transmit Buffer Threshold Value
299 _i3c_tx_buf_threshold_set(regs, DATA_BUF_THLD_TX_FIFO_EMPTY_1);
300
301 // Receive Buffer Threshold Value
302 _i3c_rx_buf_threshold_set(regs, DATA_BUF_THLD_RX_FIFO_1);
303
304 // Transfer Start Threshold Value
305 _i3c_tx_start_threshold_set(regs, DATA_BUF_THLD_TX_FIFO_START_1);
306
307 // Receive Start Threshold Value
308 _i3c_rx_start_threshold_set(regs, DATA_BUF_THLD_RX_FIFO_START_1);
309
310 // Notify Rejected Target Interrupt Request Control.
311 _i3c_notify_sir_reject(regs, false);
312
313 // Notify Rejected Master Request Control.
314 _i3c_notify_mr_reject(regs, false);
315
316 // Notify Rejected Hot-Join Control.
317 _i3c_notify_hj_reject(regs, false);
318 }
319
320 /**
321 * @brief Set Response Buffer Threshold to trigger interrupt
322 *
323 * @param regs Pointer to controller registers
324 * @param threshold Threshold value
325 */
MEC_HAL_I3C_Thresholds_Response_buf_set(struct mec_i3c_ctx * ctx,uint8_t threshold)326 void MEC_HAL_I3C_Thresholds_Response_buf_set(struct mec_i3c_ctx *ctx, uint8_t threshold)
327 {
328 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
329
330 _i3c_resp_queue_threshold_set(regs, threshold);
331 }
332
333 /**
334 * @brief
335 *
336 * @param regs Pointer to controller registers
337 */
MEC_HAL_I3C_Host_Config(struct mec_i3c_ctx * ctx)338 void MEC_HAL_I3C_Host_Config(struct mec_i3c_ctx *ctx)
339 {
340 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
341
342 _i3c_host_dma_tx_burst_length_set(regs, HOST_CFG_DMA_TX_BURST_LENGTH_4);
343
344 _i3c_host_dma_rx_burst_length_set(regs, HOST_CFG_DMA_RX_BURST_LENGTH_4);
345
346 _i3c_host_port_set(regs, HOST_CFG_PORT_SEL_I3C1);
347
348 _i3c_host_stuck_sda_config(regs, HOST_CFG_STUCK_SDA_DISABLE, 0xFFFFU);
349
350 _i3c_host_tx_dma_tout_config(regs, HOST_CFG_TX_DMA_TOUT_DISABLE, 0xFFFFU);
351
352 _i3c_host_rx_dma_tout_config(regs, HOST_CFG_RX_DMA_TOUT_DISABLE, 0xFFFFU);
353 }
354
355 /**
356 * @brief
357 *
358 * @param regs Pointer to controller registers
359 */
MEC_HAL_I3C_Sec_Host_Config(struct mec_i3c_ctx * ctx)360 void MEC_HAL_I3C_Sec_Host_Config(struct mec_i3c_ctx *ctx)
361 {
362 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
363
364 _i3c_sec_host_dma_tx_burst_length_set(regs, SEC_HOST_CFG_DMA_TX_BURST_LENGTH_4);
365
366 _i3c_sec_host_dma_rx_burst_length_set(regs, SEC_HOST_CFG_DMA_RX_BURST_LENGTH_4);
367
368 _i3c_sec_host_port_set(regs, SEC_HOST_CFG_PORT_SEL_I3C0);
369
370 _i3c_sec_host_stuck_sda_scl_config(regs, SEC_HOST_CFG_STUCK_SDA_SCL_DISABLE, 0xFFFFU, 0xFFFFU);
371
372 _i3c_sec_host_tx_dma_tout_config(regs, HOST_CFG_TX_DMA_TOUT_DISABLE, 0xFFFFU);
373
374 _i3c_sec_host_rx_dma_tout_config(regs, HOST_CFG_RX_DMA_TOUT_DISABLE, 0xFFFFU);
375 }
376
377 /**
378 * @brief configure timing for i3c transfers
379 *
380 * @param regs Pointer to controller registers
381 */
MEC_HAL_I3C_Soft_Reset(struct mec_i3c_ctx * ctx)382 void MEC_HAL_I3C_Soft_Reset(struct mec_i3c_ctx *ctx)
383 {
384 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
385
386 _i3c_soft_reset(regs);
387 }
388
389 /**
390 * @brief Retrieve Device Address Table Information
391 *
392 * @param regs Pointer to controller registers
393 * @param start_addr Start Address of DAT
394 * @param depth Depth of DAT
395 */
MEC_HAL_I3C_DAT_info_get(struct mec_i3c_ctx * ctx,uint16_t * start_addr,uint16_t * depth)396 void MEC_HAL_I3C_DAT_info_get(struct mec_i3c_ctx *ctx, uint16_t *start_addr, uint16_t *depth)
397 {
398 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
399
400 _i3c_dev_addr_table_ptr_get(regs, start_addr, depth);
401 }
402
403 /**
404 * @brief Retrieve Device Characteristic Table Information
405 *
406 * @param regs Pointer to controller registers
407 * @param start_addr Start Address of DCT
408 * @param depth Depth of DCT
409 */
MEC_HAL_I3C_DCT_info_get(struct mec_i3c_ctx * ctx,uint16_t * start_addr,uint16_t * depth)410 void MEC_HAL_I3C_DCT_info_get(struct mec_i3c_ctx *ctx, uint16_t *start_addr, uint16_t *depth)
411 {
412 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
413
414 _i3c_dev_char_table_ptr_get(regs, start_addr, depth);
415 }
416
417 /**
418 * @brief Check if the core is configured as a primary
419 * or a secondary controller
420 *
421 * @param regs Pointer to controller registers
422 */
MEC_HAL_I3C_Is_Current_Role_Primary(struct mec_i3c_ctx * ctx)423 bool MEC_HAL_I3C_Is_Current_Role_Primary(struct mec_i3c_ctx *ctx)
424 {
425 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
426
427 if (_i3c_dev_role_config_get(regs) != MEC_I3C_ROLE_CFG_PRIM_CTRLR) {
428 return false;
429 }
430 return true;
431 }
432
433 /**
434 * @brief Check if the core is operating in controller
435 * or target mode
436 * (applicable only to secondary controller)
437 *
438 * @param regs Pointer to controller registers
439 */
MEC_HAL_I3C_Is_Current_Role_Master(struct mec_i3c_ctx * ctx)440 bool MEC_HAL_I3C_Is_Current_Role_Master(struct mec_i3c_ctx *ctx)
441 {
442 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
443
444 if (((_i3c_dev_role_config_get(regs) == MEC_I3C_ROLE_CFG_SEC_CTRLR) &&
445 (_i3c_dev_operation_mode_get(regs) != 0)) ||
446 _i3c_dev_role_config_get(regs) == MEC_I3C_ROLE_CFG_TGT) {
447 return false;
448 }
449 return true;
450 }
451
452 /**
453 * @brief Check if the core is the current bus master
454 * or not (applicable only to secondary controller)
455 *
456 * @param regs Pointer to controller registers
457 */
MEC_HAL_I3C_Is_Current_Role_BusMaster(struct mec_i3c_ctx * ctx)458 bool MEC_HAL_I3C_Is_Current_Role_BusMaster(struct mec_i3c_ctx *ctx)
459 {
460 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
461
462 if ((_i3c_dev_role_config_get(regs) == MEC_I3C_ROLE_CFG_SEC_CTRLR) &&
463 (_i3c_dev_controller_role_get(regs) != 1U)) {
464 return false;
465 }
466 return true;
467 }
468
469 /**
470 * @brief Retrieve the depth of all queues
471 *
472 * @param regs Pointer to controller registers
473 */
MEC_HAL_I3C_queue_depths_get(struct mec_i3c_ctx * ctx,uint8_t * tx_depth,uint8_t * rx_depth,uint8_t * cmd_depth,uint8_t * resp_depth,uint8_t * ibi_depth)474 void MEC_HAL_I3C_queue_depths_get(struct mec_i3c_ctx *ctx,
475 uint8_t *tx_depth,
476 uint8_t *rx_depth,
477 uint8_t *cmd_depth,
478 uint8_t *resp_depth,
479 uint8_t *ibi_depth)
480 {
481
482 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
483
484 *tx_depth = _i3c_tx_fifo_depth_get(regs);
485 *rx_depth = _i3c_rx_fifo_depth_get(regs);
486 *cmd_depth = _i3c_cmd_fifo_depth_get(regs);
487 *resp_depth = _i3c_resp_fifo_depth_get(regs);
488 *ibi_depth = _i3c_ibi_fifo_depth_get(regs);
489 }
490
491 /**
492 * @brief Enables the I3C Controller
493 *
494 * @param regs Pointer to controller registers
495 * @param address 7-bit dynamic address for controller or
496 * 7-bit static address for target
497 * @param config configuration flags
498 */
MEC_HAL_I3C_Enable(struct mec_i3c_ctx * ctx,uint8_t address,uint8_t config)499 void MEC_HAL_I3C_Enable(struct mec_i3c_ctx *ctx, uint8_t address, uint8_t config)
500 {
501 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
502 uint8_t mode;
503 bool enable_dma = false;
504
505 mode = DEV_OPERATION_MODE_CTL;
506
507 if (sbit_MODE_TARGET & config) {
508 mode = DEV_OPERATION_MODE_TGT;
509 _i3c_static_addr_set(regs, address);
510 } else {
511 _i3c_dynamic_addr_set(regs, address);
512 }
513
514 if (sbit_HOTJOIN_DISABLE & config) {
515
516 if (sbit_MODE_TARGET & config) {
517 _i3c_tgt_hot_join_disable((struct mec_i3c_sec_regs *)regs);
518
519 } else {
520 /* Disable Hot-Join */
521 _i3c_hot_join_disable(regs);
522 }
523
524 } else {
525
526 if (!(sbit_MODE_TARGET & config)) {
527 /* Enable IBI Interrupt */
528 _i3c_intr_IBI_enable(regs);
529 }
530 }
531
532 if (sbit_CONFG_ENABLE & config) {
533
534 /* Set Operation Mode */
535 _i3c_operation_mode_set(regs, mode);
536
537 if (sbit_DMA_MODE & config) {
538 enable_dma = true;
539 }
540
541 /* Enable the Controller */
542 _i3c_enable(regs, mode, enable_dma);
543
544 /* For the target mode of operation, we are not programming
545 * the IDLE_CNT_MULTIPLIER and ADAPTIVE_I2C_I3C. Mostly likely
546 * the default values should be fine; Revisit later if we need to update
547 * them. Reference section 8.1.4 in user guide */
548
549 }
550 else {
551 /* Disable the Controller */
552 _i3c_disable(regs);
553 }
554 }
555
556 /**
557 * @brief Reads the DCT entry
558 *
559 * @param regs Pointer to controller registers
560 * @param DCT_start Start address of DCT
561 * @param DCT_idx Index for the DAT entry
562 * @param address 7-bit dynamic address
563 */
MEC_HAL_I3C_DCT_read(struct mec_i3c_ctx * ctx,uint16_t DCT_start,uint16_t DCT_idx,struct mec_i3c_DCT_info * info)564 void MEC_HAL_I3C_DCT_read(struct mec_i3c_ctx *ctx, uint16_t DCT_start, uint16_t DCT_idx,
565 struct mec_i3c_DCT_info *info)
566 {
567 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
568
569 _i3c_DCT_read(regs, DCT_start, (uint8_t)DCT_idx, info);
570 }
571
572 /**
573 * @brief Read the entries from SDCT and program DAT
574 *
575 * @param regs Pointer to controller registers
576 * @param DCT_start Start address of DCT
577 * @param targets_count Number of entries in the SDCT
578 */
MEC_HAL_I3C_TGT_DEFTGTS_DAT_write(struct mec_i3c_ctx * ctx,uint16_t DCT_start,uint16_t DAT_start,uint8_t targets_count)579 void MEC_HAL_I3C_TGT_DEFTGTS_DAT_write(struct mec_i3c_ctx *ctx, uint16_t DCT_start,
580 uint16_t DAT_start, uint8_t targets_count)
581 {
582 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
583 struct mec_i3c_SDCT_info sdct_info;
584 uint32_t val = 0;
585 uint8_t i;
586
587 for (i=0; i< targets_count; i++) {
588
589 MEC_HAL_I3C_SDCT_read(ctx, DCT_start, i, &sdct_info);
590
591 val = DEV_ADDR_TABLE1_LOC1_DYNAMIC_ADDR(sdct_info.dynamic_addr);
592
593 if (sdct_info.static_addr) {
594 val |= DEV_ADDR_TABLE1_LOC1_STATIC_ADDR(sdct_info.static_addr);
595 }
596
597 _i3c_DAT_write(regs, DAT_start, i, val);
598 }
599 }
600
601 /**
602 * @brief Reads the Secondary DCT entry
603 *
604 _i3c_SDCT_read(regs, DCT_start, DCT_idx, info);
605 }* @param regs Pointer to controller registers
606 * @param DCT_start Start address of DCT
607 * @param DCT_idx Index for the DAT entry
608 * @param address 7-bit dynamic address
609 */
MEC_HAL_I3C_SDCT_read(struct mec_i3c_ctx * ctx,uint16_t DCT_start,uint16_t idx,struct mec_i3c_SDCT_info * info)610 void MEC_HAL_I3C_SDCT_read(struct mec_i3c_ctx *ctx, uint16_t DCT_start, uint16_t idx,
611 struct mec_i3c_SDCT_info *info)
612 {
613 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
614
615 _i3c_SDCT_read(regs, DCT_start, (uint8_t)idx, info);
616 }
617
618 /**
619 * @brief Writes the DAT entry with a dynamic address
620 *
621 * @param regs Pointer to controller registers
622 * @param DAT_loc Start address of DAT
623 * @param DAT_idx Index for the DAT entry
624 * @param address 7-bit dynamic address
625 */
MEC_HAL_I3C_DAT_DynamicAddr_write(struct mec_i3c_ctx * ctx,uint16_t DAT_start,uint16_t DAT_idx,uint8_t address)626 void MEC_HAL_I3C_DAT_DynamicAddr_write(struct mec_i3c_ctx *ctx, uint16_t DAT_start,
627 uint16_t DAT_idx, uint8_t address)
628 {
629 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
630 uint32_t val;
631
632 val = DEV_ADDR_TABLE1_LOC1_DYNAMIC_ADDR(address);
633
634 _i3c_DAT_write(regs, DAT_start, (uint8_t)DAT_idx, val);
635 }
636
637 /**
638 * @brief Writes the DAT entry with a dynamic address for DAA
639 *
640 * @param regs Pointer to controller registers
641 * @param DAT_loc Start address of DAT
642 * @param DAT_idx Index for the DAT entry
643 * @param address 7-bit dynamic address
644 */
MEC_HAL_I3C_DAT_DynamicAddrAssign_write(struct mec_i3c_ctx * ctx,uint16_t DAT_start,uint16_t DAT_idx,uint8_t address)645 void MEC_HAL_I3C_DAT_DynamicAddrAssign_write(struct mec_i3c_ctx *ctx, uint16_t DAT_start,
646 uint16_t DAT_idx, uint8_t address)
647 {
648 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
649 uint32_t val;
650
651 val = DEV_ADDR_TABLE1_LOC1_DYNAMIC_ADDR(address);
652
653 /* Set the odd parity for the dynamic address */
654 if (!__builtin_parity(address)) {
655 val |= DEV_ADDR_TABLE1_LOC1_PARITY;
656 }
657
658 _i3c_DAT_write(regs, DAT_start, (uint8_t)DAT_idx, val);
659 }
660
661 /**
662 * @brief Starts the DAA process using ENTDAA
663 *
664 * @param regs Pointer to controller registers
665 * @param tgt_idx Device index of the first device in DAT that needs DAA
666 * @param tgts_count Number of devices (from tgt_idx) that needs DAA process
667 * @param tid_xfer Tid used for the transfer
668 */
MEC_HAL_I3C_DO_DAA(struct mec_i3c_ctx * ctx,uint8_t tgt_idx,uint8_t tgts_count,uint8_t * tid_xfer)669 void MEC_HAL_I3C_DO_DAA(struct mec_i3c_ctx *ctx, uint8_t tgt_idx, uint8_t tgts_count,
670 uint8_t *tid_xfer)
671 {
672 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
673 uint32_t command = 0;
674
675 tid++; if (tid > 0) tid = 0; *tid_xfer = tid;
676
677 command = (tid << COMMAND_AA_TID_BITPOS) |
678 (tgt_idx << COMMAND_AA_DEV_IDX_BITPOS) |
679 (MEC_I3C_CCC_ENTDAA << COMMAND_AA_CMD_BITPOS) |
680 (tgts_count << COMMAND_AA_DEV_CNT_BITPOS) |
681 COMMAND_STOP_ON_COMPLETION |
682 COMMAND_RESPONSE_ON_COMPLETION |
683 COMMAND_ATTR_ADDR_ASSGN_CMD;
684
685 /* Set Response Buffer Threshold as 1 entry */
686 _i3c_resp_queue_threshold_set(regs, 0);
687
688 /* All required interrupts are already enabled? */
689
690 /* Write the Command */
691 _i3c_command_write(regs, command);
692 }
693
694 /**
695 * @brief Sends the CCC on the I3C bus
696 *
697 * @param regs Pointer to controller registers
698 * @param target Target that need to be sent CCC
699 * @param tid_xfer Tid used for the transfer
700 */
MEC_HAL_I3C_DO_CCC(struct mec_i3c_ctx * ctx,struct mec_i3c_DO_CCC * tgt,uint8_t * tid_xfer)701 void MEC_HAL_I3C_DO_CCC(struct mec_i3c_ctx *ctx, struct mec_i3c_DO_CCC *tgt, uint8_t *tid_xfer)
702 {
703 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
704 uint32_t command = 0, argument = 0;
705
706 argument = COMMAND_ATTR_XFER_ARG;
707 argument |= (tgt->data_len << COMMAND_XFER_ARG_DATA_LEN_BITPOS);
708 if (tgt->defining_byte_valid) {
709 argument |= (tgt->defining_byte << COMMAND_XFER_DEF_BYTE_BITPOS);
710 }
711
712 tid++; if (tid > 0) tid = 0; *tid_xfer = tid;
713
714 command = (tid << COMMAND_TID_BITPOS) |
715 (tgt->tgt_idx << COMMAND_DEV_IDX_BITPOS) |
716 (tgt->ccc_id << COMMAND_CMD_BITPOS) |
717 COMMAND_STOP_ON_COMPLETION |
718 COMMAND_RESPONSE_ON_COMPLETION |
719 COMMAND_CMD_PRESENT |
720 COMMAND_ATTR_XFER_CMD;
721 /* Note:
722 * Response Buffer Threshold is already set to 1 (in initialization)
723 */
724
725 if (tgt->defining_byte_valid) {
726 command |= COMMAND_DEF_BYTE_PRESENT;
727 }
728
729 if (tgt->read) { //CCC Get
730
731 command |= COMMAND_READ_XFER;
732
733 } else { // CCC Set
734
735 if (tgt->data_len) {
736
737 /* fill the TX FIFO with the data
738 * Note: We are not using Short Data Argument
739 */
740 _i3c_fifo_write(regs, tgt->data_buf, tgt->data_len);
741 }
742
743 }
744
745 /* Set Response Buffer Threshold as 1 entry */
746 _i3c_resp_queue_threshold_set(regs, 0);
747
748 if (tgt->data_len || tgt->defining_byte_valid)
749 {
750 /* Write the transfer argument */
751 _i3c_command_write(regs, argument);
752 }
753
754 /* All required interrupts are already enabled? */
755 /* Write the Command */
756 _i3c_command_write(regs, command);
757 }
758
759 /**
760 * @brief Prepare for private transfer
761 * This function will form the command and argument DS
762 * and write data to the tx FIFO in case of private
763 * write
764 *
765 * @param regs Pointer to controller registers
766 * @param target Target that need to be sent CCC
767 * @param tid_xfer Tid used for the transfer
768 */
MEC_HAL_I3C_DO_Xfer_Prep(struct mec_i3c_ctx * ctx,struct mec_i3c_dw_cmd * cmd,uint8_t * tid_xfer)769 void MEC_HAL_I3C_DO_Xfer_Prep(struct mec_i3c_ctx *ctx, struct mec_i3c_dw_cmd *cmd,
770 uint8_t *tid_xfer)
771 {
772 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
773 uint32_t command = 0, argument = 0;
774
775 argument = (cmd->data_len << COMMAND_XFER_ARG_DATA_LEN_BITPOS) |
776 COMMAND_ATTR_XFER_ARG;
777
778 tid++; if (tid > 0) tid = 0; *tid_xfer = tid;
779
780 command = (tid << COMMAND_TID_BITPOS) |
781 (cmd->tgt_idx << COMMAND_DEV_IDX_BITPOS) |
782 (cmd->xfer_speed << COMMAND_SPEED_BITPOS) |
783 COMMAND_RESPONSE_ON_COMPLETION |
784 COMMAND_ATTR_XFER_CMD;
785
786 if(true == cmd->stop) {
787 /* Send STOP */
788 command |= COMMAND_STOP_ON_COMPLETION;
789 } else {
790 // Send REPEATED START
791 }
792
793 if(true == cmd->pec_en) {
794 /* Calculate PEC */
795 command |= COMMAND_PACKET_ERROR_CHECK;
796 } else {
797 /* Do not calculate PEC */
798 }
799 /* Note:
800 * Response Buffer Threshold is already set to 1 (in initialization)
801 */
802
803 if (cmd->read) { // Read data
804
805 command |= COMMAND_READ_XFER;
806
807 if (MEC_XFER_SPEED_HDR_DDR == cmd->xfer_speed) {
808 command |= (COMMAND_CMD_PRESENT | COMMAND_HDR_DDR_READ_BITPOS);
809 }
810
811 } else { // Write data
812
813 /* fill the TX FIFO with the data
814 * Note: We are not using Short Data Argument
815 */
816
817 if (MEC_XFER_SPEED_HDR_DDR == cmd->xfer_speed) {
818 command |= (COMMAND_CMD_PRESENT | COMMAND_HDR_DDR_WRITE_BITPOS);
819 }
820
821 _i3c_fifo_write(regs, cmd->data_buf, cmd->data_len);
822 }
823
824 cmd->cmd = command;
825 cmd->arg = argument;
826 }
827
MEC_HAL_I3C_DO_Xfer(struct mec_i3c_ctx * ctx,struct mec_i3c_dw_cmd * tgt)828 void MEC_HAL_I3C_DO_Xfer(struct mec_i3c_ctx *ctx, struct mec_i3c_dw_cmd *tgt)
829 {
830 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
831
832 /* Write the transfer argument */
833 _i3c_command_write(regs, tgt->arg);
834
835 _i3c_command_write(regs, tgt->cmd);
836 }
837
838
MEC_HAL_I3C_DO_TGT_Xfer(struct mec_i3c_ctx * ctx,uint8_t * data_buf,uint16_t data_len)839 void MEC_HAL_I3C_DO_TGT_Xfer(struct mec_i3c_ctx *ctx, uint8_t *data_buf, uint16_t data_len)
840 {
841 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
842 uint32_t command = 0;
843
844 tid++; if (tid > 0) tid = 0;
845
846 /* fill the TX FIFO with the data */
847 _i3c_fifo_write(regs, data_buf, data_len);
848
849 command = ((data_len << COMMAND_XFER_ARG_DATA_LEN_BITPOS) |
850 (tid << COMMAND_TID_BITPOS));
851 /*Note: Command Attribute is 0 - Transmit Command without IBI */
852
853 /* Write the transfer command */
854 _i3c_command_write(regs, command);
855
856 }
857
858 /**
859 * @brief Enables the IBI SIR for the target
860 *
861 * @param regs Pointer to controller registers
862 * @param ibi_sir_info Information required to enable IBI SIR on a target
863 * @param ibi_sir_info Flag to indicate if IBI interrupt needs to be enabled
864 */
MEC_HAL_I3C_IBI_SIR_Enable(struct mec_i3c_ctx * ctx,struct mec_i3c_IBI_SIR * ibi_sir_info,bool enable_ibi_interrupt)865 void MEC_HAL_I3C_IBI_SIR_Enable(struct mec_i3c_ctx *ctx, struct mec_i3c_IBI_SIR *ibi_sir_info,
866 bool enable_ibi_interrupt)
867 {
868 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
869 uint32_t dat_value;
870
871 /* Following sequence is for Controller only configuration
872 * For secondary controller need to program 32-bit vector control
873 * register (IBI_SIR_REQ_REJECT).
874 * See section 2.6.3.3.1 1 in Databook
875 */
876
877 /* Get the Dat entry */
878 dat_value = _i3c_DAT_read(regs, ibi_sir_info->DAT_start, ibi_sir_info->tgt_dat_idx);
879
880 /* Enable IBI SIR */
881 dat_value &= ~DEV_ADDR_TABLE1_LOC1_SIR_REJECT;
882
883 if (ibi_sir_info->ibi_has_payload) {
884 /* IBI with one or more mandatory bytes */
885 dat_value |= DEV_ADDR_TABLE1_LOC1_IBI_WITH_DATA;
886 }
887
888 _i3c_DAT_write(regs, ibi_sir_info->DAT_start, ibi_sir_info->tgt_dat_idx, dat_value);
889
890 if ((0 == targets_ibi_enable_sts) && (enable_ibi_interrupt)) {
891
892 /* IBI Data and Status thresholds are already set in initialization */
893 _i3c_intr_IBI_enable(regs);
894 }
895
896 targets_ibi_enable_sts |= (1 << ibi_sir_info->tgt_dat_idx);
897 }
898
899 /**
900 * @brief Enables the IBI SIR for the target
901 *
902 * @param regs Pointer to controller registers
903 * @param ibi_sir_info Information required to disable IBI SIR on a target
904 * @param disable_ibi_interrupt Flag to indicate if IBI interrupt can be disabled
905 */
MEC_HAL_I3C_IBI_SIR_Disable(struct mec_i3c_ctx * ctx,struct mec_i3c_IBI_SIR * ibi_sir_info,bool disable_ibi_interrupt)906 void MEC_HAL_I3C_IBI_SIR_Disable(struct mec_i3c_ctx *ctx, struct mec_i3c_IBI_SIR *ibi_sir_info,
907 bool disable_ibi_interrupt)
908 {
909 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
910 uint32_t dat_value;
911
912 /* Get the Dat entry */
913 dat_value = _i3c_DAT_read(regs, ibi_sir_info->DAT_start, ibi_sir_info->tgt_dat_idx);
914
915 /* Disable IBI SIR */
916 dat_value |= DEV_ADDR_TABLE1_LOC1_SIR_REJECT;
917
918 _i3c_DAT_write(regs, ibi_sir_info->DAT_start, ibi_sir_info->tgt_dat_idx, dat_value);
919
920 targets_ibi_enable_sts &= (uint32_t)~(1 << ibi_sir_info->tgt_dat_idx);
921
922 if ((0 == targets_ibi_enable_sts) && (disable_ibi_interrupt)){
923
924 _i3c_intr_IBI_disable(regs);
925 }
926 }
927
928 /**
929 * @brief Set the MIPI PID value for target
930 *
931 * @param regs Pointer to controller registers
932 * @param pid 48-bit PID value
933 */
MEC_HAL_I3C_TGT_PID_set(struct mec_i3c_ctx * ctx,uint64_t pid,bool pid_random)934 void MEC_HAL_I3C_TGT_PID_set(struct mec_i3c_ctx *ctx, uint64_t pid, bool pid_random)
935 {
936 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
937
938 _i3c_tgt_pid_set(regs, TGT_MIPI_MFG_ID(pid), pid_random,
939 TGT_PART_ID(pid), TGT_INST_ID(pid),
940 TGT_PID_DCR(pid));
941 }
942
943 /**
944 * @brief Check if the dynamic address is valid (in target mode)
945 *
946 * @param regs Pointer to controller registers
947 */
MEC_HAL_I3C_TGT_is_dyn_addr_valid(struct mec_i3c_ctx * ctx)948 bool MEC_HAL_I3C_TGT_is_dyn_addr_valid(struct mec_i3c_ctx *ctx)
949 {
950 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
951
952 return _i3c_tgt_dyn_addr_valid_get(regs);
953 }
954
955 /**
956 * @brief Get the dynamic address assinged (in target mode)
957 *
958 * @param regs Pointer to controller registers
959 */
MEC_HAL_I3C_TGT_dyn_addr_get(struct mec_i3c_ctx * ctx)960 uint8_t MEC_HAL_I3C_TGT_dyn_addr_get(struct mec_i3c_ctx *ctx)
961 {
962 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
963
964 return _i3c_tgt_dyn_addr_get(regs);;
965 }
966
967 /**
968 * @brief Set the MWL value for target
969 *
970 * @param regs Pointer to controller registers
971 * @param uint8_t wr_speed maximum write speed, refer enum mec_mxds_max_wr_speed
972 * @param uint8_t rd_speed maximum read speed, refer enum mec_mxds_max_rd_speed
973 * @param uint8_t tsco clock to data turnaround time, refer enum mec_mxds_tsco
974 */
MEC_HAL_I3C_TGT_MXDS_set(struct mec_i3c_ctx * ctx,uint8_t wr_speed,uint8_t rd_speed,uint8_t tsco,uint32_t rd_trnd_us)975 void MEC_HAL_I3C_TGT_MXDS_set(struct mec_i3c_ctx *ctx,
976 uint8_t wr_speed,
977 uint8_t rd_speed,
978 uint8_t tsco,
979 uint32_t rd_trnd_us)
980 {
981 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
982
983 _i3c_tgt_mxds_set(regs, wr_speed, rd_speed, tsco, rd_trnd_us);
984 }
985
986 /**
987 * @brief Issues the IBI SIR for the target
988 *
989 * @param regs Pointer to controller registers
990 * @param ibi_sir_info Information required to enable IBI SIR on a target
991 */
MEC_HAL_I3C_TGT_IBI_SIR_Raise(struct mec_i3c_ctx * ctx,struct mec_i3c_raise_IBI_SIR * ibi_sir_request)992 int MEC_HAL_I3C_TGT_IBI_SIR_Raise(struct mec_i3c_ctx *ctx,
993 struct mec_i3c_raise_IBI_SIR *ibi_sir_request)
994 {
995 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
996 uint8_t ret = 0;
997
998 /* Ensure Controller has enabled SIR for the target (us) */
999 if (_i3c_tgt_SIR_enabled(regs)) {
1000
1001 /* Raise IBI SIR*/
1002 _i3c_tgt_raise_ibi_SIR(regs, ibi_sir_request->data_buf, ibi_sir_request->data_len,
1003 ibi_sir_request->mdb);
1004
1005 } else {
1006 ret = 1;
1007 }
1008
1009 return ret;
1010 }
1011
1012 /**
1013 * @brief Issues the IBI Master Request for the target
1014 *
1015 * @param regs Pointer to controller registers
1016 */
MEC_HAL_I3C_TGT_IBI_MR_Raise(struct mec_i3c_ctx * ctx)1017 int MEC_HAL_I3C_TGT_IBI_MR_Raise(struct mec_i3c_ctx *ctx)
1018 {
1019 struct mec_i3c_sec_regs *regs = (struct mec_i3c_sec_regs *)ctx->base;
1020 uint8_t ret = 0;
1021
1022 /* Ensure Controller has enabled MR for the target (us) */
1023 if (_i3c_tgt_MR_enabled(regs)) {
1024
1025 /* Raise IBI SIR*/
1026 _i3c_tgt_raise_ibi_MR(regs);
1027
1028 } else {
1029 ret = 1;
1030 }
1031
1032 return ret;
1033 }
1034
1035 /**
1036 * @brief Handles Target Raise IBI SIR Residual data
1037 *
1038 * @param regs Pointer to controller registers
1039 */
MEC_HAL_I3C_TGT_IBI_SIR_Residual_handle(struct mec_i3c_ctx * ctx)1040 void MEC_HAL_I3C_TGT_IBI_SIR_Residual_handle(struct mec_i3c_ctx *ctx)
1041 {
1042 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
1043 /* Clear SIR residual data by resettig TX Fifo */
1044 _i3c_tx_fifo_rst(regs);
1045
1046 /* Hit Resume */
1047 _i3c_resume(regs);
1048 }
1049
1050 /**
1051 * @brief Handles Target Raise IBI SIR Residual data
1052 *
1053 * @param regs Pointer to controller registers
1054 */
MEC_HAL_I3C_TGT_Error_Recovery(struct mec_i3c_ctx * ctx,uint8_t err_sts)1055 void MEC_HAL_I3C_TGT_Error_Recovery(struct mec_i3c_ctx *ctx, uint8_t err_sts)
1056 {
1057 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
1058
1059 if ((err_sts == TARGET_RESP_ERR_CRC) ||
1060 (err_sts == TARGET_RESP_ERR_PARITY) ||
1061 (err_sts == TARGET_RESP_ERR_UNDERFLOW_OVERFLOW)) {
1062
1063 /* Reset RX Fifo */
1064 _i3c_rx_fifo_rst(regs);
1065
1066 } else {
1067
1068 /* Reset TX FIFO and Command Queue */
1069 _i3c_tx_fifo_rst(regs);
1070 _i3c_cmd_queue_rst(regs);
1071 }
1072 /* Hit Resume */
1073 _i3c_resume(regs);
1074 }
1075
1076 /**
1077 * @brief Handles switching of target to controller for role switch IBI
1078 *
1079 * @param regs Pointer to controller registers
1080 */
MEC_HAL_I3C_TGT_RoleSwitch_Resume(struct mec_i3c_ctx * ctx)1081 void MEC_HAL_I3C_TGT_RoleSwitch_Resume(struct mec_i3c_ctx *ctx)
1082 {
1083 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
1084
1085 /* Reset TX and RX Fifos */
1086 _i3c_rx_fifo_rst(regs);
1087 _i3c_tx_fifo_rst(regs);
1088
1089 /* Reset command queues */
1090 _i3c_cmd_queue_rst(regs);
1091
1092 /* Hit Resume */
1093 _i3c_resume(regs);
1094
1095 }
1096
1097
1098
1099 /**
1100 * @brief Resumes the controller and clears transfer error
1101 *
1102 * @param regs Pointer to controller registers
1103 */
MEC_HAL_I3C_Xfer_Error_Resume(struct mec_i3c_ctx * ctx)1104 void MEC_HAL_I3C_Xfer_Error_Resume(struct mec_i3c_ctx *ctx)
1105 {
1106 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
1107
1108 /* Hit Resume */
1109 _i3c_resume(regs);
1110
1111 /* Clear transfer error status */
1112 _i3c_xfer_err_sts_clr(regs);
1113 }
1114
1115 /**
1116 * @brief Resets the transfer fifos and queues
1117 *
1118 * @param regs Pointer to controller registers
1119 */
MEC_HAL_I3C_Xfer_Reset(struct mec_i3c_ctx * ctx)1120 void MEC_HAL_I3C_Xfer_Reset(struct mec_i3c_ctx *ctx)
1121 {
1122 struct mec_i3c_host_regs *regs = (struct mec_i3c_host_regs *)ctx->base;
1123
1124 /* Reset the TX/RX Fifos & Cmd/Res Queues */
1125 _i3c_xfers_reset(regs);
1126 }
1127
1128
1129 /* Interrupt functions */
1130 /*--------------------------------------------------------*/
1131
MEC_HAL_I3C_GIRQ_Status_Clr(struct mec_i3c_ctx * ctx)1132 void MEC_HAL_I3C_GIRQ_Status_Clr(struct mec_i3c_ctx *ctx)
1133 {
1134 if (ctx) {
1135
1136 mec_hal_girq_clr_src(ctx->devi);
1137 }
1138 }
1139
1140 /* Enable/disable I23 controller interrupt signal from propagating to NVIC */
MEC_HAL_I3C_GIRQ_CTRL(struct mec_i3c_ctx * ctx,int flags)1141 void MEC_HAL_I3C_GIRQ_CTRL(struct mec_i3c_ctx *ctx, int flags)
1142 {
1143 if (ctx) {
1144
1145
1146 if (flags & MEC_I3C_GIRQ_DIS) {
1147 mec_hal_girq_ctrl(ctx->devi, 0);
1148 }
1149
1150 if (flags & MEC_I3C_GIRQ_CLR_STS) {
1151 mec_hal_girq_clr_src(ctx->devi);
1152 }
1153
1154 if (flags & MEC_I3C_GIRQ_EN) {
1155 mec_hal_girq_ctrl(ctx->devi, 1);
1156 }
1157 }
1158
1159 }
1160
MEC_HAL_I3C_GIRQ_Status(struct mec_i3c_ctx * ctx)1161 int MEC_HAL_I3C_GIRQ_Status(struct mec_i3c_ctx *ctx)
1162 {
1163 if (!ctx) {
1164 return 0;
1165 }
1166
1167 return (int)mec_hal_girq_src(ctx->devi);
1168 }
1169
MEC_HAL_I3C_GIRQ_Result(struct mec_i3c_ctx * ctx)1170 int MEC_HAL_I3C_GIRQ_Result(struct mec_i3c_ctx *ctx)
1171 {
1172 if (!ctx) {
1173 return 0;
1174 }
1175
1176 return (int)mec_hal_girq_result(ctx->devi);
1177 }
1178