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