1 /*
2  * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <string.h>
7 
8 #include <device_mec5.h>
9 #include "mec_defs.h"
10 #include "mec_pcfg.h"
11 #include "mec_ecia_api.h"
12 #include "mec_pcr_api.h"
13 #include "mec_retval.h"
14 
15 #include "mec_i3c_pvt.h"
16 
17 
18 /**
19  * @brief Get interrupt status
20  *
21  * @param regs Pointer to controller registers
22  */
_i3c_intr_sts_get(struct mec_i3c_host_regs * regs)23 uint32_t _i3c_intr_sts_get(struct mec_i3c_host_regs *regs)
24 {
25     return regs->INTR_STS;
26 }
27 
28 /**
29  * @brief clear all interrupt status
30  *
31  * @param regs Pointer to controller registers
32  */
_i3c_intr_sts_clear(struct mec_i3c_host_regs * regs,uint32_t mask)33 void _i3c_intr_sts_clear(struct mec_i3c_host_regs *regs, uint32_t mask)
34 {
35     regs->INTR_STS = mask;
36 }
37 
38 /**
39  * @brief Enable interrupt status
40  *
41  * @param regs Pointer to controller registers
42  */
_i3c_intr_sts_enable(struct mec_i3c_host_regs * regs,uint32_t mask)43 void _i3c_intr_sts_enable(struct mec_i3c_host_regs *regs, uint32_t mask)
44 {
45     regs->INTR_EN = mask;
46 }
47 
48 /**
49  * @brief Enable IBI interrupt
50  *
51  * @param regs Pointer to controller registers
52  */
_i3c_intr_IBI_enable(struct mec_i3c_host_regs * regs)53 void _i3c_intr_IBI_enable(struct mec_i3c_host_regs *regs)
54 {
55     regs->INTR_EN |= sbit_IBI_THLD_STS;
56 
57     regs->INTR_SIG_EN |= sbit_IBI_THLD_STS;
58 }
59 
60 /**
61  * @brief Disable IBI interrupt
62  *
63  * @param regs Pointer to controller registers
64  */
_i3c_intr_IBI_disable(struct mec_i3c_host_regs * regs)65 void _i3c_intr_IBI_disable(struct mec_i3c_host_regs *regs)
66 {
67     regs->INTR_EN &= (uint32_t)~sbit_IBI_THLD_STS;
68 
69     regs->INTR_SIG_EN &= (uint32_t)~sbit_IBI_THLD_STS;
70 }
71 
72 /**
73  * @brief Enable the TX Threshold interrupt
74  *
75  * @param regs Pointer to controller registers
76  */
_i3c_intr_thresholds_tx_enable(struct mec_i3c_host_regs * regs)77 void _i3c_intr_thresholds_tx_enable(struct mec_i3c_host_regs *regs)
78 {
79     regs->INTR_EN |= sbit_TX_THLD_STS;
80 
81     regs->INTR_SIG_EN |= sbit_TX_THLD_STS;
82 }
83 
84 /**
85  * @brief Disable the TX Threshold interrupt
86  *
87  * @param regs Pointer to controller registers
88  */
_i3c_intr_thresholds_tx_disable(struct mec_i3c_host_regs * regs)89 void _i3c_intr_thresholds_tx_disable(struct mec_i3c_host_regs *regs)
90 {
91     regs->INTR_EN &= (uint32_t)~sbit_TX_THLD_STS;
92 
93     regs->INTR_SIG_EN &= (uint32_t)~sbit_TX_THLD_STS;
94 }
95 
96 /**
97  * @brief Enable the RX Threshold interrupt
98  *
99  * @param regs Pointer to controller registers
100  */
_i3c_intr_thresholds_rx_enable(struct mec_i3c_host_regs * regs)101 void _i3c_intr_thresholds_rx_enable(struct mec_i3c_host_regs *regs)
102 {
103     regs->INTR_EN |= sbit_RX_THLD_STS;
104 
105     regs->INTR_SIG_EN |= sbit_RX_THLD_STS;
106 }
107 
108 /**
109  * @brief Disable the RX Threshold interrupt
110  *
111  * @param regs Pointer to controller registers
112  */
_i3c_intr_thresholds_rx_disable(struct mec_i3c_host_regs * regs)113 void _i3c_intr_thresholds_rx_disable(struct mec_i3c_host_regs *regs)
114 {
115     regs->INTR_EN &= (uint32_t)~sbit_RX_THLD_STS;
116 
117     regs->INTR_SIG_EN &= (uint32_t)~sbit_RX_THLD_STS;
118 }
119 
120 /**
121  * @brief Enable interrupt signal
122  *
123  * @param regs Pointer to controller registers
124  */
_i3c_intr_sgnl_enable(struct mec_i3c_host_regs * regs,uint32_t mask)125 void _i3c_intr_sgnl_enable(struct mec_i3c_host_regs *regs, uint32_t mask)
126 {
127     regs->INTR_SIG_EN = mask;
128 }
129 
130 /**
131  * @brief Set Response Buffer Threshold to trigger interrupt
132  *
133  * @param regs Pointer to controller registers
134  */
_i3c_resp_queue_threshold_set(struct mec_i3c_host_regs * regs,uint8_t threshold)135 void _i3c_resp_queue_threshold_set(struct mec_i3c_host_regs *regs, uint8_t threshold)
136 {
137     if (threshold < I3C_RESPONSE_BUFFER_DEPTH)
138     {
139         regs->QUE_THLD_CTRL &= (uint32_t)~(0xFFu << QUEUE_THLD_RESP_QUEUE_BITPOS);
140         regs->QUE_THLD_CTRL |= (threshold << QUEUE_THLD_RESP_QUEUE_BITPOS);
141     }
142 }
143 
144 /**
145  * @brief Reads the Response Buffer Level Value
146  *
147  * @param regs Pointer to controller registers
148  */
_i3c_resp_buf_level_get(struct mec_i3c_host_regs * regs)149 uint8_t _i3c_resp_buf_level_get(struct mec_i3c_host_regs *regs)
150 {
151     volatile uint8_t level = 0;
152 
153     level = (regs->QUE_STS_LVL >> Q_STS_LVL_RESP_BUFFER_BIT_POS) & 0xFF;
154 
155     return level;
156 }
157 
158 /**
159  * @brief Reads the IBI status count
160  *
161  * @param regs Pointer to controller registers
162  */
_i3c_ibi_status_count_get(struct mec_i3c_host_regs * regs)163 uint8_t _i3c_ibi_status_count_get(struct mec_i3c_host_regs *regs)
164 {
165     volatile uint8_t level = 0;
166 
167     level = (regs->QUE_STS_LVL >> Q_STS_LVL_IBI_STS_CNT_BIT_POS) & 0x1F;
168 
169     return level;
170 }
171 
172 /**
173  * @brief Reads the IBI status queue
174  *
175  * @param regs Pointer to controller registers
176  */
_i3c_ibi_queue_status_get(struct mec_i3c_host_regs * regs)177 uint32_t _i3c_ibi_queue_status_get(struct mec_i3c_host_regs *regs)
178 {
179     volatile uint32_t queue_sts = 0;
180 
181     queue_sts = regs->IBI_QUE_STS;
182 
183     return queue_sts;
184 }
185 
186 /**
187  * @brief Reads the Response Buffer Level Value
188  *
189  * @param regs Pointer to controller registers
190  */
_i3c_response_sts_get(struct mec_i3c_host_regs * regs,uint16_t * len,uint8_t * tid)191 uint8_t _i3c_response_sts_get(struct mec_i3c_host_regs *regs, uint16_t *len, uint8_t *tid)
192 {
193     volatile uint32_t response = 0;
194     uint8_t resp_sts;
195 
196     response = regs->RESP;
197 
198     *len = response & 0xFFFFu;
199     *tid = (response & RESPONSE_TID_BITMASK) >> RESPONSE_TID_BITPOS;
200 
201     resp_sts = (response & RESPONSE_ERR_STS_BITMASK) >> RESPONSE_ERR_STS_BITPOS;
202 
203     return resp_sts;
204 }
205 
206 /**
207  * @brief Reads the Response Buffer Level Value
208  *
209  * @param regs Pointer to controller registers
210  */
_i3c_tgt_response_sts_get(struct mec_i3c_sec_regs * regs,uint16_t * len,uint8_t * tid,bool * rx_response)211 uint8_t _i3c_tgt_response_sts_get(struct mec_i3c_sec_regs *regs, uint16_t *len, uint8_t *tid,
212                                   bool *rx_response)
213 {
214     volatile uint32_t response = 0;
215     uint8_t resp_sts, rx_rsp_bit;
216 
217     response = regs->RESP;
218 
219     *len = response & 0xFFFFu;
220     *tid = (response & RESPONSE_TID_TGT_BITMASK) >> RESPONSE_TID_BITPOS;
221 
222     resp_sts = (response & RESPONSE_ERR_STS_BITMASK) >> RESPONSE_ERR_STS_BITPOS;
223 
224     rx_rsp_bit = (response & RESPONSE_RX_RESP_BITMASK) >> RESPONSE_RX_RESP_BITPOS;
225 
226     if (rx_rsp_bit) {
227         *rx_response = true;
228     }
229 
230     return resp_sts;
231 }
232 
233 /**
234  * @brief
235  *
236  * @param regs Pointer to controller registers
237  */
_i3c_cmd_queue_threshold_set(struct mec_i3c_host_regs * regs,uint32_t val)238 void _i3c_cmd_queue_threshold_set(struct mec_i3c_host_regs *regs, uint32_t val)
239 {
240     regs->QUE_THLD_CTRL &= (uint32_t)~(0xFFu << QUEUE_THLD_CMD_QUEUE_BITPOS);
241     regs->QUE_THLD_CTRL |= (val << QUEUE_THLD_CMD_QUEUE_BITPOS);
242 }
243 
244 /**
245  * @brief
246  *
247  * @param regs Pointer to controller registers
248  */
_i3c_ibi_data_threshold_set(struct mec_i3c_host_regs * regs,uint32_t val)249 void _i3c_ibi_data_threshold_set(struct mec_i3c_host_regs *regs, uint32_t val)
250 {
251     regs->QUE_THLD_CTRL &= (uint32_t)~(0xFFu << QUEUE_THLD_IBI_DATA_BITPOS);
252     regs->QUE_THLD_CTRL |= (val << QUEUE_THLD_IBI_DATA_BITPOS);
253 }
254 
255 /**
256  * @brief
257  *
258  * @param regs Pointer to controller registers
259  */
_i3c_ibi_status_threshold_set(struct mec_i3c_host_regs * regs,uint32_t val)260 void _i3c_ibi_status_threshold_set(struct mec_i3c_host_regs *regs, uint32_t val)
261 {
262     regs->QUE_THLD_CTRL &= (uint32_t)~(0xFFu << QUEUE_THLD_IBI_STATUS_BITPOS);
263     regs->QUE_THLD_CTRL |= (val << QUEUE_THLD_IBI_STATUS_BITPOS);
264 }
265 
266 /**
267  * @brief
268  *
269  * @param regs Pointer to controller registers
270  */
_i3c_tx_buf_threshold_set(struct mec_i3c_host_regs * regs,uint32_t val)271 void _i3c_tx_buf_threshold_set(struct mec_i3c_host_regs *regs, uint32_t val)
272 {
273     regs->DB_THLD_CTRL &= (uint32_t)~(0xFFu << DATA_BUF_THLD_TX_FIFO_EMPTY_BITPOS);
274     regs->DB_THLD_CTRL |= (val << DATA_BUF_THLD_TX_FIFO_EMPTY_BITPOS);
275 }
276 
277 /**
278  * @brief
279  *
280  * @param regs Pointer to controller registers
281  */
_i3c_rx_buf_threshold_set(struct mec_i3c_host_regs * regs,uint32_t val)282 void _i3c_rx_buf_threshold_set(struct mec_i3c_host_regs *regs, uint32_t val)
283 {
284     regs->DB_THLD_CTRL &= (uint32_t)~(0xFFu << DATA_BUF_THLD_RX_FIFO_BITPOS);
285     regs->DB_THLD_CTRL |= (val << DATA_BUF_THLD_RX_FIFO_BITPOS);
286 }
287 
288 /**
289  * @brief
290  *
291  * @param regs Pointer to controller registers
292  */
_i3c_tx_start_threshold_set(struct mec_i3c_host_regs * regs,uint32_t val)293 void _i3c_tx_start_threshold_set(struct mec_i3c_host_regs *regs, uint32_t val)
294 {
295     regs->DB_THLD_CTRL &= (uint32_t)~(0xFFu << DATA_BUF_THLD_TX_FIFO_START_BITPOS);
296     regs->DB_THLD_CTRL |= (val << DATA_BUF_THLD_TX_FIFO_START_BITPOS);
297 }
298 
299 /**
300  * @brief
301  *
302  * @param regs Pointer to controller registers
303  */
_i3c_rx_start_threshold_set(struct mec_i3c_host_regs * regs,uint32_t val)304 void _i3c_rx_start_threshold_set(struct mec_i3c_host_regs *regs, uint32_t val)
305 {
306      regs->DB_THLD_CTRL &= ~(0xFF << DATA_BUF_THLD_RX_FIFO_START_BITPOS);
307      regs->DB_THLD_CTRL |= (val << DATA_BUF_THLD_RX_FIFO_START_BITPOS);
308 }
309 
310 /**
311  * @brief
312  *
313  * @param regs Pointer to controller registers
314  */
_i3c_notify_sir_reject(struct mec_i3c_host_regs * regs,bool opt)315 void _i3c_notify_sir_reject(struct mec_i3c_host_regs *regs, bool opt)
316 {
317     regs->IBI_QUE_CTRL = (opt << IBI_QUEUE_CTRL_SIR_REJ_BITPOS);
318 }
319 
320 /**
321  * @brief
322  *
323  * @param regs Pointer to controller registers
324  */
_i3c_notify_mr_reject(struct mec_i3c_host_regs * regs,bool opt)325 void _i3c_notify_mr_reject(struct mec_i3c_host_regs *regs, bool opt)
326 {
327     regs->IBI_QUE_CTRL = (opt << IBI_QUEUE_CTRL_MR_REJ_BITPOS);
328 }
329 
330 /**
331  * @brief
332  *
333  * @param regs Pointer to controller registers
334  */
_i3c_notify_hj_reject(struct mec_i3c_host_regs * regs,bool opt)335 void _i3c_notify_hj_reject(struct mec_i3c_host_regs *regs, bool opt)
336 {
337     regs->IBI_QUE_CTRL = (opt << IBI_QUEUE_CTRL_HJ_REJ_BITPOS);
338 }
339 
340 /**
341  * @brief Set the dynamic address of the controller
342  *
343  * @param regs Pointer to controller registers
344  * @param address 7-bit dynamic address
345  */
_i3c_dynamic_addr_set(struct mec_i3c_host_regs * regs,uint8_t address)346 void _i3c_dynamic_addr_set(struct mec_i3c_host_regs *regs, uint8_t address)
347 {
348     regs->DEV_ADDR = ((address & 0x7F) << DEVICE_ADDR_DYNAMIC_ADDR_BITPOS) |
349                      sbit_DEVICE_ADDR_DYNAMIC_ADDR_VALID;
350 }
351 
352 /**
353  * @brief Set the static address of the controller
354  *
355  * @param regs Pointer to controller registers
356  * @param address 7-bit static address
357  */
_i3c_static_addr_set(struct mec_i3c_host_regs * regs,uint8_t address)358 void _i3c_static_addr_set(struct mec_i3c_host_regs *regs, uint8_t address)
359 {
360     volatile uint32_t reg_val;
361 
362     reg_val = regs->DEV_ADDR;
363 
364     reg_val |= ((address & 0x7F) | sbit_DEVICE_ADDR_STATIC_ADDR_VALID);
365 
366     regs->DEV_ADDR = reg_val;
367 }
368 
369 /**
370  * @brief Set the operation mode of the controller
371  *
372  * @param regs Pointer to controller registers
373  * @param mode device mode - 0-Controller, 1-Target
374  */
_i3c_operation_mode_set(struct mec_i3c_host_regs * regs,uint8_t mode)375 void _i3c_operation_mode_set(struct mec_i3c_host_regs *regs, uint8_t mode)
376 {
377     regs->DEV_EXT_CTRL = mode & 0x1;
378 }
379 
380 /**
381  * @brief Enable the controller
382  *
383  * @param regs Pointer to controller registers
384  * @param mode device mode - 0-Controller, 1-Target
385  */
_i3c_enable(struct mec_i3c_host_regs * regs,uint8_t mode,bool enable_dma)386 void _i3c_enable(struct mec_i3c_host_regs *regs, uint8_t mode, bool enable_dma)
387 {
388     uint32_t val;
389 
390     /* Read the control register */
391     val = regs->DEV_CTRL;
392 
393     val |= sbit_ENABLE;
394 
395     if (DEV_OPERATION_MODE_CTL == mode)
396     {
397         /* I3C Broadcast Address is included for private transfers */
398         val |= sbit_IBA_INCLUDE;
399     }
400 
401     if (enable_dma) {
402         val |= sbit_DMA_ENABLE;
403     }
404 
405     regs->DEV_CTRL = val;
406 }
407 
408 /**
409  * @brief Disable the controller
410  *
411  * @param regs Pointer to controller registers
412  */
_i3c_disable(struct mec_i3c_host_regs * regs)413 void _i3c_disable(struct mec_i3c_host_regs *regs)
414 {
415     volatile uint32_t val = 0;
416 
417     /* Read the control register */
418     val = regs->DEV_CTRL;
419 
420     val &= ~sbit_ENABLE;
421 
422     regs->DEV_CTRL = val;
423 }
424 
425 /**
426  * @brief Resume the controller
427  *
428  * @param regs Pointer to controller registers
429  */
_i3c_resume(struct mec_i3c_host_regs * regs)430 void _i3c_resume(struct mec_i3c_host_regs *regs)
431 {
432     regs->DEV_CTRL |= sbit_RESUME;
433 }
434 
435 /**
436  * @brief Clears transfer error status in Interrupt Status
437  *
438  * @param regs Pointer to controller registers
439  */
_i3c_xfer_err_sts_clr(struct mec_i3c_host_regs * regs)440 void _i3c_xfer_err_sts_clr(struct mec_i3c_host_regs *regs)
441 {
442     volatile uint32_t sts = 0;
443 
444     sts = regs->INTR_STS;
445 
446     if (sts & sbit_TRANSFER_ERR_STS) {
447         /* W1C */
448         regs->INTR_STS = sbit_TRANSFER_ERR_STS;
449     }
450 }
451 
452 /**
453  * @brief Disable hot join
454  * used in master mode of operation
455  *
456  * @param regs Pointer to controller registers
457  */
_i3c_hot_join_disable(struct mec_i3c_host_regs * regs)458 void _i3c_hot_join_disable(struct mec_i3c_host_regs *regs)
459 {
460     volatile uint32_t val = 0;
461 
462     /* Read the control register */
463     val = regs->DEV_CTRL;
464 
465     /* sbit_HOT_JOIN_CTRL = 1 for NACK and send broadcast CCC
466      * to disable Hot-join */
467     val |= sbit_HOT_JOIN_CTRL;
468 
469     regs->DEV_CTRL = val;
470 }
471 
472 /**
473  * @brief Disable hot join
474  * used in target mode of operation
475  *
476  * @param regs Pointer to secondary controller registers
477  */
_i3c_tgt_hot_join_disable(struct mec_i3c_sec_regs * regs)478 void _i3c_tgt_hot_join_disable(struct mec_i3c_sec_regs *regs)
479 {
480     volatile uint32_t val = 0;
481 
482     /* Read the target event status register */
483     val = regs->TGT_EVT_STS;
484 
485     val &= (uint32_t)~sbit_HJ_ENABLE;
486 
487     regs->DEV_CTRL = val;
488 }
489 
490 /**
491  * @brief Enable hot join
492  * used in master mode of operation
493  *
494  * @param regs Pointer to controller registers
495  */
_i3c_hot_join_enable(struct mec_i3c_host_regs * regs)496 void _i3c_hot_join_enable(struct mec_i3c_host_regs *regs)
497 {
498     volatile uint32_t val = 0;
499 
500     /* Read the control register */
501     val = regs->DEV_CTRL;
502 
503     /* sbit_HOT_JOIN_CTRL = 0 ACK Hot-Join requests */
504     val &= ~sbit_HOT_JOIN_CTRL;
505 
506     regs->DEV_CTRL = val;
507 }
508 
509 /**
510  * @brief Program I2C Fast Mode Timing Register
511  *
512  * @param regs Pointer to controller registers
513  * @param core_clk_freq_ns Core clock frequency in nanoseconds
514  */
_i2c_fm_timing_set(struct mec_i3c_host_regs * regs,uint32_t core_clk_freq_ns)515 void _i2c_fm_timing_set(struct mec_i3c_host_regs *regs, uint32_t core_clk_freq_ns)
516 {
517     uint16_t low_count, high_count;
518     uint32_t timing_val;
519 
520     high_count = (uint16_t)MEC_DIV_ROUND_UP(I2C_FM_SCL_MIN_HIGH_PERIOD_NS, core_clk_freq_ns);
521     if(high_count < I3C_SCL_TIMING_COUNT_MIN) {
522         high_count = I3C_SCL_TIMING_COUNT_MIN;
523     }
524 
525     low_count = (uint16_t)MEC_DIV_ROUND_UP(I2C_FM_SCL_MIN_LOW_PERIOD_NS, core_clk_freq_ns);
526     if(low_count < I3C_SCL_TIMING_COUNT_MIN) {
527         low_count = I3C_SCL_TIMING_COUNT_MIN;
528     }
529 
530     /* Program the I3C Push Pull Timing Register */
531     timing_val = (high_count << 16) | low_count;
532     regs->SCL_I2C_FM_TM = timing_val;
533 
534     /* This is a Mixed Bus system
535      * Hence program the Bus Free Time (Master Mode) to tLOW of I2C Timing
536      */
537     regs->BUS_FREE_TM = low_count;
538 }
539 
540 /**
541  * @brief Program the I3C Bus Free Timing Register
542  *
543  * @param regs Pointer to controller registers
544  * @param core_clk_freq_ns Core clock frequency in nanoseconds
545  */
_i3c_bus_free_timing_set(struct mec_i3c_sec_regs * regs,uint32_t core_clk_freq_ns)546 void _i3c_bus_free_timing_set(struct mec_i3c_sec_regs *regs, uint32_t core_clk_freq_ns)
547 {
548     uint32_t bus_free_timing_count;
549 
550     /* To review */
551     bus_free_timing_count = (uint32_t)MEC_DIV_ROUND_UP(TGT_BUS_FREE_DURATION_ns, core_clk_freq_ns);
552     if(bus_free_timing_count < I3C_SCL_TIMING_COUNT_MIN) {
553         bus_free_timing_count = I3C_SCL_TIMING_COUNT_MIN;
554     }
555 
556     regs->BUS_FREE_TM |= (bus_free_timing_count & 0xffffu);
557 }
558 
559 /**
560  * @brief Program the I3C Bus Free Timing Register
561  *
562  * @param regs Pointer to controller registers
563  * @param core_clk_freq_ns Core clock frequency in nanoseconds
564  */
_i3c_bus_available_timing_set(struct mec_i3c_sec_regs * regs,uint32_t core_clk_freq_ns)565 void _i3c_bus_available_timing_set(struct mec_i3c_sec_regs *regs, uint32_t core_clk_freq_ns)
566 {
567     uint32_t bus_avail_timing_count;
568 
569     bus_avail_timing_count = (uint32_t)MEC_DIV_ROUND_UP(TGT_BUS_AVAIL_COND_ns, core_clk_freq_ns);
570     if(bus_avail_timing_count < I3C_SCL_TIMING_COUNT_MIN) {
571         bus_avail_timing_count = I3C_SCL_TIMING_COUNT_MIN;
572     }
573 
574     regs->BUS_FREE_TM = (bus_avail_timing_count << 16);
575 }
576 
577 /**
578  * @brief Program the I3C Bus Free Timing Register
579  *
580  * @param regs Pointer to controller registers
581  * @param core_clk_freq_ns Core clock frequency in nanoseconds
582  */
_i3c_bus_idle_timing_set(struct mec_i3c_sec_regs * regs,uint32_t core_clk_freq_ns)583 void _i3c_bus_idle_timing_set(struct mec_i3c_sec_regs *regs, uint32_t core_clk_freq_ns)
584 {
585     uint32_t idle_count;
586 
587     idle_count = (uint32_t)MEC_DIV_ROUND_UP(TGT_BUS_IDLE_COND_ns, core_clk_freq_ns);
588     if(idle_count < I3C_SCL_TIMING_COUNT_MIN) {
589         idle_count = I3C_SCL_TIMING_COUNT_MIN;
590     }
591 
592     regs->BUS_IDLE_TM = idle_count;
593 }
594 
595 /**
596  * @brief Program the I3C SDA Hold Switch Timing Register
597  *
598  * @param regs Pointer to controller registers
599  * @param core_clk_freq_ns Core clock frequency in nanoseconds
600  */
_i3c_sda_hld_switch_delay_timing_set(struct mec_i3c_sec_regs * regs,uint8_t sda_od_pp_switch_dly,uint8_t sda_pp_od_switch_dly,uint8_t sda_tx_hold)601 void _i3c_sda_hld_switch_delay_timing_set(struct mec_i3c_sec_regs *regs,
602                                             uint8_t sda_od_pp_switch_dly,
603                                             uint8_t sda_pp_od_switch_dly,
604                                             uint8_t sda_tx_hold)
605 {
606     regs->SDA_HMSD_TM = (sda_od_pp_switch_dly << SDA_OD_PP_SWITCH_DLY_BITPOS);
607     regs->SDA_HMSD_TM |= (sda_pp_od_switch_dly << SDA_PP_OD_SWITCH_DLY_BITPOS);
608     regs->SDA_HMSD_TM |= (sda_tx_hold << SDA_TX_HOLD_BITPOS);
609 }
610 
611 /**
612  * @brief Program the I3C SDA Hold time control value
613  *
614  * @param regs Pointer to controller registers
615  * @param sda_tx_hold SDA TX Hold time control
616  */
_i3c_sda_hld_timing_set(struct mec_i3c_host_regs * regs,uint8_t sda_tx_hold)617 void _i3c_sda_hld_timing_set(struct mec_i3c_host_regs *regs,
618                                             uint8_t sda_tx_hold)
619 {
620     uint32_t reg_value = 0;
621 
622     reg_value = regs->SDA_HMSD_TM;
623     regs->SDA_HMSD_TM = (reg_value & 0xFFF8FFFF) | (sda_tx_hold << SDA_TX_HOLD_BITPOS);
624 }
625 
626 /**
627  * @brief Program the I3C read termination bit low count
628  *
629  * @param regs Pointer to controller registers
630  * @param sda_tx_hold SDA TX Hold time control
631  */
_i3c_read_term_bit_low_count_set(struct mec_i3c_host_regs * regs,uint8_t read_term_low_count)632 void _i3c_read_term_bit_low_count_set(struct mec_i3c_host_regs *regs,
633                                             uint8_t read_term_low_count)
634 {
635     uint32_t reg_value = 0;
636 
637     reg_value = regs->SCL_TBLC_TM;
638     regs->SCL_TBLC_TM = (reg_value & 0xFFFFFFF0) | (read_term_low_count);
639 }
640 
641 /**
642  * @brief Program the I3C SCL Low Master Extended Timeout register
643  *
644  * @param regs Pointer to controller registers
645  * @param core_clk_freq_ns Core clock frequency in nanoseconds
646  */
_i3c_scl_low_mst_tout_set(struct mec_i3c_sec_regs * regs,uint32_t tout_val)647 void _i3c_scl_low_mst_tout_set(struct mec_i3c_sec_regs *regs, uint32_t tout_val)
648 {
649     regs->SCL_LMST_TM = tout_val;
650 }
651 
652 /**
653  * @brief Inform the core that I2C targets are present on the bus
654  *
655  * @param regs Pointer to controller registers
656  */
_i2c_target_present_set(struct mec_i3c_host_regs * regs)657 void _i2c_target_present_set(struct mec_i3c_host_regs *regs)
658 {
659     regs->DEV_CTRL |= sbit_I2C_TGT_PRESENT;
660 }
661 
662 /**
663  * @brief Inform the core that I2C targets are not present on the bus
664  *
665  * @param regs Pointer to controller registers
666  */
_i2c_target_present_reset(struct mec_i3c_host_regs * regs)667 void _i2c_target_present_reset(struct mec_i3c_host_regs *regs)
668 {
669     regs->DEV_CTRL &= ~sbit_I2C_TGT_PRESENT;
670 }
671 
672 /**
673  * @brief Program I2C Fast Mode Plus Timing Register
674  *
675  * @param regs Pointer to controller registers
676  * @param core_clk_freq_ns Core clock frequency in nanoseconds
677  */
_i2c_fmp_timing_set(struct mec_i3c_host_regs * regs,uint32_t core_clk_freq_ns)678 void _i2c_fmp_timing_set(struct mec_i3c_host_regs *regs, uint32_t core_clk_freq_ns)
679 {
680     uint32_t low_count, high_count;
681     uint32_t timing_val;
682 
683     high_count = (uint32_t)MEC_DIV_ROUND_UP(I2C_FMP_SCL_MIN_HIGH_PERIOD_NS, core_clk_freq_ns);
684     if(high_count < I3C_SCL_TIMING_COUNT_MIN) {
685         high_count = I3C_SCL_TIMING_COUNT_MIN;
686     }
687 
688     low_count = (uint32_t)MEC_DIV_ROUND_UP(I2C_FMP_SCL_MIN_LOW_PERIOD_NS, core_clk_freq_ns);
689     if(low_count < I3C_SCL_TIMING_COUNT_MIN) {
690         low_count = I3C_SCL_TIMING_COUNT_MIN;
691     }
692 
693     /* Program the I3C Push Pull Timing Register */
694     timing_val = (high_count << 16) | low_count;
695     regs->SCL_I2C_FMP_TM = timing_val;
696 }
697 
698 /**
699  * @brief Program I3C Push Pull Timing Register
700  *
701  * @param regs Pointer to controller registers
702  * @param core_clk_freq_ns Core clock frequency in nanoseconds
703  */
_i3c_push_pull_timing_set(struct mec_i3c_host_regs * regs,uint32_t core_clk_freq_ns,uint32_t i3c_freq_ns)704 void _i3c_push_pull_timing_set(struct mec_i3c_host_regs *regs, uint32_t core_clk_freq_ns,
705                                uint32_t i3c_freq_ns)
706 {
707     uint32_t low_count = 0, high_count = 0, base_count = 0;
708     uint32_t timing_val = 0, sdr_ext_lcount = 0;
709 
710     base_count = (uint32_t)MEC_DIV_ROUND_UP(I3C_PUSH_PULL_SCL_MIN_HIGH_PERIOD_NS, core_clk_freq_ns);
711 
712     if(base_count < I3C_SCL_TIMING_COUNT_MIN) {
713         base_count = I3C_SCL_TIMING_COUNT_MIN;
714     }
715 
716     high_count = (uint32_t)MEC_DIV_ROUND_UP(base_count * i3c_freq_ns, I3C_SCL_12_5MHZ_PERIOD_NS);
717 
718     if(high_count < I3C_SCL_TIMING_COUNT_MIN) {
719         high_count = I3C_SCL_TIMING_COUNT_MIN;
720     }
721 
722     low_count = high_count;
723 
724     /* Program the I3C Push Pull Timing Register */
725     timing_val = (high_count << 16) | low_count;
726     regs->SCL_PP_TM = timing_val;
727 
728     /* If this is a PURE I3C bus
729      * Program the Bus Free Time (Master Mode) to tCAS parameter
730      */
731     if (!(regs->DEV_CTRL & sbit_I2C_TGT_PRESENT))
732     {
733         regs->BUS_FREE_TM = low_count;
734     }
735 
736     sdr_ext_lcount = MEC_DIV_ROUND_UP(I3C_BUS_SDR4_SCL_PERIOD_NS, core_clk_freq_ns) - high_count;
737     sdr_ext_lcount = sdr_ext_lcount << 8;
738     sdr_ext_lcount |= MEC_DIV_ROUND_UP(I3C_BUS_SDR3_SCL_PERIOD_NS, core_clk_freq_ns) - high_count;
739     sdr_ext_lcount = sdr_ext_lcount << 8;
740     sdr_ext_lcount |= MEC_DIV_ROUND_UP(I3C_BUS_SDR2_SCL_PERIOD_NS, core_clk_freq_ns) - high_count;
741     sdr_ext_lcount = sdr_ext_lcount << 8;
742     sdr_ext_lcount |= MEC_DIV_ROUND_UP(I3C_BUS_SDR1_SCL_PERIOD_NS, core_clk_freq_ns) - high_count;
743     sdr_ext_lcount = sdr_ext_lcount << 8;
744 
745     regs->SCL_ELC_TM = sdr_ext_lcount;
746 }
747 
748 /**
749  * @brief Program I3C Open Drain Timing Register
750  *
751  * @param regs Pointer to controller registers
752  * @param core_clk_freq_ns Core clock frequency in nanoseconds
753  */
_i3c_open_drain_timing_set(struct mec_i3c_host_regs * regs,uint32_t core_clk_freq_ns,uint32_t i3c_freq_ns)754 void _i3c_open_drain_timing_set(struct mec_i3c_host_regs *regs, uint32_t core_clk_freq_ns,
755                                 uint32_t i3c_freq_ns)
756 {
757     uint32_t low_count = 0, high_count = 0;
758     uint32_t timing_val;
759 
760     high_count = (uint32_t)MEC_DIV_ROUND_UP(I3C_OPEN_DRAIN_SCL_MIN_HIGH_PERIOD_NS, core_clk_freq_ns);
761 
762     high_count = (uint32_t)MEC_DIV_ROUND_UP(high_count * i3c_freq_ns, I3C_SCL_12_5MHZ_PERIOD_NS);
763 
764     if(high_count < I3C_SCL_TIMING_COUNT_MIN) {
765         high_count = I3C_SCL_TIMING_COUNT_MIN;
766     }
767 
768     low_count = (uint32_t)MEC_DIV_ROUND_UP(I3C_OPEN_DRAIN_SCL_MIN_LOW_PERIOD_NS, core_clk_freq_ns);
769 
770     low_count = (uint32_t)MEC_DIV_ROUND_UP(low_count * i3c_freq_ns, I3C_SCL_12_5MHZ_PERIOD_NS);
771 
772     if(low_count < I3C_SCL_TIMING_COUNT_MIN) {
773         low_count = I3C_SCL_TIMING_COUNT_MIN;
774     }
775 
776     /* Program the I3C Push Pull Timing Register */
777     timing_val = (high_count << 16) | low_count;
778     regs->SCL_OD_TM = timing_val;
779 }
780 
781 /**
782  * @brief
783  *
784  * @param regs Pointer to controller registers
785  */
_i3c_host_dma_tx_burst_length_set(struct mec_i3c_host_regs * regs,uint32_t val)786 void _i3c_host_dma_tx_burst_length_set(struct mec_i3c_host_regs *regs, uint32_t val)
787 {
788     regs->HOST_CFG &= (uint32_t)~(0x03u << HOST_CFG_DMA_TX_BURST_LENGTH_BIT_POS);
789     regs->HOST_CFG |= (val << HOST_CFG_DMA_TX_BURST_LENGTH_BIT_POS);
790 }
791 
792 /**
793  * @brief
794  *
795  * @param regs Pointer to controller registers
796  */
_i3c_host_dma_rx_burst_length_set(struct mec_i3c_host_regs * regs,uint32_t val)797 void _i3c_host_dma_rx_burst_length_set(struct mec_i3c_host_regs *regs, uint32_t val)
798 {
799     regs->HOST_CFG &= (uint32_t)~(0x03u << HOST_CFG_DMA_RX_BURST_LENGTH_BIT_POS);
800     regs->HOST_CFG |= (val << HOST_CFG_DMA_RX_BURST_LENGTH_BIT_POS);
801 }
802 
803 /**
804  * @brief
805  *
806  * @param regs Pointer to controller registers
807  */
_i3c_host_port_set(struct mec_i3c_host_regs * regs,uint32_t val)808 void _i3c_host_port_set(struct mec_i3c_host_regs *regs, uint32_t val)
809 {
810     regs->HOST_CFG &= (uint32_t)~(0x0Fu << HOST_CFG_PORT_SEL_BIT_POS);
811     regs->HOST_CFG |= (val << HOST_CFG_PORT_SEL_BIT_POS);
812 }
813 
814 /**
815  * @brief
816  *
817  * @param regs Pointer to controller registers
818  */
_i3c_host_stuck_sda_config(struct mec_i3c_host_regs * regs,uint32_t en,uint32_t tout_val)819 void _i3c_host_stuck_sda_config(struct mec_i3c_host_regs *regs, uint32_t en, uint32_t tout_val)
820 {
821     regs->HOST_CFG &= (uint32_t)~(0x01u << HOST_CFG_STUCK_SDA_EN_BIT_POS);
822     regs->HOST_CFG |= (en << HOST_CFG_STUCK_SDA_EN_BIT_POS);
823     if(en) {
824         regs->STK_SDA_TMOUT = tout_val;
825     } else {
826         regs->STK_SDA_TMOUT = 0U;
827     }
828 }
829 
830 /**
831  * @brief
832  *
833  * @param regs Pointer to controller registers
834  */
_i3c_host_tx_dma_tout_config(struct mec_i3c_host_regs * regs,uint32_t en,uint32_t tout_val)835 void _i3c_host_tx_dma_tout_config(struct mec_i3c_host_regs *regs, uint32_t en, uint32_t tout_val)
836 {
837     regs->HOST_CFG &= (uint32_t)~(0x01u << HOST_CFG_TX_DMA_TOUT_BITPOS);
838     regs->HOST_CFG |= (en << HOST_CFG_TX_DMA_TOUT_BITPOS);
839     if(en) {
840         regs->HOST_DMA_TX_TMOUT = tout_val;
841     } else {
842         regs->HOST_DMA_TX_TMOUT = 0U;
843     }
844 }
845 
846 /**
847  * @brief
848  *
849  * @param regs Pointer to controller registers
850  */
_i3c_host_rx_dma_tout_config(struct mec_i3c_host_regs * regs,uint32_t en,uint32_t tout_val)851 void _i3c_host_rx_dma_tout_config(struct mec_i3c_host_regs *regs, uint32_t en, uint32_t tout_val)
852 {
853     regs->HOST_CFG &= (uint32_t)~(0x01u << HOST_CFG_TX_DMA_TOUT_BITPOS);
854     regs->HOST_CFG |= (en << HOST_CFG_TX_DMA_TOUT_BITPOS);
855     if(en) {
856         regs->HOST_DMA_RX_TMOUT = tout_val;
857     } else {
858         regs->HOST_DMA_RX_TMOUT = 0U;
859     }
860 }
861 
862 /**
863  * @brief
864  *
865  * @param regs Pointer to controller registers
866  */
_i3c_sec_host_dma_tx_burst_length_set(struct mec_i3c_sec_regs * regs,uint32_t val)867 void _i3c_sec_host_dma_tx_burst_length_set(struct mec_i3c_sec_regs *regs, uint32_t val)
868 {
869     regs->SEC_CFG &= (uint32_t)~(0x03u << SEC_HOST_CFG_DMA_TX_BURST_LENGTH_BIT_POS);
870     regs->SEC_CFG |= (val << SEC_HOST_CFG_DMA_TX_BURST_LENGTH_BIT_POS);
871 }
872 
873 /**
874  * @brief
875  *
876  * @param regs Pointer to controller registers
877  */
_i3c_sec_host_dma_rx_burst_length_set(struct mec_i3c_sec_regs * regs,uint32_t val)878 void _i3c_sec_host_dma_rx_burst_length_set(struct mec_i3c_sec_regs *regs, uint32_t val)
879 {
880     regs->SEC_CFG &= (uint32_t)~(0x03u << SEC_HOST_CFG_DMA_RX_BURST_LENGTH_BIT_POS);
881     regs->SEC_CFG |= (val << SEC_HOST_CFG_DMA_RX_BURST_LENGTH_BIT_POS);
882 }
883 
884 /**
885  * @brief
886  *
887  * @param regs Pointer to controller registers
888  */
_i3c_sec_host_port_set(struct mec_i3c_sec_regs * regs,uint32_t val)889 void _i3c_sec_host_port_set(struct mec_i3c_sec_regs *regs, uint32_t val)
890 {
891     regs->SEC_CFG &= (uint32_t)~(0x0Fu << SEC_HOST_CFG_PORT_SEL_BIT_POS);
892     regs->SEC_CFG |= (val << SEC_HOST_CFG_PORT_SEL_BIT_POS);
893 }
894 
895 /**
896  * @brief
897  *
898  * @param regs Pointer to controller registers
899  */
_i3c_sec_host_stuck_sda_scl_config(struct mec_i3c_sec_regs * regs,uint32_t en,uint32_t sda_tout_val,uint32_t scl_tout_val)900 void _i3c_sec_host_stuck_sda_scl_config(struct mec_i3c_sec_regs *regs, uint32_t en,
901                                         uint32_t sda_tout_val, uint32_t scl_tout_val)
902 {
903     regs->SEC_CFG &= (uint32_t)~(0x01u << SEC_HOST_CFG_STUCK_SDA_EN_BIT_POS);
904     regs->SEC_CFG |= (en << SEC_HOST_CFG_STUCK_SDA_EN_BIT_POS);
905     if(en) {
906         regs->STK_SDA_TMOUT =
907             ((sda_tout_val & (uint32_t)MEC_GENMASK(9 , 0)) << SEC_HOST_CFG_STUCK_SDA_TOUT_BITPOS);
908         regs->STK_SDA_TMOUT =
909             ((scl_tout_val & (uint32_t)MEC_GENMASK(9 , 0)) << SEC_HOST_CFG_STUCK_SCL_TOUT_BITPOS);
910     } else {
911         regs->STK_SDA_TMOUT = 0U;
912     }
913 }
914 
915 /**
916  * @brief
917  *
918  * @param regs Pointer to controller registers
919  */
_i3c_sec_host_tx_dma_tout_config(struct mec_i3c_sec_regs * regs,uint32_t en,uint32_t tout_val)920 void _i3c_sec_host_tx_dma_tout_config(struct mec_i3c_sec_regs *regs, uint32_t en, uint32_t tout_val)
921 {
922     if(en) {
923         regs->HOST_DMA_TX_TMOUT = tout_val;
924     } else {
925         regs->HOST_DMA_TX_TMOUT = 0U;
926     }
927 }
928 
929 /**
930  * @brief
931  *
932  * @param regs Pointer to controller registers
933  */
_i3c_sec_host_rx_dma_tout_config(struct mec_i3c_sec_regs * regs,uint32_t en,uint32_t tout_val)934 void _i3c_sec_host_rx_dma_tout_config(struct mec_i3c_sec_regs *regs, uint32_t en, uint32_t tout_val)
935 {
936     if(en) {
937         regs->HOST_DMA_RX_TMOUT = tout_val;
938     } else {
939         regs->HOST_DMA_RX_TMOUT = 0U;
940     }
941 }
942 
943 /**
944  * @brief
945  *
946  * @param regs Pointer to controller registers
947  */
_i3c_sec_host_dma_fsm_enable(struct mec_i3c_sec_regs * regs)948 void _i3c_sec_host_dma_fsm_enable(struct mec_i3c_sec_regs *regs)
949 {
950     uint32_t bitmask;
951 
952     bitmask = (SEC_HOST_CFG_TX_DMA_FSM_ENABLE << SEC_HOST_CFG_TX_DMA_FSM_BITPOS) | \
953               (SEC_HOST_CFG_RX_DMA_FSM_ENABLE << SEC_HOST_CFG_RX_DMA_FSM_BITPOS);
954 
955     regs->SEC_CFG |= bitmask;
956 }
957 
958 /**
959  * @brief Read the Device Address Table Pointer Register
960  *
961  * @param regs Pointer to controller registers
962  * @param start_addr return the start address of device address table
963  * @param depth return the depth of device address table
964  */
_i3c_dev_addr_table_ptr_get(struct mec_i3c_host_regs * regs,uint16_t * start_addr,uint16_t * depth)965 void _i3c_dev_addr_table_ptr_get(struct mec_i3c_host_regs *regs, uint16_t *start_addr,
966                                  uint16_t *depth)
967 {
968     uint32_t val;
969 
970     val = regs->DAT_PTR;
971 
972     *start_addr = val & 0xFFFFu;
973     *depth = (uint16_t)((val >> 16) & 0xFFFFu);
974 }
975 
976 /**
977  * @brief Read the Device Characteristics Table Pointer Register
978  *
979  * @param regs Pointer to controller registers
980  * @param start_addr return the start address of device characteristics table
981  * @param depth return the depth of device characteristics table
982  */
_i3c_dev_char_table_ptr_get(struct mec_i3c_host_regs * regs,uint16_t * start_addr,uint16_t * depth)983 void _i3c_dev_char_table_ptr_get(struct mec_i3c_host_regs *regs, uint16_t *start_addr,
984                                  uint16_t *depth)
985 {
986     uint32_t val;
987 
988     val = regs->DCT_PTR;
989 
990     *start_addr = val & 0xFFFu; /* Bits 0 to 11 */
991     *depth = (val >> 12) & 0x7Fu; /* Bits 12 to 18 */
992 }
993 
994 /**
995  * @brief Retrieve the current operation of the the device
996  *
997  * @param regs Pointer to controller registers
998  */
_i3c_dev_operation_mode_get(struct mec_i3c_host_regs * regs)999 uint8_t _i3c_dev_operation_mode_get(struct mec_i3c_host_regs *regs)
1000 {
1001     return (uint8_t)(regs->DEV_EXT_CTRL & 0x03U);
1002 }
1003 
1004 /**
1005  * @brief Retrieve the current operation mode of the controller
1006  * (active or secondary)
1007  *
1008  * @param regs Pointer to controller registers
1009  */
_i3c_dev_controller_role_get(struct mec_i3c_host_regs * regs)1010 uint8_t _i3c_dev_controller_role_get(struct mec_i3c_host_regs *regs)
1011 {
1012     return (uint8_t)(regs->PRES_STATE & 0x04U);
1013 }
1014 
1015 /**
1016  * @brief Retrieve the HW configured role of the core
1017  * (controller only or secondary controller or target only)
1018  *
1019  * @param regs Pointer to controller registers
1020  */
_i3c_dev_role_config_get(struct mec_i3c_host_regs * regs)1021 uint8_t _i3c_dev_role_config_get(struct mec_i3c_host_regs *regs)
1022 {
1023     return (uint8_t)(regs->HW_CAP & 0x07U);
1024 }
1025 
1026 /**
1027  * @brief Writes the DAT entry
1028  *
1029  * @param regs Pointer to controller registers
1030  * @param DAT_start Start location of DAT
1031  * @param DAT_idx Position in the Device Address table
1032  * @param val 32-bit value to program
1033  */
_i3c_DAT_write(struct mec_i3c_host_regs * regs,uint16_t DAT_start,uint8_t DAT_idx,uint32_t val)1034 void _i3c_DAT_write(struct mec_i3c_host_regs *regs, uint16_t DAT_start, uint8_t DAT_idx,
1035                     uint32_t val)
1036 {
1037      uint32_t *entry_addr;
1038 
1039      entry_addr = (uint32_t *)((uint32_t)regs + ((uint32_t)DAT_start + ((uint32_t)DAT_idx * 4u)));
1040 
1041      *entry_addr = val;
1042 }
1043 
1044 /**
1045  * @brief Reads the DAT entry
1046  *
1047  * @param regs Pointer to controller registers
1048  * @param DAT_start Start location of DAT
1049  * @param DAT_idx Position in the Device Address table
1050  * @return val 32-bit DAT value
1051  */
_i3c_DAT_read(struct mec_i3c_host_regs * regs,uint16_t DAT_start,uint8_t DAT_idx)1052 uint32_t _i3c_DAT_read(struct mec_i3c_host_regs *regs, uint16_t DAT_start, uint8_t DAT_idx)
1053 {
1054      uint32_t *entry_addr;
1055      uint32_t val;
1056 
1057      entry_addr = (uint32_t *)((uint32_t)regs + ((uint32_t)DAT_start + ((uint32_t)DAT_idx * 4u)));
1058 
1059      val = *entry_addr;
1060 
1061      return val;
1062 }
1063 
1064 /**
1065  * @brief Read the DCT
1066  *
1067  * @param regs Pointer to controller registers
1068  * @param DAT_start Start location of DCT
1069  * @param DAT_idx Position in the Device Characteristics table
1070  * @param info DCT information read
1071  */
_i3c_DCT_read(struct mec_i3c_host_regs * regs,uint16_t DCT_start,uint8_t DCT_idx,struct mec_i3c_DCT_info * info)1072 void _i3c_DCT_read(struct mec_i3c_host_regs *regs, uint16_t DCT_start, uint8_t DCT_idx,
1073                    struct mec_i3c_DCT_info *info)
1074 {
1075      uint32_t *entry_addr;
1076      uint64_t prov_id = 0;
1077 
1078      entry_addr =
1079         (uint32_t *)((uint32_t)regs + ((uint32_t)DCT_start + ((uint32_t)DCT_idx * 4u * 4u)));
1080 
1081      prov_id = *entry_addr;
1082 
1083      entry_addr++;
1084      info->pid = (prov_id << 16) | (*entry_addr & 0xFFFF);
1085 
1086      entry_addr++;
1087      info->dcr = *entry_addr & 0xFF;
1088      info->bcr = (*entry_addr >> 8) & 0xFF;
1089 
1090      entry_addr++;
1091      info->dynamic_addr = *entry_addr & 0x7F;
1092 }
1093 
1094 /**
1095  * @brief Read the Secondary DCT
1096  *
1097  * @param regs Pointer to controller registers
1098  * @param DAT_start Start location of DCT
1099  * @param DAT_idx Position in the Device Characteristics table
1100  * @param info SDCT information read
1101  */
_i3c_SDCT_read(struct mec_i3c_host_regs * regs,uint16_t DCT_start,uint8_t idx,struct mec_i3c_SDCT_info * info)1102 void _i3c_SDCT_read(struct mec_i3c_host_regs *regs, uint16_t DCT_start, uint8_t idx,
1103                     struct mec_i3c_SDCT_info *info)
1104 {
1105      uint32_t *entry_addr;
1106      uint32_t sdct_val = 0;
1107 
1108      entry_addr = (uint32_t *)((uint32_t)regs + ((uint32_t)DCT_start + ((uint32_t)idx * 4u)));
1109 
1110      sdct_val = *entry_addr;
1111 
1112      info->dynamic_addr = sdct_val & 0xFFu;
1113      info->dcr = (sdct_val >> 8) & 0xFFu;
1114      info->bcr = (sdct_val >> 16) & 0xFFu;
1115      info->static_addr = (uint8_t)((sdct_val >> 24) & 0xFFu);
1116 }
1117 
1118 /**
1119  * @brief Write the FIFO with data
1120  *
1121  * @param regs Pointer to controller registers
1122  * @param buffer  buffer with data
1123  * @param len Length of data in the buffer
1124  */
_i3c_fifo_write(struct mec_i3c_host_regs * regs,uint8_t * buffer,uint16_t len)1125 void _i3c_fifo_write(struct mec_i3c_host_regs *regs, uint8_t *buffer, uint16_t len)
1126 {
1127     uint32_t *dword_ptr;
1128     uint32_t last_dword = 0;
1129     uint16_t i, remaining_bytes;
1130 
1131     if (len >= 4) {
1132 
1133         dword_ptr = (uint32_t *)buffer;
1134 
1135         for (i = 0; i < len / 4; i++) {
1136             regs->TX_DATA = dword_ptr[i];
1137         }
1138     }
1139 
1140     remaining_bytes = len % 4;
1141 
1142     if (remaining_bytes) {
1143         memcpy(&last_dword, buffer + (len & ~0x3), remaining_bytes);
1144         regs->TX_DATA = last_dword;
1145     }
1146 }
1147 
1148 /**
1149  * @brief Read from FIFO
1150  *
1151  * @param regs Pointer to controller registers
1152  * @param buffer  buffer to copy data
1153  * @param len Length of data to read
1154  */
_i3c_fifo_read(struct mec_i3c_host_regs * regs,uint8_t * buffer,uint16_t len)1155 void _i3c_fifo_read(struct mec_i3c_host_regs *regs, uint8_t *buffer, uint16_t len)
1156 {
1157     uint32_t *dword_ptr;
1158     uint32_t last_dword = 0;
1159     uint16_t i =0, remaining_bytes = 0;
1160 
1161     if (len >= 4) {
1162 
1163         dword_ptr = (uint32_t *)buffer;
1164 
1165         for (i = 0; i < len / 4; i++) {
1166             dword_ptr[i] = regs->RX_DATA;
1167         }
1168     }
1169 
1170     remaining_bytes = len % 4;
1171 
1172     if (remaining_bytes) {
1173         last_dword = regs->RX_DATA;
1174         memcpy(buffer + (len & ~0x3), &last_dword, remaining_bytes);
1175     }
1176 }
1177 
1178 /**
1179  * @brief Read from IBI Queue
1180  *
1181  * @param regs Pointer to controller registers
1182  * @param buffer  buffer to copy data
1183  * @param len Length of data to read
1184  */
_i3c_ibi_data_read(struct mec_i3c_host_regs * regs,uint8_t * buffer,uint16_t len)1185 void _i3c_ibi_data_read(struct mec_i3c_host_regs *regs, uint8_t *buffer, uint16_t len)
1186 {
1187     uint32_t *dword_ptr;
1188     uint32_t last_dword = 0;
1189     uint16_t i =0, remaining_bytes = 0;
1190     volatile uint32_t drain_dword;
1191     bool drain_flag = false;
1192 
1193     if (NULL == buffer) {
1194         drain_flag = true;
1195     }
1196 
1197     if (len >= 4) {
1198 
1199         if (drain_flag) {
1200             for (i = 0; i < len / 4; i++) {
1201                 drain_dword |= regs->IBI_QUE_STS;
1202             }
1203         } else {
1204             dword_ptr = (uint32_t *)buffer;
1205 
1206             for (i = 0; i < len / 4; i++) {
1207                 dword_ptr[i] = regs->IBI_QUE_STS;
1208             }
1209         }
1210     }
1211 
1212     remaining_bytes = len % 4;
1213 
1214     if (remaining_bytes) {
1215         last_dword = regs->IBI_QUE_STS;
1216         if (!drain_flag) {
1217             memcpy(buffer + (len & ~0x3), &last_dword, remaining_bytes);
1218         }
1219     }
1220 }
1221 
1222 /**
1223  * @brief Reset all transfers
1224  *
1225  * @param regs Pointer to controller registers
1226  */
_i3c_xfers_reset(struct mec_i3c_host_regs * regs)1227 void _i3c_xfers_reset(struct mec_i3c_host_regs *regs)
1228 {
1229     volatile uint32_t reg_val = 1;
1230 
1231     regs->RST_CTRL = RESET_CTRL_RX_FIFO_RST | RESET_CTRL_TX_FIFO_RST |
1232                         RESET_CTRL_RES_Q_RST | RESET_CTRL_CMD_Q_RST;
1233 
1234     while (reg_val) {
1235         reg_val = regs->RST_CTRL;
1236     }
1237 }
1238 
1239 /**
1240  * @brief clears residual data by flushing transmit fifo
1241  *
1242  * @param regs Pointer to controller registers
1243  */
_i3c_tx_fifo_rst(struct mec_i3c_host_regs * regs)1244 void _i3c_tx_fifo_rst(struct mec_i3c_host_regs *regs)
1245 {
1246     regs->RST_CTRL = RESET_CTRL_TX_FIFO_RST;
1247 }
1248 
1249 /**
1250  * @brief resets RX Fifo
1251  *
1252  * @param regs Pointer to controller registers
1253  */
_i3c_rx_fifo_rst(struct mec_i3c_host_regs * regs)1254 void _i3c_rx_fifo_rst(struct mec_i3c_host_regs *regs)
1255 {
1256     regs->RST_CTRL = RESET_CTRL_RX_FIFO_RST;
1257 }
1258 
1259 /**
1260  * @brief Resets Command Queue
1261  *
1262  * @param regs Pointer to controller registers
1263  */
_i3c_cmd_queue_rst(struct mec_i3c_host_regs * regs)1264 void _i3c_cmd_queue_rst(struct mec_i3c_host_regs *regs)
1265 {
1266     regs->RST_CTRL = RESET_CTRL_CMD_Q_RST;
1267 }
1268 
1269 /**
1270  * @brief I3C core software reset
1271  *
1272  * @param regs Pointer to controller registers
1273  */
_i3c_soft_reset(struct mec_i3c_host_regs * regs)1274 void _i3c_soft_reset(struct mec_i3c_host_regs *regs)
1275 {
1276     volatile uint32_t reg_val = 1;
1277 
1278     regs->RST_CTRL = RESET_CTRL_SOFT_RST;
1279 
1280     while (reg_val & RESET_CTRL_SOFT_RST) {
1281         reg_val = regs->RST_CTRL;
1282     }
1283 }
1284 /**
1285  * @brief Write the command in the Command Queue Port
1286  *
1287  * @param regs Pointer to controller registers
1288  * @param cmd  The Command
1289   */
_i3c_command_write(struct mec_i3c_host_regs * regs,uint32_t cmd)1290 void _i3c_command_write(struct mec_i3c_host_regs *regs, uint32_t cmd)
1291 {
1292     regs->CMD = cmd;
1293 }
1294 
1295 /**
1296  * @brief Retrieve the depth of the TX FIFO
1297  * in bytes
1298  */
_i3c_tx_fifo_depth_get(struct mec_i3c_host_regs * regs)1299 uint8_t _i3c_tx_fifo_depth_get(struct mec_i3c_host_regs *regs)
1300 {
1301     return (uint8_t)((FIFO_DEPTH_MIN_DWORD << ((regs->QUE_SIZE_CAP & MEC_GENMASK(3, 0)) >> Q_CAP_TX_FIFO_DEPTH_BITPOS)) * 4u);
1302 }
1303 
1304 /**
1305  * @brief Retrieve the depth of the RX FIFO
1306  * in bytes
1307  */
_i3c_rx_fifo_depth_get(struct mec_i3c_host_regs * regs)1308 uint8_t _i3c_rx_fifo_depth_get(struct mec_i3c_host_regs *regs)
1309 {
1310     return (uint8_t)((FIFO_DEPTH_MIN_DWORD << ((regs->QUE_SIZE_CAP & MEC_GENMASK(7, 4)) >> Q_CAP_RX_FIFO_DEPTH_BITPOS)) * 4u);
1311 }
1312 
1313 /**
1314  * @brief Retrieve the depth of the command FIFO
1315  * in bytes
1316  */
_i3c_cmd_fifo_depth_get(struct mec_i3c_host_regs * regs)1317 uint8_t _i3c_cmd_fifo_depth_get(struct mec_i3c_host_regs *regs)
1318 {
1319     return (uint8_t)(FIFO_DEPTH_MIN_DWORD << ((regs->QUE_SIZE_CAP & MEC_GENMASK(11, 8)) >> Q_CAP_CMD_FIFO_DEPTH_BITPOS));
1320 }
1321 
1322 /**
1323  * @brief Retrieve the depth of the response FIFO
1324  * in bytes
1325  */
_i3c_resp_fifo_depth_get(struct mec_i3c_host_regs * regs)1326 uint8_t _i3c_resp_fifo_depth_get(struct mec_i3c_host_regs *regs)
1327 {
1328     return (uint8_t)(FIFO_DEPTH_MIN_DWORD << ((regs->QUE_SIZE_CAP & MEC_GENMASK(15, 12)) >> Q_CAP_RESP_FIFO_DEPTH_BITPOS));
1329 }
1330 
1331 /**
1332  * @brief Retrieve the depth of the IBI FIFO
1333  * in bytes
1334  */
_i3c_ibi_fifo_depth_get(struct mec_i3c_host_regs * regs)1335 uint8_t _i3c_ibi_fifo_depth_get(struct mec_i3c_host_regs *regs)
1336 {
1337     return (uint8_t)(FIFO_DEPTH_MIN_DWORD << ((regs->QUE_SIZE_CAP & MEC_GENMASK(19, 16)) >> Q_CAP_IBI_FIFO_DEPTH_BITPOS));
1338 }
1339 
1340 /**
1341  * @brief Set the PID of secondary controller (in target mode)
1342  */
_i3c_tgt_pid_set(struct mec_i3c_sec_regs * regs,uint16_t tgt_mipi_mfg_id,bool is_random_prov_id,uint16_t tgt_part_id,uint8_t tgt_inst_id,uint16_t tgt_pid_dcr)1343 void _i3c_tgt_pid_set(struct mec_i3c_sec_regs *regs,
1344                         uint16_t tgt_mipi_mfg_id,
1345                         bool is_random_prov_id,
1346                         uint16_t tgt_part_id,
1347                         uint8_t tgt_inst_id,
1348                         uint16_t tgt_pid_dcr)
1349 {
1350     regs->MIPI_MAN_ID = (tgt_mipi_mfg_id << TGT_MIPI_MFG_ID_BITPOS);
1351 
1352     if(false == is_random_prov_id) {
1353         regs->NORM_PROV_ID = (tgt_part_id << TGT_PART_ID_BITPOS) |
1354                             (tgt_inst_id << TGT_INST_ID_BITPOS) |
1355                             (tgt_pid_dcr << TGT_PID_DCR_BITPOS);
1356     }
1357 }
1358 
1359 /**
1360  * @brief Get the Dynamic address valid bit
1361  * of secondary controller (in target mode)
1362  */
_i3c_tgt_dyn_addr_valid_get(struct mec_i3c_sec_regs * regs)1363 bool _i3c_tgt_dyn_addr_valid_get(struct mec_i3c_sec_regs *regs)
1364 {
1365     return (bool)(regs->DEV_ADDR & sbit_DEVICE_ADDR_DYNAMIC_ADDR_VALID);
1366 }
1367 
1368 /**
1369  * @brief Get the Dynamic address
1370  * of secondary controller (in target mode)
1371  */
_i3c_tgt_dyn_addr_get(struct mec_i3c_sec_regs * regs)1372 uint8_t _i3c_tgt_dyn_addr_get(struct mec_i3c_sec_regs *regs)
1373 {
1374     return (uint8_t)((regs->DEV_ADDR & MEC_GENMASK(22, 16)) >> DEVICE_ADDR_DYNAMIC_ADDR_BITPOS);
1375 }
1376 
1377 /**
1378  * @brief Set the MRL of secondary controller (in target mode)
1379  */
_i3c_tgt_mrl_set(struct mec_i3c_sec_regs * regs,uint16_t mrl)1380 void _i3c_tgt_mrl_set(struct mec_i3c_sec_regs *regs, uint16_t mrl)
1381 {
1382     regs->MAX_RW_LEN = (regs->MAX_RW_LEN & ~(MEC_GENMASK(31, 16))) | (mrl << MRL_BITPOS);
1383 }
1384 
1385 /**
1386  * @brief Set the MWL of secondary controller (in target mode)
1387  */
_i3c_tgt_mwl_set(struct mec_i3c_sec_regs * regs,uint16_t mwl)1388 void _i3c_tgt_mwl_set(struct mec_i3c_sec_regs *regs, uint16_t mwl)
1389 {
1390     regs->MAX_RW_LEN = (regs->MAX_RW_LEN & ~(MEC_GENMASK(15, 0))) | (mwl << MWL_BITPOS);
1391 }
1392 
1393 /**
1394  * @brief Set the MXDS value of secondary controller (in target mode)
1395  */
_i3c_tgt_mxds_set(struct mec_i3c_sec_regs * regs,uint8_t wr_speed,uint8_t rd_speed,uint8_t tsco,uint32_t rd_trnd_us)1396 void _i3c_tgt_mxds_set(struct mec_i3c_sec_regs *regs,
1397                         uint8_t wr_speed,
1398                         uint8_t rd_speed,
1399                         uint8_t tsco,
1400                         uint32_t rd_trnd_us)
1401 {
1402     regs->MAX_DS = (wr_speed << MXDS_MAX_WR_SPEED_BITPOS) |
1403                             (rd_speed << MXDS_MAX_RD_SPEED_BITPOS) |
1404                             (tsco << MXDS_TSCO_BITPOS);
1405     regs->MAX_RD_TAR = MXDS_MAX_RD_TURN_MASK(rd_trnd_us);
1406 }
1407 
1408 /**
1409  * @brief Check if SIR is enabled by the controller
1410  */
_i3c_tgt_SIR_enabled(struct mec_i3c_sec_regs * regs)1411 bool _i3c_tgt_SIR_enabled(struct mec_i3c_sec_regs *regs)
1412 {
1413     bool ret = false;
1414     if (regs->TGT_EVT_STS & TGT_EVT_STS_SIR_EN) {
1415         ret = true;
1416     }
1417 
1418     return ret;
1419 }
1420 
1421 /**
1422  * @brief Check if SIR is enabled by the controller
1423  */
_i3c_tgt_MR_enabled(struct mec_i3c_sec_regs * regs)1424 bool _i3c_tgt_MR_enabled(struct mec_i3c_sec_regs *regs)
1425 {
1426     bool ret = false;
1427     if (regs->TGT_EVT_STS & TGT_EVT_STS_MIR_EN) {
1428         ret = true;
1429     }
1430 
1431     return ret;
1432 }
1433 
1434 /**
1435  * @brief Raise IBI Target Interrupt Request (SIR)
1436  */
_i3c_tgt_raise_ibi_SIR(struct mec_i3c_sec_regs * regs,uint8_t * sir_data,uint8_t sir_datalen,uint8_t mdb)1437 void _i3c_tgt_raise_ibi_SIR(struct mec_i3c_sec_regs *regs, uint8_t *sir_data, uint8_t sir_datalen,
1438                             uint8_t mdb)
1439 {
1440     uint32_t sir_data_dword = 0;
1441 
1442     regs->TARG_IREQ = (mdb << TGT_INTR_REQ_MDB_BITPOS) |
1443                         (sir_datalen << TGT_INTR_REQ_SIR_DATALEN_BITPOS);
1444 
1445     if (sir_datalen ) {
1446         for (int i = 0; i < sir_datalen; i++) {
1447             sir_data_dword <<= 8;
1448             sir_data_dword |= sir_data[i];
1449         }
1450         regs->TARG_IREQ_DATA = sir_data_dword;
1451     }
1452     regs->TARG_IREQ |= TGT_INTR_REQ_SIR;
1453 }
1454 
1455 /**
1456  * @brief Raise IBI Master Request (MR)
1457  */
_i3c_tgt_raise_ibi_MR(struct mec_i3c_sec_regs * regs)1458 void _i3c_tgt_raise_ibi_MR(struct mec_i3c_sec_regs *regs)
1459 {
1460     regs->TARG_IREQ = TGT_INTR_REQ_MR;
1461 
1462     /* Enable ACK for GETACCMST CCC from master */
1463     regs->DEV_EXT_CTRL &= ~(DEV_REQMST_ACK_CTRL_NACK);
1464 }
1465 
1466 /**
1467  * @brief Retrieve the IBI response from IBI Response register
1468  */
_i3c_tgt_ibi_resp_get(struct mec_i3c_sec_regs * regs,uint8_t * sir_rem_datalen)1469 bool _i3c_tgt_ibi_resp_get(struct mec_i3c_sec_regs *regs, uint8_t *sir_rem_datalen)
1470 {
1471     bool ret = false;
1472     /* Databook mentions SIR RESP DATA LENGTH as bits 8 t0 23, but we are using only
1473      * 8 bits because IBI Datalen is not supposed to be more than 4
1474      */
1475     *sir_rem_datalen = (regs->TARG_IBI_RESP >>  TGT_IBI_RESP_DATALEN_BITPOS) & 0xFF;
1476 
1477     if (TGT_IBI_RESP_SUCCESS == (regs->TARG_IBI_RESP & 0x3)) {
1478             ret = true;
1479     }
1480 
1481     return ret;
1482 }
1483 
1484 /**
1485  * @brief Retrieve target max read length
1486  */
_i3c_tgt_MRL_get(struct mec_i3c_sec_regs * regs,uint16_t * max_rd_len)1487 void _i3c_tgt_MRL_get(struct mec_i3c_sec_regs *regs, uint16_t *max_rd_len)
1488 {
1489     *max_rd_len = (uint16_t)(regs->MAX_RW_LEN >> 16);
1490 }
1491 
1492 /**
1493  * @brief Retrieve target max write length
1494  */
_i3c_tgt_MWL_get(struct mec_i3c_sec_regs * regs,uint16_t * max_wr_len)1495 void _i3c_tgt_MWL_get(struct mec_i3c_sec_regs *regs, uint16_t *max_wr_len)
1496 {
1497     *max_wr_len = (uint16_t)(regs->MAX_RW_LEN & 0xFFFF);
1498 }
1499 
1500 /**
1501  * @brief Set target max read and write length
1502  */
_i3c_tgt_MRL_MWL_set(struct mec_i3c_sec_regs * regs,uint16_t max_rd_len,uint16_t max_wr_len)1503 void _i3c_tgt_MRL_MWL_set(struct mec_i3c_sec_regs *regs, uint16_t max_rd_len, uint16_t max_wr_len)
1504 {
1505     regs->MAX_RW_LEN  = ((uint32_t)max_rd_len << 16) | max_wr_len;
1506 }
1507 
1508 /**
1509  * @brief Retrieve target max write length
1510  */
_i3c_tgt_MWL_set(struct mec_i3c_sec_regs * regs,uint16_t * max_wr_len)1511 void _i3c_tgt_MWL_set(struct mec_i3c_sec_regs *regs, uint16_t *max_wr_len)
1512 {
1513     *max_wr_len = (uint16_t)(regs->MAX_RW_LEN & 0xFFFFu);
1514 }
1515 
1516 /**
1517  * @brief Returns true if controller updated MRL
1518  */
_i3c_tgt_MRL_updated(struct mec_i3c_sec_regs * regs)1519 bool _i3c_tgt_MRL_updated(struct mec_i3c_sec_regs *regs)
1520 {
1521     bool ret = false;
1522 
1523     if (regs->TGT_EVT_STS & TGT_EVT_STS_MRL_UPDATED)    {
1524         ret = true;
1525         /* Write 1 to clear */
1526         regs->TGT_EVT_STS = TGT_EVT_STS_MRL_UPDATED;
1527     }
1528 
1529     return ret;
1530 }
1531 
1532 /**
1533  * @brief Returns true if controller updated MWL
1534  */
_i3c_tgt_MWL_updated(struct mec_i3c_sec_regs * regs)1535 bool _i3c_tgt_MWL_updated(struct mec_i3c_sec_regs *regs)
1536 {
1537     bool ret = false;
1538 
1539     if (regs->TGT_EVT_STS & TGT_EVT_STS_MWL_UPDATED)    {
1540         ret = true;
1541         /* Write 1 to clear */
1542         regs->TGT_EVT_STS = TGT_EVT_STS_MWL_UPDATED;
1543     }
1544 
1545     return ret;
1546 }
1547 
1548 /**
1549  * @brief Set target max read and write speed
1550  */
_i3c_tgt_max_speed_update(struct mec_i3c_sec_regs * regs,uint8_t max_rd_speed,uint8_t max_wr_speed)1551 void _i3c_tgt_max_speed_update(struct mec_i3c_sec_regs *regs, uint8_t max_rd_speed,
1552                                uint8_t max_wr_speed)
1553 {
1554     regs->MAX_DS &= (uint32_t)~(TGT_MAX_WR_DATA_SPEED_MASK << TGT_MAX_WR_DATA_SPEED_POS);
1555     regs->MAX_DS &= (uint32_t)~(TGT_MAX_RD_DATA_SPEED_MASK << TGT_MAX_RD_DATA_SPEED_POS);
1556 
1557     regs->MAX_DS |= (max_wr_speed << TGT_MAX_WR_DATA_SPEED_POS);
1558     regs->MAX_DS |= (max_rd_speed << TGT_MAX_RD_DATA_SPEED_POS);
1559 }
1560 
1561 /**
1562  * @brief Set target max read and write speed
1563  */
_i3c_tgt_clk_to_data_turn_update(struct mec_i3c_sec_regs * regs,uint8_t clk_data_turn_time)1564 void _i3c_tgt_clk_to_data_turn_update(struct mec_i3c_sec_regs *regs, uint8_t clk_data_turn_time)
1565 {
1566     regs->MAX_DS &= (uint32_t)~(TGT_CLK_TO_DATA_TURN_MASK << TGT_CLK_TO_DATA_TURN_POS);
1567 
1568     regs->MAX_DS |= ((uint32_t)clk_data_turn_time << TGT_CLK_TO_DATA_TURN_POS);
1569 }
1570