Lines Matching +full:fifo +full:- +full:depth
4 * SPDX-License-Identifier: Apache-2.0
472 /* Target T_LOW period in open-drain mode. */
482 /* command response fifo threshold */
484 /* command tx fifo threshold - unused */
486 /* in-band-interrupt data fifo threshold - unused */
488 /* in-band-interrupt response queue threshold */
490 /* tx data threshold - unused */
504 /* The maxiumum command queue depth. */
506 /* The maxiumum command response queue depth. */
508 /* The maximum RX FIFO depth. */
510 /* The maximum TX FIFO depth. */
512 /* The maximum DDR RX FIFO depth. */
514 /* The maximum DDR TX FIFO depth. */
516 /* The maximum IBIR FIFO depth. */
518 /* The maximum IBI FIFO depth. */
611 for (i = 15; i >= 0; --i) { in i3c_cdns_crc5()
660 /* Returns [7:1] 7-bit addr, [0] even/xor parity */
668 b = b & (b - 1); in cdns_i3c_even_parity_byte()
675 /* Check if command response fifo is empty */
678 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_cmd_rsp_fifo_empty()
683 /* Check if command fifo is empty */
686 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_cmd_fifo_empty()
691 /* Check if command fifo is full */
694 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_cmd_fifo_full()
699 /* Check if ibi response fifo is empty */
702 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_ibi_rsp_fifo_empty()
707 /* Check if tx fifo is full */
710 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_tx_fifo_full()
715 /* Check if rx fifo is full */
718 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_rx_fifo_full()
723 /* Check if rx fifo is empty */
726 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_rx_fifo_empty()
731 /* Check if ibi fifo is empty */
734 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_ibi_fifo_empty()
742 sys_write32(MST_INT_MASK, config->base + MST_IDR); in cdns_i3c_interrupts_disable()
747 sys_write32(MST_INT_MASK, config->base + MST_ICR); in cdns_i3c_interrupts_clear()
750 /* FIFO mgmt */
757 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_write_tx_fifo()
759 sys_write32(val, config->base + TX_FIFO); in cdns_i3c_write_tx_fifo()
765 sys_write32(val, config->base + TX_FIFO); in cdns_i3c_write_tx_fifo()
775 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_write_ddr_tx_fifo()
777 sys_write32(val, config->base + SLV_DDR_TX_FIFO); in cdns_i3c_write_ddr_tx_fifo()
783 sys_write32(val, config->base + SLV_DDR_TX_FIFO); in cdns_i3c_write_ddr_tx_fifo()
794 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_write_ibi_fifo()
796 sys_write32(val, config->base + IBI_DATA_FIFO); in cdns_i3c_write_ibi_fifo()
802 sys_write32(val, config->base + IBI_DATA_FIFO); in cdns_i3c_write_ibi_fifo()
809 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_read_rx_fifo()
810 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_read_rx_fifo()
811 const struct i3c_target_callbacks *target_cb = data->target_config->callbacks; in cdns_i3c_target_read_rx_fifo()
813 /* Version 1p7 uses the full 32b FIFO width */ in cdns_i3c_target_read_rx_fifo()
814 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_read_rx_fifo()
816 SLV_STATUS0_XFRD_BYTES(sys_read32(config->base + SLV_STATUS0)); in cdns_i3c_target_read_rx_fifo()
818 for (int i = data->fifo_bytes_read; i < xferred_bytes; i += 4) { in cdns_i3c_target_read_rx_fifo()
819 uint32_t rx_data = sys_read32(config->base + RX_FIFO); in cdns_i3c_target_read_rx_fifo()
821 for (int j = 0; j < MIN(4, xferred_bytes - i); j++) { in cdns_i3c_target_read_rx_fifo()
822 target_cb->write_received_cb(data->target_config, in cdns_i3c_target_read_rx_fifo()
830 data->fifo_bytes_read = xferred_bytes; in cdns_i3c_target_read_rx_fifo()
834 * width fifo for older version in cdns_i3c_target_read_rx_fifo()
836 uint8_t rx_data = (uint8_t)sys_read32(config->base + RX_FIFO); in cdns_i3c_target_read_rx_fifo()
838 target_cb->write_received_cb(data->target_config, rx_data); in cdns_i3c_target_read_rx_fifo()
847 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_read_rx_fifo()
849 return -EIO; in cdns_i3c_read_rx_fifo()
851 val = sys_le32_to_cpu(sys_read32(config->base + RX_FIFO)); in cdns_i3c_read_rx_fifo()
857 return -EIO; in cdns_i3c_read_rx_fifo()
859 val = sys_le32_to_cpu(sys_read32(config->base + RX_FIFO)); in cdns_i3c_read_rx_fifo()
876 * whole packet to be within the FIFO and not split across multiple calls to this function. in cdns_i3c_read_rx_fifo_ddr_xfer()
882 return -EIO; in cdns_i3c_read_rx_fifo_ddr_xfer()
884 val = sys_read32(config->base + RX_FIFO); in cdns_i3c_read_rx_fifo_ddr_xfer()
897 return -EIO; in cdns_i3c_read_rx_fifo_ddr_xfer()
907 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_wait_for_idle()
915 while (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_IDLE)) { in cdns_i3c_wait_for_idle()
916 if (k_cycle_get_32() - start_time > I3C_IDLE_TIMEOUT_CYC) { in cdns_i3c_wait_for_idle()
917 return -EAGAIN; in cdns_i3c_wait_for_idle()
926 struct cdns_i3c_data *data = dev->data; in cdns_i3c_set_prescalers()
927 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_set_prescalers()
928 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_set_prescalers()
931 uint32_t prescl_i3c = DIV_ROUND_UP(config->input_frequency, in cdns_i3c_set_prescalers()
932 (ctrl_config->scl.i3c * I3C_PRESCL_REG_SCALE)) - in cdns_i3c_set_prescalers()
934 uint32_t prescl_i2c = DIV_ROUND_UP(config->input_frequency, in cdns_i3c_set_prescalers()
935 (ctrl_config->scl.i2c * I2C_PRESCL_REG_SCALE)) - in cdns_i3c_set_prescalers()
939 ctrl_config->scl.i3c = config->input_frequency / ((prescl_i3c + 1) * I3C_PRESCL_REG_SCALE); in cdns_i3c_set_prescalers()
940 ctrl_config->scl.i2c = config->input_frequency / ((prescl_i2c + 1) * I2C_PRESCL_REG_SCALE); in cdns_i3c_set_prescalers()
942 LOG_DBG("%s: I3C speed = %u, PRESCL_CTRL0.i3c = 0x%x", dev->name, ctrl_config->scl.i3c, in cdns_i3c_set_prescalers()
944 LOG_DBG("%s: I2C speed = %u, PRESCL_CTRL0.i2c = 0x%x", dev->name, ctrl_config->scl.i2c, in cdns_i3c_set_prescalers()
948 uint32_t pres_step = 1000000000 / (ctrl_config->scl.i3c * 4); in cdns_i3c_set_prescalers()
949 int32_t od_low = DIV_ROUND_UP(I3C_BUS_TLOW_OD_MIN_NS, pres_step) - 2; in cdns_i3c_set_prescalers()
954 LOG_DBG("%s: PRESCL_CTRL1.od_low = 0x%x", dev->name, od_low); in cdns_i3c_set_prescalers()
957 uint32_t ctrl = sys_read32(config->base + CTRL); in cdns_i3c_set_prescalers()
960 sys_write32(~CTRL_DEV_EN & ctrl, config->base + CTRL); in cdns_i3c_set_prescalers()
964 config->base + PRESCL_CTRL0); in cdns_i3c_set_prescalers()
966 /* Sets the open drain low time relative to the push-pull. */ in cdns_i3c_set_prescalers()
968 config->base + PRESCL_CTRL1); in cdns_i3c_set_prescalers()
972 sys_write32(CTRL_DEV_EN | ctrl, config->base + CTRL); in cdns_i3c_set_prescalers()
1007 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_program_controller_retaining_reg()
1008 struct cdns_i3c_data *data = dev->data; in cdns_i3c_program_controller_retaining_reg()
1012 if (!i3c_addr_slots_is_free(&data->common.attached_dev.addr_slots, controller_da)) { in cdns_i3c_program_controller_retaining_reg()
1014 i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots, 0); in cdns_i3c_program_controller_retaining_reg()
1015 LOG_DBG("%s: 0x%02x DA selected for controller", dev->name, controller_da); in cdns_i3c_program_controller_retaining_reg()
1017 sys_write32(prepare_rr0_dev_address(controller_da), config->base + DEV_ID_RR0(0)); in cdns_i3c_program_controller_retaining_reg()
1019 i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, controller_da); in cdns_i3c_program_controller_retaining_reg()
1027 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_controller_ibi_enable()
1028 struct cdns_i3c_i2c_dev_data *cdns_i3c_device_data = target->controller_priv; in cdns_i3c_controller_ibi_enable()
1033 ret = -EINVAL; in cdns_i3c_controller_ibi_enable()
1039 sir_cfg = SIR_MAP_DEV_ROLE(I3C_BCR_DEVICE_ROLE(target->bcr)) | in cdns_i3c_controller_ibi_enable()
1040 SIR_MAP_DEV_DA(target->dynamic_addr) | in cdns_i3c_controller_ibi_enable()
1041 SIR_MAP_DEV_PL(target->data_length.max_ibi); in cdns_i3c_controller_ibi_enable()
1042 if (target->ibi_cb != NULL) { in cdns_i3c_controller_ibi_enable()
1045 if (target->bcr & I3C_BCR_MAX_DATA_SPEED_LIMIT) { in cdns_i3c_controller_ibi_enable()
1049 LOG_DBG("%s: IBI enabling for 0x%02x (BCR 0x%02x)", dev->name, target->dynamic_addr, in cdns_i3c_controller_ibi_enable()
1050 target->bcr); in cdns_i3c_controller_ibi_enable()
1056 LOG_ERR("%s: Error sending IBI ENEC for 0x%02x (%d)", dev->name, in cdns_i3c_controller_ibi_enable()
1057 target->dynamic_addr, ret); in cdns_i3c_controller_ibi_enable()
1061 sir_map = sys_read32(config->base + SIR_MAP_DEV_REG(cdns_i3c_device_data->id - 1)); in cdns_i3c_controller_ibi_enable()
1062 sir_map &= ~SIR_MAP_DEV_CONF_MASK(cdns_i3c_device_data->id - 1); in cdns_i3c_controller_ibi_enable()
1063 sir_map |= SIR_MAP_DEV_CONF(cdns_i3c_device_data->id - 1, sir_cfg); in cdns_i3c_controller_ibi_enable()
1065 sys_write32(sir_map, config->base + SIR_MAP_DEV_REG(cdns_i3c_device_data->id - 1)); in cdns_i3c_controller_ibi_enable()
1073 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_controller_ibi_disable()
1074 struct cdns_i3c_i2c_dev_data *cdns_i3c_device_data = target->controller_priv; in cdns_i3c_controller_ibi_disable()
1079 ret = -EINVAL; in cdns_i3c_controller_ibi_disable()
1087 LOG_ERR("%s: Error sending IBI DISEC for 0x%02x (%d)", dev->name, in cdns_i3c_controller_ibi_disable()
1088 target->dynamic_addr, ret); in cdns_i3c_controller_ibi_disable()
1092 sir_map = sys_read32(config->base + SIR_MAP_DEV_REG(cdns_i3c_device_data->id - 1)); in cdns_i3c_controller_ibi_disable()
1093 sir_map &= ~SIR_MAP_DEV_CONF_MASK(cdns_i3c_device_data->id - 1); in cdns_i3c_controller_ibi_disable()
1095 SIR_MAP_DEV_CONF(cdns_i3c_device_data->id - 1, SIR_MAP_DEV_DA(I3C_BROADCAST_ADDR)); in cdns_i3c_controller_ibi_disable()
1096 sys_write32(sir_map, config->base + SIR_MAP_DEV_REG(cdns_i3c_device_data->id - 1)); in cdns_i3c_controller_ibi_disable()
1103 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_ibi_raise_hj()
1104 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_raise_hj()
1105 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_target_ibi_raise_hj()
1108 if (!ctrl_config->is_secondary) { in cdns_i3c_target_ibi_raise_hj()
1109 LOG_ERR("%s: controller is primary, HJ not available", dev->name); in cdns_i3c_target_ibi_raise_hj()
1110 return -ENOTSUP; in cdns_i3c_target_ibi_raise_hj()
1113 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_HAS_DA) { in cdns_i3c_target_ibi_raise_hj()
1114 LOG_ERR("%s: HJ not available, DA already assigned", dev->name); in cdns_i3c_target_ibi_raise_hj()
1115 return -EACCES; in cdns_i3c_target_ibi_raise_hj()
1118 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_HJ_DIS) { in cdns_i3c_target_ibi_raise_hj()
1119 LOG_ERR("%s: HJ requests are currently disabled by DISEC", dev->name); in cdns_i3c_target_ibi_raise_hj()
1120 return -EAGAIN; in cdns_i3c_target_ibi_raise_hj()
1123 sys_write32(CTRL_HJ_INIT | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_target_ibi_raise_hj()
1124 k_sem_reset(&data->ibi_hj_complete); in cdns_i3c_target_ibi_raise_hj()
1125 if (k_sem_take(&data->ibi_hj_complete, K_MSEC(500)) != 0) { in cdns_i3c_target_ibi_raise_hj()
1126 LOG_ERR("%s: timeout waiting for DAA after HJ", dev->name); in cdns_i3c_target_ibi_raise_hj()
1127 return -ETIMEDOUT; in cdns_i3c_target_ibi_raise_hj()
1134 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_ibi_raise_intr()
1135 const struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_raise_intr()
1138 LOG_DBG("%s: issuing IBI TIR", dev->name); in cdns_i3c_target_ibi_raise_intr()
1141 * Ensure data will fit within FIFO in cdns_i3c_target_ibi_raise_intr()
1144 * FIFO sizes and should be replaced with an implementation that in cdns_i3c_target_ibi_raise_intr()
1147 if (request->payload_len > data->hw_cfg.ibi_mem_depth) { in cdns_i3c_target_ibi_raise_intr()
1148 LOG_ERR("%s: payload too large for IBI TIR", dev->name); in cdns_i3c_target_ibi_raise_intr()
1149 return -ENOMEM; in cdns_i3c_target_ibi_raise_intr()
1152 cdns_i3c_write_ibi_fifo(config, request->payload, request->payload_len); in cdns_i3c_target_ibi_raise_intr()
1155 ibi_ctrl_val = sys_read32(config->base + SLV_IBI_CTRL); in cdns_i3c_target_ibi_raise_intr()
1156 ibi_ctrl_val |= SLV_IBI_PL(request->payload_len); in cdns_i3c_target_ibi_raise_intr()
1158 sys_write32(ibi_ctrl_val, config->base + SLV_IBI_CTRL); in cdns_i3c_target_ibi_raise_intr()
1164 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_raise()
1167 return -EINVAL; in cdns_i3c_target_ibi_raise()
1170 switch (request->ibi_type) { in cdns_i3c_target_ibi_raise()
1173 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_ibi_raise()
1176 return -ENOTSUP; in cdns_i3c_target_ibi_raise()
1180 return -ENOTSUP; in cdns_i3c_target_ibi_raise()
1184 return -EINVAL; in cdns_i3c_target_ibi_raise()
1191 struct cdns_i3c_data *data = dev->data; in cdns_i3c_cancel_transfer()
1192 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_cancel_transfer()
1197 sys_write32(MST_INT_CMDD_EMP, config->base + MST_IDR); in cdns_i3c_cancel_transfer()
1200 if (data->xfer.num_cmds == 0) { in cdns_i3c_cancel_transfer()
1204 data->xfer.num_cmds = 0; in cdns_i3c_cancel_transfer()
1207 sys_write32(~CTRL_DEV_EN & sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_cancel_transfer()
1215 while (retry_count--) { in cdns_i3c_cancel_transfer()
1216 val = sys_read32(config->base + MST_STATUS0); in cdns_i3c_cancel_transfer()
1223 data->xfer.ret = -ETIMEDOUT; in cdns_i3c_cancel_transfer()
1230 config->base + FLUSH_CTRL); in cdns_i3c_cancel_transfer()
1232 /* Re-enable device */ in cdns_i3c_cancel_transfer()
1233 sys_write32(CTRL_DEV_EN | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_cancel_transfer()
1246 struct cdns_i3c_data *data = dev->data; in cdns_i3c_start_transfer()
1247 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_start_transfer()
1248 struct cdns_i3c_xfer *xfer = &data->xfer; in cdns_i3c_start_transfer()
1251 sys_write32(MST_INT_CMDD_EMP, config->base + MST_ICR); in cdns_i3c_start_transfer()
1253 /* Make sure RX FIFO is empty. */ in cdns_i3c_start_transfer()
1255 (void)sys_read32(config->base + RX_FIFO); in cdns_i3c_start_transfer()
1257 /* Make sure CMDR FIFO is empty too */ in cdns_i3c_start_transfer()
1259 (void)sys_read32(config->base + CMDR); in cdns_i3c_start_transfer()
1262 /* Write all tx data to fifo */ in cdns_i3c_start_transfer()
1263 for (unsigned int i = 0; i < xfer->num_cmds; i++) { in cdns_i3c_start_transfer()
1264 if (xfer->cmds[i].hdr == I3C_DATA_RATE_SDR) { in cdns_i3c_start_transfer()
1265 if (!(xfer->cmds[i].cmd0 & CMD0_FIFO_RNW)) { in cdns_i3c_start_transfer()
1266 cdns_i3c_write_tx_fifo(config, xfer->cmds[i].buf, in cdns_i3c_start_transfer()
1267 xfer->cmds[i].len); in cdns_i3c_start_transfer()
1269 } else if (xfer->cmds[i].hdr == I3C_DATA_RATE_HDR_DDR) { in cdns_i3c_start_transfer()
1271 cdns_i3c_write_tx_fifo(config, &xfer->cmds[i].ddr_header, in cdns_i3c_start_transfer()
1274 if (!(DDR_DATA(xfer->cmds[i].ddr_header) & HDR_CMD_RD)) { in cdns_i3c_start_transfer()
1275 uint8_t *buf = (uint8_t *)xfer->cmds[i].buf; in cdns_i3c_start_transfer()
1278 /* HDR-DDR Data Words */ in cdns_i3c_start_transfer()
1283 for (int j = 2; j < ((xfer->cmds[i].len - 2) * 2); j += 2) { in cdns_i3c_start_transfer()
1290 /* HDR-DDR CRC Word */ in cdns_i3c_start_transfer()
1291 cdns_i3c_write_tx_fifo(config, &xfer->cmds[i].ddr_crc, in cdns_i3c_start_transfer()
1295 xfer->ret = -ENOTSUP; in cdns_i3c_start_transfer()
1301 for (unsigned int i = 0; i < xfer->num_cmds; i++) { in cdns_i3c_start_transfer()
1303 xfer->cmds[i].cmd1 |= CMD1_FIFO_CMDID(i); in cdns_i3c_start_transfer()
1304 sys_write32(xfer->cmds[i].cmd1, config->base + CMD1_FIFO); in cdns_i3c_start_transfer()
1305 sys_write32(xfer->cmds[i].cmd0, config->base + CMD0_FIFO); in cdns_i3c_start_transfer()
1307 if (xfer->cmds[i].hdr == I3C_DATA_RATE_HDR_DDR) { in cdns_i3c_start_transfer()
1308 sys_write32(0x00, config->base + CMD1_FIFO); in cdns_i3c_start_transfer()
1309 if ((DDR_DATA(xfer->cmds[i].ddr_header) & HDR_CMD_RD)) { in cdns_i3c_start_transfer()
1311 config->base + CMD0_FIFO); in cdns_i3c_start_transfer()
1313 sys_write32(CMD0_FIFO_IS_DDR | CMD0_FIFO_PL_LEN(xfer->cmds[i].len), in cdns_i3c_start_transfer()
1314 config->base + CMD0_FIFO); in cdns_i3c_start_transfer()
1320 sys_write32(CTRL_MCS | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_start_transfer()
1321 sys_write32(MST_INT_CMDD_EMP, config->base + MST_IER); in cdns_i3c_start_transfer()
1336 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_do_ccc()
1337 struct cdns_i3c_data *data = dev->data; in cdns_i3c_do_ccc()
1343 if (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE)) { in cdns_i3c_do_ccc()
1344 return -EACCES; in cdns_i3c_do_ccc()
1348 return -EINVAL; in cdns_i3c_do_ccc()
1355 * FIFO sizes and should be replaced with an implementation that in cdns_i3c_do_ccc()
1359 1 + ((payload->ccc.data_len > 0) ? payload->targets.num_targets in cdns_i3c_do_ccc()
1360 : MAX(payload->targets.num_targets - 1, 0)); in cdns_i3c_do_ccc()
1361 if (num_msgs > data->hw_cfg.cmd_mem_depth || num_msgs > data->hw_cfg.cmdr_mem_depth) { in cdns_i3c_do_ccc()
1362 LOG_ERR("%s: Too many messages", dev->name); in cdns_i3c_do_ccc()
1363 return -ENOMEM; in cdns_i3c_do_ccc()
1369 i3c_ccc_is_payload_broadcast(payload) ? ROUND_UP(payload->ccc.data_len, 4) : 0; in cdns_i3c_do_ccc()
1371 for (int i = 0; i < payload->targets.num_targets; i++) { in cdns_i3c_do_ccc()
1372 if (payload->targets.payloads[i].rnw) { in cdns_i3c_do_ccc()
1373 rxsize += ROUND_UP(payload->targets.payloads[i].data_len, 4); in cdns_i3c_do_ccc()
1375 txsize += ROUND_UP(payload->targets.payloads[i].data_len, 4); in cdns_i3c_do_ccc()
1378 if ((rxsize > data->hw_cfg.rx_mem_depth) || (txsize > data->hw_cfg.tx_mem_depth)) { in cdns_i3c_do_ccc()
1379 LOG_ERR("%s: Total RX and/or TX transfer larger than FIFO", dev->name); in cdns_i3c_do_ccc()
1380 return -ENOMEM; in cdns_i3c_do_ccc()
1383 LOG_DBG("%s: CCC[0x%02x]", dev->name, payload->ccc.id); in cdns_i3c_do_ccc()
1385 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_do_ccc()
1398 for (int i = 0; i < payload->targets.num_targets; i++) { in cdns_i3c_do_ccc()
1399 cmd = &data->xfer.cmds[i]; in cdns_i3c_do_ccc()
1401 cmd->cmd1 = CMD1_FIFO_CCC(payload->ccc.id); in cdns_i3c_do_ccc()
1402 cmd->cmd0 = CMD0_FIFO_IS_CCC; in cdns_i3c_do_ccc()
1404 if (payload->ccc.data_len == 1) { in cdns_i3c_do_ccc()
1406 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_do_ccc()
1407 cmd->cmd0 |= CMD0_FIFO_IS_DB; in cdns_i3c_do_ccc()
1408 cmd->cmd1 |= CMD1_FIFO_DB(payload->ccc.data[0]); in cdns_i3c_do_ccc()
1412 dev->name, REV_ID_REV_MAJOR(data->hw_cfg.rev_id), in cdns_i3c_do_ccc()
1413 REV_ID_REV_MINOR(data->hw_cfg.rev_id)); in cdns_i3c_do_ccc()
1414 ret = -ENOTSUP; in cdns_i3c_do_ccc()
1417 } else if (payload->ccc.data_len > 1) { in cdns_i3c_do_ccc()
1418 LOG_ERR("%s: Defining Byte length greater than 1", dev->name); in cdns_i3c_do_ccc()
1419 ret = -EINVAL; in cdns_i3c_do_ccc()
1427 cmd->cmd0 |= CMD0_FIFO_BCH; in cdns_i3c_do_ccc()
1429 if (i < (payload->targets.num_targets - 1)) { in cdns_i3c_do_ccc()
1430 cmd->cmd0 |= CMD0_FIFO_RSBC; in cdns_i3c_do_ccc()
1432 cmd->buf = payload->targets.payloads[i].data; in cdns_i3c_do_ccc()
1433 cmd->len = payload->targets.payloads[i].data_len; in cdns_i3c_do_ccc()
1434 cmd->cmd0 |= CMD0_FIFO_DEV_ADDR(payload->targets.payloads[i].addr) | in cdns_i3c_do_ccc()
1435 CMD0_FIFO_PL_LEN(payload->targets.payloads[i].data_len); in cdns_i3c_do_ccc()
1436 if (payload->targets.payloads[i].rnw) { in cdns_i3c_do_ccc()
1437 cmd->cmd0 |= CMD0_FIFO_RNW; in cdns_i3c_do_ccc()
1439 cmd->hdr = I3C_DATA_RATE_SDR; in cdns_i3c_do_ccc()
1444 cmd->num_xfer = &(payload->targets.payloads[i].num_xfer); in cdns_i3c_do_ccc()
1447 cmd = &data->xfer.cmds[0]; in cdns_i3c_do_ccc()
1449 cmd->cmd1 = CMD1_FIFO_CCC(payload->ccc.id); in cdns_i3c_do_ccc()
1450 cmd->cmd0 = CMD0_FIFO_IS_CCC | CMD0_FIFO_BCH; in cdns_i3c_do_ccc()
1451 cmd->hdr = I3C_DATA_RATE_SDR; in cdns_i3c_do_ccc()
1453 if (payload->ccc.data_len > 0) { in cdns_i3c_do_ccc()
1455 cmd->buf = payload->ccc.data; in cdns_i3c_do_ccc()
1456 cmd->len = payload->ccc.data_len; in cdns_i3c_do_ccc()
1457 cmd->cmd0 |= CMD0_FIFO_PL_LEN(payload->ccc.data_len); in cdns_i3c_do_ccc()
1461 cmd->num_xfer = &(payload->ccc.num_xfer); in cdns_i3c_do_ccc()
1464 cmd->len = 0; in cdns_i3c_do_ccc()
1465 cmd->num_xfer = NULL; in cdns_i3c_do_ccc()
1469 data->xfer.ret = -ETIMEDOUT; in cdns_i3c_do_ccc()
1470 data->xfer.num_cmds = num_cmds; in cdns_i3c_do_ccc()
1473 if (k_sem_take(&data->xfer.complete, K_MSEC(1000)) != 0) { in cdns_i3c_do_ccc()
1477 if (data->xfer.ret < 0) { in cdns_i3c_do_ccc()
1478 LOG_ERR("%s: CCC[0x%02x] error (%d)", dev->name, payload->ccc.id, data->xfer.ret); in cdns_i3c_do_ccc()
1481 ret = data->xfer.ret; in cdns_i3c_do_ccc()
1483 k_mutex_unlock(&data->bus_lock); in cdns_i3c_do_ccc()
1499 struct cdns_i3c_data *data = dev->data; in cdns_i3c_do_daa()
1500 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_do_daa()
1501 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_do_daa()
1505 if (ctrl_config->is_secondary) { in cdns_i3c_do_daa()
1506 return -EACCES; in cdns_i3c_do_daa()
1510 uint32_t olddevs = sys_read32(config->base + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; in cdns_i3c_do_daa()
1516 for (uint8_t i = find_lsb_set(~olddevs); i <= data->max_devs; i++) { in cdns_i3c_do_daa()
1517 uint8_t rr_idx = i - 1; in cdns_i3c_do_daa()
1522 &data->common.attached_dev.addr_slots, last_addr + 1); in cdns_i3c_do_daa()
1525 config->base + DEV_ID_RR0(rr_idx)); in cdns_i3c_do_daa()
1526 sys_write32(0, config->base + DEV_ID_RR1(rr_idx)); in cdns_i3c_do_daa()
1527 sys_write32(0, config->base + DEV_ID_RR2(rr_idx)); in cdns_i3c_do_daa()
1544 uint32_t newdevs = sys_read32(config->base + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; in cdns_i3c_do_daa()
1551 uint8_t rr_idx = i - 1; in cdns_i3c_do_daa()
1555 uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(rr_idx)); in cdns_i3c_do_daa()
1556 uint32_t dev_id_rr1 = sys_read32(config->base + DEV_ID_RR1(rr_idx)); in cdns_i3c_do_daa()
1557 uint32_t dev_id_rr2 = sys_read32(config->base + DEV_ID_RR2(rr_idx)); in cdns_i3c_do_daa()
1570 dev->name, pid, dyn_addr); in cdns_i3c_do_daa()
1572 &data->common.attached_dev.addr_slots, dyn_addr); in cdns_i3c_do_daa()
1574 target->dynamic_addr = dyn_addr; in cdns_i3c_do_daa()
1575 target->bcr = bcr; in cdns_i3c_do_daa()
1576 target->dcr = dcr; in cdns_i3c_do_daa()
1579 dev->name, pid, dyn_addr); in cdns_i3c_do_daa()
1584 LOG_DBG("%s: ENTDAA: No devices found", dev->name); in cdns_i3c_do_daa()
1588 data->free_rr_slots &= ~newdevs; in cdns_i3c_do_daa()
1590 /* Unmask Hot-Join request interrupts. HJ will send DISEC HJ from the CTRL value */ in cdns_i3c_do_daa()
1596 LOG_DBG("%s: Broadcast ENEC was NACK", dev->name); in cdns_i3c_do_daa()
1609 * @retval -EINVAL If invalid configure parameters.
1610 * @retval -EIO General Input/Output errors.
1611 * @retval -ENOSYS If not implemented.
1615 struct cdns_i3c_data *data = dev->data; in cdns_i3c_i2c_api_configure()
1616 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_i2c_api_configure()
1620 ctrl_config->scl.i2c = 100000; in cdns_i3c_i2c_api_configure()
1623 ctrl_config->scl.i2c = 400000; in cdns_i3c_i2c_api_configure()
1626 ctrl_config->scl.i2c = 1000000; in cdns_i3c_i2c_api_configure()
1629 ctrl_config->scl.i2c = 3400000; in cdns_i3c_i2c_api_configure()
1632 ctrl_config->scl.i2c = 5000000; in cdns_i3c_i2c_api_configure()
1638 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_i2c_api_configure()
1640 k_mutex_unlock(&data->bus_lock); in cdns_i3c_i2c_api_configure()
1654 * @retval -EINVAL If invalid configure parameters.
1655 * @retval -EIO General Input/Output errors.
1656 * @retval -ENOSYS If not implemented.
1660 struct cdns_i3c_data *data = dev->data; in cdns_i3c_configure()
1663 if ((ctrl_cfg->scl.i2c == 0U) || (ctrl_cfg->scl.i3c == 0U)) { in cdns_i3c_configure()
1664 return -EINVAL; in cdns_i3c_configure()
1667 data->common.ctrl_config.scl.i3c = ctrl_cfg->scl.i3c; in cdns_i3c_configure()
1668 data->common.ctrl_config.scl.i2c = ctrl_cfg->scl.i2c; in cdns_i3c_configure()
1670 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_configure()
1672 k_mutex_unlock(&data->bus_lock); in cdns_i3c_configure()
1680 * This is to be called from an ISR when the Command Response FIFO
1682 * FIFO if message was a RnW and if any message had an error.
1688 struct cdns_i3c_data *data = dev->data; in cdns_i3c_complete_transfer()
1689 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_complete_transfer()
1701 sys_write32(MST_INT_CMDD_EMP, config->base + MST_IDR); in cdns_i3c_complete_transfer()
1704 if (data->xfer.num_cmds == 0) { in cdns_i3c_complete_transfer()
1708 /* Process all results in fifo */ in cdns_i3c_complete_transfer()
1709 for (uint32_t status0 = sys_read32(config->base + MST_STATUS0); in cdns_i3c_complete_transfer()
1710 !(status0 & MST_STATUS0_CMDR_EMP); status0 = sys_read32(config->base + MST_STATUS0)) { in cdns_i3c_complete_transfer()
1711 cmdr = sys_read32(config->base + CMDR); in cdns_i3c_complete_transfer()
1715 id >= data->xfer.num_cmds) { in cdns_i3c_complete_transfer()
1719 cmd = &data->xfer.cmds[id]; in cdns_i3c_complete_transfer()
1721 xfer = MIN(CMDR_XFER_BYTES(cmdr), cmd->len); in cdns_i3c_complete_transfer()
1722 if (cmd->num_xfer != NULL) { in cdns_i3c_complete_transfer()
1723 *cmd->num_xfer = xfer; in cdns_i3c_complete_transfer()
1726 if (cmd->cmd0 & CMD0_FIFO_RNW) { in cdns_i3c_complete_transfer()
1727 ret = cdns_i3c_read_rx_fifo(config, cmd->buf, xfer); in cdns_i3c_complete_transfer()
1730 if ((cmd->hdr == I3C_DATA_RATE_HDR_DDR) && in cdns_i3c_complete_transfer()
1731 (DDR_DATA(cmd->ddr_header) & HDR_CMD_RD)) { in cdns_i3c_complete_transfer()
1732 ret = cdns_i3c_read_rx_fifo_ddr_xfer(config, cmd->buf, xfer, in cdns_i3c_complete_transfer()
1733 cmd->ddr_header); in cdns_i3c_complete_transfer()
1737 cmd->error = CMDR_ERROR(cmdr); in cdns_i3c_complete_transfer()
1740 for (int i = 0; i < data->xfer.num_cmds; i++) { in cdns_i3c_complete_transfer()
1741 switch (data->xfer.cmds[i].error) { in cdns_i3c_complete_transfer()
1747 * A controller abort is forced if the RX FIFO fills up in cdns_i3c_complete_transfer()
1748 * There is also the case where the fifo can be full as in cdns_i3c_complete_transfer()
1749 * the len of the packet is the same length of the fifo in cdns_i3c_complete_transfer()
1755 * some targets will just auto-increment the read address in cdns_i3c_complete_transfer()
1758 if ((was_full) && (data->xfer.cmds[i].len > *data->xfer.cmds[i].num_xfer)) { in cdns_i3c_complete_transfer()
1759 ret = -ENOSPC; in cdns_i3c_complete_transfer()
1763 dev->name); in cdns_i3c_complete_transfer()
1768 uint8_t ccc = data->xfer.cmds[i].cmd1 & 0xFF; in cdns_i3c_complete_transfer()
1784 if ((*data->xfer.cmds[i].num_xfer != in cdns_i3c_complete_transfer()
1785 sizeof(((union i3c_ccc_getmxds *)0)->fmt1)) && in cdns_i3c_complete_transfer()
1786 (*data->xfer.cmds[i].num_xfer != in cdns_i3c_complete_transfer()
1787 sizeof(((union i3c_ccc_getmxds *)0)->fmt2))) { in cdns_i3c_complete_transfer()
1788 ret = -EIO; in cdns_i3c_complete_transfer()
1791 /* GETCAPS can only return 1-4 bytes */ in cdns_i3c_complete_transfer()
1792 if (*data->xfer.cmds[i].num_xfer > sizeof(union i3c_ccc_getcaps)) { in cdns_i3c_complete_transfer()
1793 ret = -EIO; in cdns_i3c_complete_transfer()
1796 ret = -EIO; in cdns_i3c_complete_transfer()
1807 ret = -EIO; in cdns_i3c_complete_transfer()
1812 ret = -ENOSPC; in cdns_i3c_complete_transfer()
1817 ret = -EINVAL; in cdns_i3c_complete_transfer()
1822 data->xfer.ret = ret; in cdns_i3c_complete_transfer()
1825 data->xfer.num_cmds = 0; in cdns_i3c_complete_transfer()
1827 k_sem_give(&data->xfer.complete); in cdns_i3c_complete_transfer()
1839 * @retval -EIO General input / output error.
1840 * @retval -EINVAL Address not registered
1845 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_i2c_transfer()
1846 struct cdns_i3c_data *data = dev->data; in cdns_i3c_i2c_transfer()
1852 if (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE)) { in cdns_i3c_i2c_transfer()
1853 return -EACCES; in cdns_i3c_i2c_transfer()
1860 if (num_msgs > data->hw_cfg.cmd_mem_depth || num_msgs > data->hw_cfg.cmdr_mem_depth) { in cdns_i3c_i2c_transfer()
1861 LOG_ERR("%s: Too many messages", dev->name); in cdns_i3c_i2c_transfer()
1862 return -ENOMEM; in cdns_i3c_i2c_transfer()
1875 if ((rxsize > data->hw_cfg.rx_mem_depth) || (txsize > data->hw_cfg.tx_mem_depth)) { in cdns_i3c_i2c_transfer()
1876 LOG_ERR("%s: Total RX and/or TX transfer larger than FIFO", dev->name); in cdns_i3c_i2c_transfer()
1877 return -ENOMEM; in cdns_i3c_i2c_transfer()
1880 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_i2c_transfer()
1889 struct cdns_i3c_cmd *cmd = &data->xfer.cmds[i]; in cdns_i3c_i2c_transfer()
1891 cmd->len = msgs[i].len; in cdns_i3c_i2c_transfer()
1892 cmd->buf = msgs[i].buf; in cdns_i3c_i2c_transfer()
1894 cmd->hdr = I3C_DATA_RATE_SDR; in cdns_i3c_i2c_transfer()
1896 cmd->cmd0 = CMD0_FIFO_PRIV_XMIT_MODE(XMIT_BURST_WITHOUT_SUBADDR); in cdns_i3c_i2c_transfer()
1897 cmd->cmd0 |= CMD0_FIFO_DEV_ADDR(i2c_dev->addr); in cdns_i3c_i2c_transfer()
1898 cmd->cmd0 |= CMD0_FIFO_PL_LEN(msgs[i].len); in cdns_i3c_i2c_transfer()
1901 if ((i < (num_msgs - 1)) && ((msgs[i].flags & I2C_MSG_STOP) == 0)) { in cdns_i3c_i2c_transfer()
1902 cmd->cmd0 |= CMD0_FIFO_RSBC; in cdns_i3c_i2c_transfer()
1906 cmd->cmd0 |= CMD0_FIFO_IS_10B; in cdns_i3c_i2c_transfer()
1910 cmd->cmd0 |= CMD0_FIFO_RNW; in cdns_i3c_i2c_transfer()
1914 cmd->num_xfer = NULL; in cdns_i3c_i2c_transfer()
1917 data->xfer.ret = -ETIMEDOUT; in cdns_i3c_i2c_transfer()
1918 data->xfer.num_cmds = num_msgs; in cdns_i3c_i2c_transfer()
1921 if (k_sem_take(&data->xfer.complete, K_MSEC(1000)) != 0) { in cdns_i3c_i2c_transfer()
1925 ret = data->xfer.ret; in cdns_i3c_i2c_transfer()
1927 k_mutex_unlock(&data->bus_lock); in cdns_i3c_i2c_transfer()
1934 struct cdns_i3c_data *data = dev->data; in cdns_i3c_master_get_rr_slot()
1935 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_master_get_rr_slot()
1941 if (!data->free_rr_slots) { in cdns_i3c_master_get_rr_slot()
1942 return -ENOSPC; in cdns_i3c_master_get_rr_slot()
1945 return find_lsb_set(data->free_rr_slots) - 1; in cdns_i3c_master_get_rr_slot()
1949 activedevs = sys_read32(config->base + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; in cdns_i3c_master_get_rr_slot()
1955 rr_idx = i - 1; in cdns_i3c_master_get_rr_slot()
1957 rr = sys_read32(config->base + DEV_ID_RR0(rr_idx)); in cdns_i3c_master_get_rr_slot()
1964 return -EINVAL; in cdns_i3c_master_get_rr_slot()
1978 if ((desc->static_addr != 0) || (desc->dynamic_addr != 0)) { in cdns_i3c_attach_device()
1979 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_attach_device()
1980 struct cdns_i3c_data *data = dev->data; in cdns_i3c_attach_device()
1982 int slot = cdns_i3c_master_get_rr_slot(dev, desc->dynamic_addr ? desc->dynamic_addr in cdns_i3c_attach_device()
1983 : desc->static_addr); in cdns_i3c_attach_device()
1986 LOG_ERR("%s: no space for i3c device: %s", dev->name, desc->dev->name); in cdns_i3c_attach_device()
1990 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_attach_device()
1992 sys_write32(sys_read32(config->base + DEVS_CTRL) | DEVS_CTRL_DEV_ACTIVE(slot), in cdns_i3c_attach_device()
1993 config->base + DEVS_CTRL); in cdns_i3c_attach_device()
1995 data->cdns_i3c_i2c_priv_data[slot].id = slot; in cdns_i3c_attach_device()
1996 desc->controller_priv = &(data->cdns_i3c_i2c_priv_data[slot]); in cdns_i3c_attach_device()
1997 data->free_rr_slots &= ~BIT(slot); in cdns_i3c_attach_device()
2001 prepare_rr0_dev_address(desc->dynamic_addr ? desc->dynamic_addr in cdns_i3c_attach_device()
2002 : desc->static_addr); in cdns_i3c_attach_device()
2003 uint32_t dev_id_rr1 = DEV_ID_RR1_PID_MSB((desc->pid & 0xFFFFFFFF0000) >> 16); in cdns_i3c_attach_device()
2004 uint32_t dev_id_rr2 = DEV_ID_RR2_PID_LSB(desc->pid & 0xFFFF); in cdns_i3c_attach_device()
2006 sys_write32(dev_id_rr0, config->base + DEV_ID_RR0(slot)); in cdns_i3c_attach_device()
2007 sys_write32(dev_id_rr1, config->base + DEV_ID_RR1(slot)); in cdns_i3c_attach_device()
2008 sys_write32(dev_id_rr2, config->base + DEV_ID_RR2(slot)); in cdns_i3c_attach_device()
2010 k_mutex_unlock(&data->bus_lock); in cdns_i3c_attach_device()
2019 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_reattach_device()
2020 struct cdns_i3c_data *data = dev->data; in cdns_i3c_reattach_device()
2021 struct cdns_i3c_i2c_dev_data *cdns_i3c_device_data = desc->controller_priv; in cdns_i3c_reattach_device()
2024 LOG_ERR("%s: %s: device not attached", dev->name, desc->dev->name); in cdns_i3c_reattach_device()
2025 return -EINVAL; in cdns_i3c_reattach_device()
2028 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_reattach_device()
2030 uint32_t dev_id_rr0 = DEV_ID_RR0_IS_I3C | prepare_rr0_dev_address(desc->dynamic_addr); in cdns_i3c_reattach_device()
2031 uint32_t dev_id_rr1 = DEV_ID_RR1_PID_MSB((desc->pid & 0xFFFFFFFF0000) >> 16); in cdns_i3c_reattach_device()
2032 uint32_t dev_id_rr2 = DEV_ID_RR2_PID_LSB(desc->pid & 0xFFFF) | DEV_ID_RR2_BCR(desc->bcr) | in cdns_i3c_reattach_device()
2033 DEV_ID_RR2_DCR(desc->dcr); in cdns_i3c_reattach_device()
2035 sys_write32(dev_id_rr0, config->base + DEV_ID_RR0(cdns_i3c_device_data->id)); in cdns_i3c_reattach_device()
2036 sys_write32(dev_id_rr1, config->base + DEV_ID_RR1(cdns_i3c_device_data->id)); in cdns_i3c_reattach_device()
2037 sys_write32(dev_id_rr2, config->base + DEV_ID_RR2(cdns_i3c_device_data->id)); in cdns_i3c_reattach_device()
2039 k_mutex_unlock(&data->bus_lock); in cdns_i3c_reattach_device()
2046 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_detach_device()
2047 struct cdns_i3c_data *data = dev->data; in cdns_i3c_detach_device()
2048 struct cdns_i3c_i2c_dev_data *cdns_i3c_device_data = desc->controller_priv; in cdns_i3c_detach_device()
2051 LOG_ERR("%s: %s: device not attached", dev->name, desc->dev->name); in cdns_i3c_detach_device()
2052 return -EINVAL; in cdns_i3c_detach_device()
2055 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_detach_device()
2057 sys_write32(sys_read32(config->base + DEVS_CTRL) | in cdns_i3c_detach_device()
2058 DEVS_CTRL_DEV_CLR(cdns_i3c_device_data->id), in cdns_i3c_detach_device()
2059 config->base + DEVS_CTRL); in cdns_i3c_detach_device()
2060 data->free_rr_slots |= BIT(cdns_i3c_device_data->id); in cdns_i3c_detach_device()
2061 desc->controller_priv = NULL; in cdns_i3c_detach_device()
2063 k_mutex_unlock(&data->bus_lock); in cdns_i3c_detach_device()
2070 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_i2c_attach_device()
2071 struct cdns_i3c_data *data = dev->data; in cdns_i3c_i2c_attach_device()
2076 LOG_ERR("%s: no space for i2c device: addr 0x%02x", dev->name, desc->addr); in cdns_i3c_i2c_attach_device()
2080 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_i2c_attach_device()
2082 uint32_t dev_id_rr0 = prepare_rr0_dev_address(desc->addr); in cdns_i3c_i2c_attach_device()
2083 uint32_t dev_id_rr2 = DEV_ID_RR2_LVR(desc->lvr); in cdns_i3c_i2c_attach_device()
2085 sys_write32(dev_id_rr0, config->base + DEV_ID_RR0(slot)); in cdns_i3c_i2c_attach_device()
2086 sys_write32(0, config->base + DEV_ID_RR1(slot)); in cdns_i3c_i2c_attach_device()
2087 sys_write32(dev_id_rr2, config->base + DEV_ID_RR2(slot)); in cdns_i3c_i2c_attach_device()
2089 data->cdns_i3c_i2c_priv_data[slot].id = slot; in cdns_i3c_i2c_attach_device()
2090 desc->controller_priv = &(data->cdns_i3c_i2c_priv_data[slot]); in cdns_i3c_i2c_attach_device()
2091 data->free_rr_slots &= ~BIT(slot); in cdns_i3c_i2c_attach_device()
2093 sys_write32(sys_read32(config->base + DEVS_CTRL) | DEVS_CTRL_DEV_ACTIVE(slot), in cdns_i3c_i2c_attach_device()
2094 config->base + DEVS_CTRL); in cdns_i3c_i2c_attach_device()
2096 k_mutex_unlock(&data->bus_lock); in cdns_i3c_i2c_attach_device()
2103 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_i2c_detach_device()
2104 struct cdns_i3c_data *data = dev->data; in cdns_i3c_i2c_detach_device()
2105 struct cdns_i3c_i2c_dev_data *cdns_i2c_device_data = desc->controller_priv; in cdns_i3c_i2c_detach_device()
2108 LOG_ERR("%s: device not attached", dev->name); in cdns_i3c_i2c_detach_device()
2109 return -EINVAL; in cdns_i3c_i2c_detach_device()
2112 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_i2c_detach_device()
2114 sys_write32(sys_read32(config->base + DEVS_CTRL) | in cdns_i3c_i2c_detach_device()
2115 DEVS_CTRL_DEV_CLR(cdns_i2c_device_data->id), in cdns_i3c_i2c_detach_device()
2116 config->base + DEVS_CTRL); in cdns_i3c_i2c_detach_device()
2117 data->free_rr_slots |= BIT(cdns_i2c_device_data->id); in cdns_i3c_i2c_detach_device()
2118 desc->controller_priv = NULL; in cdns_i3c_i2c_detach_device()
2120 k_mutex_unlock(&data->bus_lock); in cdns_i3c_i2c_detach_device()
2140 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_transfer()
2141 struct cdns_i3c_data *data = dev->data; in cdns_i3c_transfer()
2147 if (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE)) { in cdns_i3c_transfer()
2148 return -EACCES; in cdns_i3c_transfer()
2155 if (num_msgs > data->hw_cfg.cmd_mem_depth || num_msgs > data->hw_cfg.cmdr_mem_depth) { in cdns_i3c_transfer()
2156 LOG_ERR("%s: Too many messages", dev->name); in cdns_i3c_transfer()
2157 return -ENOMEM; in cdns_i3c_transfer()
2164 * FIFO sizes and should be replaced with an implementation that in cdns_i3c_transfer()
2174 if ((rxsize > data->hw_cfg.rx_mem_depth) || (txsize > data->hw_cfg.tx_mem_depth)) { in cdns_i3c_transfer()
2175 LOG_ERR("%s: Total RX and/or TX transfer larger than FIFO", dev->name); in cdns_i3c_transfer()
2176 return -ENOMEM; in cdns_i3c_transfer()
2179 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_transfer()
2189 * in-flight but it would be possible to keep a queue of transfers. If so, in cdns_i3c_transfer()
2196 struct cdns_i3c_cmd *cmd = &data->xfer.cmds[i]; in cdns_i3c_transfer()
2203 cmd->len = pl; in cdns_i3c_transfer()
2204 cmd->buf = msgs[i].buf; in cdns_i3c_transfer()
2206 cmd->cmd0 = CMD0_FIFO_PRIV_XMIT_MODE(XMIT_BURST_WITHOUT_SUBADDR); in cdns_i3c_transfer()
2207 cmd->cmd0 |= CMD0_FIFO_DEV_ADDR(target->dynamic_addr); in cdns_i3c_transfer()
2209 cmd->cmd0 |= CMD0_FIFO_RNW; in cdns_i3c_transfer()
2214 cmd->cmd0 |= CMD0_FIFO_PL_LEN(pl + 1); in cdns_i3c_transfer()
2216 cmd->cmd0 |= CMD0_FIFO_PL_LEN(pl); in cdns_i3c_transfer()
2221 cmd->cmd0 |= CMD0_FIFO_BCH; in cdns_i3c_transfer()
2229 if ((i < (num_msgs - 1)) && ((msgs[i].flags & I3C_MSG_STOP) == 0)) { in cdns_i3c_transfer()
2230 cmd->cmd0 |= CMD0_FIFO_RSBC; in cdns_i3c_transfer()
2239 cmd->num_xfer = &(msgs[i].num_xfer); in cdns_i3c_transfer()
2240 cmd->hdr = I3C_DATA_RATE_SDR; in cdns_i3c_transfer()
2241 } else if ((data->common.ctrl_config.supported_hdr & I3C_MSG_HDR_DDR) && in cdns_i3c_transfer()
2247 ret = -EINVAL; in cdns_i3c_transfer()
2251 cmd->buf = msgs[i].buf; in cdns_i3c_transfer()
2253 /* HDR-DDR Read */ in cdns_i3c_transfer()
2256 (target->dynamic_addr << 1); in cdns_i3c_transfer()
2260 /* HDR-DDR Command Word */ in cdns_i3c_transfer()
2261 cmd->ddr_header = in cdns_i3c_transfer()
2265 /* HDR-DDR Write */ in cdns_i3c_transfer()
2267 (target->dynamic_addr << 1); in cdns_i3c_transfer()
2268 /* HDR-DDR Command Word */ in cdns_i3c_transfer()
2269 cmd->ddr_header = in cdns_i3c_transfer()
2276 sys_get_be16((void *)((uintptr_t)cmd->buf + j))); in cdns_i3c_transfer()
2278 cmd->ddr_crc = DDR_PREAMBLE_CMD_CRC | DDR_CRC_TOKEN | (crc5 << 9) | in cdns_i3c_transfer()
2284 cmd->len = ((pl / 2) + 2); in cdns_i3c_transfer()
2286 /* prep command FIFO for ENTHDR0 */ in cdns_i3c_transfer()
2287 cmd->cmd0 = CMD0_FIFO_IS_CCC; in cdns_i3c_transfer()
2288 cmd->cmd1 = I3C_CCC_ENTHDR0; in cdns_i3c_transfer()
2292 cmd->num_xfer = &(msgs[i].num_xfer); in cdns_i3c_transfer()
2293 cmd->hdr = I3C_DATA_RATE_HDR_DDR; in cdns_i3c_transfer()
2295 LOG_ERR("%s: Unsupported HDR Mode %d", dev->name, msgs[i].hdr_mode); in cdns_i3c_transfer()
2296 ret = -ENOTSUP; in cdns_i3c_transfer()
2301 data->xfer.ret = -ETIMEDOUT; in cdns_i3c_transfer()
2302 data->xfer.num_cmds = num_msgs; in cdns_i3c_transfer()
2305 if (k_sem_take(&data->xfer.complete, K_MSEC(1000)) != 0) { in cdns_i3c_transfer()
2306 LOG_ERR("%s: transfer timed out", dev->name); in cdns_i3c_transfer()
2310 ret = data->xfer.ret; in cdns_i3c_transfer()
2312 k_mutex_unlock(&data->bus_lock); in cdns_i3c_transfer()
2323 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_read_ibi_fifo()
2325 return -EIO; in cdns_i3c_read_ibi_fifo()
2327 val = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); in cdns_i3c_read_ibi_fifo()
2333 return -EIO; in cdns_i3c_read_ibi_fifo()
2335 val = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); in cdns_i3c_read_ibi_fifo()
2344 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_handle_ibi()
2345 struct cdns_i3c_data *data = dev->data; in cdns_i3c_handle_ibi()
2357 uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(slave_id + 1)); in cdns_i3c_handle_ibi()
2369 LOG_DBG("%s: NAK for slave ID %u", dev->name, (unsigned int)slave_id); in cdns_i3c_handle_ibi()
2374 LOG_ERR("%s: IBI Data overflow", dev->name); in cdns_i3c_handle_ibi()
2381 if (ibi_len - data->ibi_buf.ibi_data_cnt > 0) { in cdns_i3c_handle_ibi()
2383 config, &data->ibi_buf.ibi_data[data->ibi_buf.ibi_data_cnt], in cdns_i3c_handle_ibi()
2384 ibi_len - data->ibi_buf.ibi_data_cnt) < 0) { in cdns_i3c_handle_ibi()
2385 LOG_ERR("%s: Failed to get payload", dev->name); in cdns_i3c_handle_ibi()
2388 data->ibi_buf.ibi_data_cnt = 0; in cdns_i3c_handle_ibi()
2391 if (i3c_ibi_work_enqueue_target_irq(desc, data->ibi_buf.ibi_data, ibi_len) != 0) { in cdns_i3c_handle_ibi()
2392 LOG_ERR("%s: Error enqueue IBI IRQ work", dev->name); in cdns_i3c_handle_ibi()
2399 LOG_DBG("%s: NAK for HJ", dev->name); in cdns_i3c_handle_hj()
2404 LOG_ERR("%s: Error enqueue IBI HJ work", dev->name); in cdns_i3c_handle_hj()
2410 const struct cdns_i3c_config *config = dev->config; in cnds_i3c_master_demux_ibis()
2412 for (uint32_t status0 = sys_read32(config->base + MST_STATUS0); in cnds_i3c_master_demux_ibis()
2413 !(status0 & MST_STATUS0_IBIR_EMP); status0 = sys_read32(config->base + MST_STATUS0)) { in cnds_i3c_master_demux_ibis()
2414 uint32_t ibir = sys_read32(config->base + IBIR); in cnds_i3c_master_demux_ibis()
2434 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_hj_complete()
2436 k_sem_give(&data->ibi_hj_complete); in cdns_i3c_target_ibi_hj_complete()
2444 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_sdr_tx_thr_int_handler()
2445 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_sdr_tx_thr_int_handler()
2447 if (target_cb != NULL && target_cb->read_processed_cb) { in cdns_i3c_target_sdr_tx_thr_int_handler()
2451 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_sdr_tx_thr_int_handler()
2452 /* while tx fifo is not full and there is still data available */ in cdns_i3c_target_sdr_tx_thr_int_handler()
2453 while ((!(sys_read32(config->base + SLV_STATUS1) & in cdns_i3c_target_sdr_tx_thr_int_handler()
2465 status = target_cb->read_processed_cb(data->target_config, in cdns_i3c_target_sdr_tx_thr_int_handler()
2477 /* while tx fifo is not full and there is still data available */ in cdns_i3c_target_sdr_tx_thr_int_handler()
2478 while ((!(sys_read32(config->base + SLV_STATUS1) & in cdns_i3c_target_sdr_tx_thr_int_handler()
2485 status = target_cb->read_processed_cb(data->target_config, &byte); in cdns_i3c_target_sdr_tx_thr_int_handler()
2496 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_irq_handler()
2497 struct cdns_i3c_data *data = dev->data; in cdns_i3c_irq_handler()
2499 if (sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE) { in cdns_i3c_irq_handler()
2500 uint32_t int_st = sys_read32(config->base + MST_ISR); in cdns_i3c_irq_handler()
2501 sys_write32(int_st, config->base + MST_ICR); in cdns_i3c_irq_handler()
2513 /* In-band interrupt */ in cdns_i3c_irq_handler()
2518 LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", in cdns_i3c_irq_handler()
2519 dev->name); in cdns_i3c_irq_handler()
2523 /* In-band interrupt data threshold */ in cdns_i3c_irq_handler()
2526 /* pop data out of the IBI FIFO */ in cdns_i3c_irq_handler()
2528 uint32_t *ptr = (uint32_t *)&data->ibi_buf in cdns_i3c_irq_handler()
2529 .ibi_data[data->ibi_buf.ibi_data_cnt]; in cdns_i3c_irq_handler()
2530 *ptr = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); in cdns_i3c_irq_handler()
2531 data->ibi_buf.ibi_data_cnt += 4; in cdns_i3c_irq_handler()
2534 LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", in cdns_i3c_irq_handler()
2535 dev->name); in cdns_i3c_irq_handler()
2539 /* In-band interrupt response overflow */ in cdns_i3c_irq_handler()
2541 LOG_ERR("%s: controller ibir overflow,", dev->name); in cdns_i3c_irq_handler()
2544 /* In-band interrupt data */ in cdns_i3c_irq_handler()
2546 LOG_ERR("%s: controller tx buffer overflow,", dev->name); in cdns_i3c_irq_handler()
2549 /* In-band interrupt data */ in cdns_i3c_irq_handler()
2551 LOG_ERR("%s: controller rx buffer underflow,", dev->name); in cdns_i3c_irq_handler()
2554 uint32_t int_sl = sys_read32(config->base + SLV_ISR); in cdns_i3c_irq_handler()
2556 data->target_config ? data->target_config->callbacks : NULL; in cdns_i3c_irq_handler()
2558 sys_write32(int_sl, config->base + SLV_ICR); in cdns_i3c_irq_handler()
2560 /* SLV SDR rx fifo threshold */ in cdns_i3c_irq_handler()
2562 /* while rx fifo is not empty */ in cdns_i3c_irq_handler()
2563 while (!(sys_read32(config->base + SLV_STATUS1) & in cdns_i3c_irq_handler()
2565 if (target_cb != NULL && target_cb->write_received_cb != NULL) { in cdns_i3c_irq_handler()
2571 /* SLV SDR tx fifo threshold */ in cdns_i3c_irq_handler()
2579 (void)sys_read32(config->base + SLV_STATUS0); in cdns_i3c_irq_handler()
2581 if (target_cb != NULL && target_cb->stop_cb) { in cdns_i3c_irq_handler()
2582 target_cb->stop_cb(data->target_config); in cdns_i3c_irq_handler()
2589 (void)sys_read32(config->base + SLV_STATUS0); in cdns_i3c_irq_handler()
2591 data->fifo_bytes_read = 0; in cdns_i3c_irq_handler()
2593 if (target_cb != NULL && target_cb->stop_cb) { in cdns_i3c_irq_handler()
2594 target_cb->stop_cb(data->target_config); in cdns_i3c_irq_handler()
2600 LOG_INF("%s: DA updated to 0x%02lx", dev->name, in cdns_i3c_irq_handler()
2601 SLV_STATUS1_DA(sys_read32(config->base + SLV_STATUS1))); in cdns_i3c_irq_handler()
2628 /* SLV SDR rx fifo underflow */ in cdns_i3c_irq_handler()
2630 LOG_ERR("%s: slave sdr rx buffer underflow", dev->name); in cdns_i3c_irq_handler()
2633 /* SLV SDR tx fifo overflow */ in cdns_i3c_irq_handler()
2635 LOG_ERR("%s: slave sdr tx buffer overflow,", dev->name); in cdns_i3c_irq_handler()
2643 /* initial value of CRC5 for HDR-DDR is 0x1F */ in cdns_i3c_irq_handler()
2646 while (!(sys_read32(config->base + SLV_STATUS1) & in cdns_i3c_irq_handler()
2648 uint32_t ddr_rx_data = sys_read32(config->base + SLV_DDR_RX_FIFO); in cdns_i3c_irq_handler()
2658 dev->name); in cdns_i3c_irq_handler()
2664 target_cb->write_received_cb != NULL) { in cdns_i3c_irq_handler()
2666 target_cb->write_received_cb( in cdns_i3c_irq_handler()
2667 data->target_config, in cdns_i3c_irq_handler()
2669 target_cb->write_received_cb( in cdns_i3c_irq_handler()
2670 data->target_config, in cdns_i3c_irq_handler()
2679 dev->name); in cdns_i3c_irq_handler()
2689 if (target_cb != NULL && target_cb->stop_cb != NULL) { in cdns_i3c_irq_handler()
2690 target_cb->stop_cb(data->target_config); in cdns_i3c_irq_handler()
2697 (void)sys_read32(config->base + SLV_STATUS0); in cdns_i3c_irq_handler()
2699 if (target_cb != NULL && target_cb->stop_cb) { in cdns_i3c_irq_handler()
2700 target_cb->stop_cb(data->target_config); in cdns_i3c_irq_handler()
2708 if (target_cb != NULL && target_cb->read_processed_cb) { in cdns_i3c_irq_handler()
2710 while ((!(sys_read32(config->base + SLV_STATUS1) & in cdns_i3c_irq_handler()
2718 status = target_cb->read_processed_cb(data->target_config, in cdns_i3c_irq_handler()
2732 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_read_hw_cfg()
2733 struct cdns_i3c_data *data = dev->data; in cdns_i3c_read_hw_cfg()
2735 uint32_t devid = sys_read32(config->base + DEV_ID); in cdns_i3c_read_hw_cfg()
2736 uint32_t revid = sys_read32(config->base + REV_ID); in cdns_i3c_read_hw_cfg()
2742 dev->name, REV_ID_VID(revid), REV_ID_PID(revid), REV_ID_REV_MAJOR(revid), in cdns_i3c_read_hw_cfg()
2748 uint32_t cfg0 = sys_read32(config->base + CONF_STATUS0); in cdns_i3c_read_hw_cfg()
2749 uint32_t cfg1 = sys_read32(config->base + CONF_STATUS1); in cdns_i3c_read_hw_cfg()
2751 data->hw_cfg.rev_id = revid; in cdns_i3c_read_hw_cfg()
2752 data->hw_cfg.cmdr_mem_depth = CONF_STATUS0_CMDR_DEPTH(cfg0) * 4; in cdns_i3c_read_hw_cfg()
2753 data->hw_cfg.cmd_mem_depth = CONF_STATUS1_CMD_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2754 data->hw_cfg.rx_mem_depth = CONF_STATUS1_RX_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2755 data->hw_cfg.tx_mem_depth = CONF_STATUS1_TX_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2756 data->hw_cfg.ddr_rx_mem_depth = CONF_STATUS1_SLV_DDR_RX_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2757 data->hw_cfg.ddr_tx_mem_depth = CONF_STATUS1_SLV_DDR_TX_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2758 data->hw_cfg.ibir_mem_depth = CONF_STATUS0_IBIR_DEPTH(cfg0) * 4; in cdns_i3c_read_hw_cfg()
2759 data->hw_cfg.ibi_mem_depth = CONF_STATUS1_IBI_DEPTH(cfg0) * 4; in cdns_i3c_read_hw_cfg()
2761 LOG_DBG("%s: FIFO info:\r\n" in cdns_i3c_read_hw_cfg()
2770 dev->name, data->hw_cfg.cmd_mem_depth, data->hw_cfg.cmdr_mem_depth, in cdns_i3c_read_hw_cfg()
2771 data->hw_cfg.rx_mem_depth, data->hw_cfg.tx_mem_depth, data->hw_cfg.ddr_rx_mem_depth, in cdns_i3c_read_hw_cfg()
2772 data->hw_cfg.ddr_tx_mem_depth, data->hw_cfg.ibi_mem_depth, in cdns_i3c_read_hw_cfg()
2773 data->hw_cfg.ibir_mem_depth); in cdns_i3c_read_hw_cfg()
2775 /* Regardless of the cmd depth size we are limited by our cmd array length. */ in cdns_i3c_read_hw_cfg()
2776 data->hw_cfg.cmd_mem_depth = MIN(data->hw_cfg.cmd_mem_depth, ARRAY_SIZE(data->xfer.cmds)); in cdns_i3c_read_hw_cfg()
2796 * @retval -EIO General Input/Output errors.
2797 * @retval -ENOSYS If not implemented.
2801 struct cdns_i3c_data *data = dev->data; in cdns_i3c_config_get()
2805 ret = -EINVAL; in cdns_i3c_config_get()
2809 (void)memcpy(config, &data->common.ctrl_config, sizeof(data->common.ctrl_config)); in cdns_i3c_config_get()
2817 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_tx_ddr_write()
2818 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_tx_ddr_write()
2823 /* check if there is space available in the tx fifo */ in cdns_i3c_target_tx_ddr_write()
2824 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_DDR_TX_FULL) { in cdns_i3c_target_tx_ddr_write()
2825 return -ENOSPC; in cdns_i3c_target_tx_ddr_write()
2830 return -EINVAL; in cdns_i3c_target_tx_ddr_write()
2834 uint8_t slave_da = SLV_STATUS1_DA(sys_read32(config->base + SLV_STATUS1)); in cdns_i3c_target_tx_ddr_write()
2840 /* write as much as you can to the fifo */ in cdns_i3c_target_tx_ddr_write()
2842 i < len && (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_DDR_TX_FULL)); in cdns_i3c_target_tx_ddr_write()
2848 sys_write32(data_word, config->base + SLV_DDR_TX_FIFO); in cdns_i3c_target_tx_ddr_write()
2851 if ((i == len) && (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_DDR_TX_FULL))) { in cdns_i3c_target_tx_ddr_write()
2853 config->base + SLV_DDR_TX_FIFO); in cdns_i3c_target_tx_ddr_write()
2857 uint32_t thr_ctrl = sys_read32(config->base + SLV_DDR_TX_RX_THR_CTRL); in cdns_i3c_target_tx_ddr_write()
2860 * Interrupt at half of the data or FIFO depth to give it enough time to be in cdns_i3c_target_tx_ddr_write()
2865 thr_ctrl |= TX_THR(MIN((data->hw_cfg.tx_mem_depth / 4) / 2, len / 2)); in cdns_i3c_target_tx_ddr_write()
2867 sys_write32(thr_ctrl, config->base + SLV_DDR_TX_RX_THR_CTRL); in cdns_i3c_target_tx_ddr_write()
2873 * @brief Writes to the Target's TX FIFO
2875 * The Cadence I3C will then ACK read requests to it's TX FIFO from a
2884 * @retval -EACCES Not in Target Mode
2885 * @retval -ENOSPC No space in Tx FIFO
2890 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_tx_write()
2891 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_tx_write()
2892 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_target_tx_write()
2899 if (sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE) { in cdns_i3c_target_tx_write()
2900 return -EACCES; in cdns_i3c_target_tx_write()
2903 /* check if there is space available in the tx fifo */ in cdns_i3c_target_tx_write()
2904 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_SDR_TX_FULL) { in cdns_i3c_target_tx_write()
2905 return -ENOSPC; in cdns_i3c_target_tx_write()
2908 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_target_tx_write()
2911 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_tx_write()
2912 sys_write32(len, config->base + SLV_CTRL); in cdns_i3c_target_tx_write()
2915 if (ctrl_config->supported_hdr & I3C_MSG_HDR_DDR) { in cdns_i3c_target_tx_write()
2919 LOG_ERR("%s: HDR-DDR not supported", dev->name); in cdns_i3c_target_tx_write()
2920 i = -ENOTSUP; in cdns_i3c_target_tx_write()
2923 /* write as much as you can to the fifo */ in cdns_i3c_target_tx_write()
2925 (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_SDR_TX_FULL))) { in cdns_i3c_target_tx_write()
2929 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_tx_write()
2930 remain = len - i; in cdns_i3c_target_tx_write()
2937 sys_write32(val, config->base + TX_FIFO); in cdns_i3c_target_tx_write()
2940 sys_write32((uint32_t)buf[i], config->base + TX_FIFO); in cdns_i3c_target_tx_write()
2946 uint32_t thr_ctrl = sys_read32(config->base + TX_RX_THR_CTRL); in cdns_i3c_target_tx_write()
2949 * Interrupt at half of the data or FIFO depth to give it enough time to be in cdns_i3c_target_tx_write()
2954 thr_ctrl |= TX_THR(MIN((data->hw_cfg.tx_mem_depth / 4) / 2, len / 2)); in cdns_i3c_target_tx_write()
2955 sys_write32(thr_ctrl, config->base + TX_RX_THR_CTRL); in cdns_i3c_target_tx_write()
2957 LOG_ERR("%s: Unsupported HDR Mode %d", dev->name, hdr_mode); in cdns_i3c_target_tx_write()
2958 i = -ENOTSUP; in cdns_i3c_target_tx_write()
2961 k_mutex_unlock(&data->bus_lock); in cdns_i3c_target_tx_write()
2981 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_register()
2983 data->target_config = cfg; in cdns_i3c_target_register()
3020 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_device_find()
3022 return i3c_dev_list_find(&config->common.dev_list, id); in cdns_i3c_device_find()
3062 ret = -ENODEV; in cdns_i3c_i2c_api_transfer()
3084 for (int i = 0; i < dev_list->num_i2c; i++) { in i3c_bus_mode()
3085 switch (I3C_LVR_I2C_DEV_IDX(dev_list->i2c[i].lvr)) { in i3c_bus_mode()
3120 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_sda_data_hold()
3121 uint32_t input_clock_frequency = config->input_frequency; in cdns_i3c_sda_data_hold()
3129 return (THD_DELAY_MAX - thd_delay); in cdns_i3c_sda_data_hold()
3139 struct cdns_i3c_data *data = dev->data; in cdns_i3c_bus_init()
3140 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_bus_init()
3141 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_bus_init()
3146 sys_write32(DEVS_CTRL_DEV_CLR_ALL, config->base + DEVS_CTRL); in cdns_i3c_bus_init()
3148 uint32_t conf0 = sys_read32(config->base + CONF_STATUS0); in cdns_i3c_bus_init()
3149 uint32_t conf1 = sys_read32(config->base + CONF_STATUS1); in cdns_i3c_bus_init()
3150 data->max_devs = CONF_STATUS0_DEVS_NUM(conf0); in cdns_i3c_bus_init()
3151 data->free_rr_slots = GENMASK(data->max_devs, 1); in cdns_i3c_bus_init()
3154 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_bus_init()
3155 ctrl_config->supported_hdr = in cdns_i3c_bus_init()
3157 ctrl_config->is_secondary = in cdns_i3c_bus_init()
3161 ctrl_config->supported_hdr = in cdns_i3c_bus_init()
3163 ctrl_config->is_secondary = (conf0 & CONF_STATUS0_SEC_MASTER) ? true : false; in cdns_i3c_bus_init()
3165 k_mutex_init(&data->bus_lock); in cdns_i3c_bus_init()
3166 k_sem_init(&data->xfer.complete, 0, 1); in cdns_i3c_bus_init()
3167 k_sem_init(&data->ibi_hj_complete, 0, 1); in cdns_i3c_bus_init()
3172 config->irq_config_func(dev); in cdns_i3c_bus_init()
3175 sys_write32(~CTRL_DEV_EN & sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_bus_init()
3180 enum i3c_bus_mode mode = i3c_bus_mode(&config->common.dev_list); in cdns_i3c_bus_init()
3182 LOG_DBG("%s: i3c bus mode %d", dev->name, mode); in cdns_i3c_bus_init()
3197 return -EINVAL; in cdns_i3c_bus_init()
3201 * When a Hot-Join request happens, disable all events coming from this device. in cdns_i3c_bus_init()
3214 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 4)) { in cdns_i3c_bus_init()
3223 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 5)) { in cdns_i3c_bus_init()
3228 sys_write32(ctrl, config->base + CTRL); in cdns_i3c_bus_init()
3231 sys_write32(CTRL_DEV_EN | ctrl, config->base + CTRL); in cdns_i3c_bus_init()
3233 /* Set fifo thresholds. */ in cdns_i3c_bus_init()
3235 IBIR_THR(config->ibid_thr), in cdns_i3c_bus_init()
3236 config->base + CMD_IBI_THR_CTRL); in cdns_i3c_bus_init()
3239 if (sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE) { in cdns_i3c_bus_init()
3240 sys_write32(TX_THR(I3C_TX_THR) | RX_THR(data->hw_cfg.rx_mem_depth), in cdns_i3c_bus_init()
3241 config->base + TX_RX_THR_CTRL); in cdns_i3c_bus_init()
3243 sys_write32(TX_THR(1) | RX_THR(1), config->base + TX_RX_THR_CTRL); in cdns_i3c_bus_init()
3245 config->base + SLV_DDR_TX_RX_THR_CTRL); in cdns_i3c_bus_init()
3253 config->base + SLV_IER); in cdns_i3c_bus_init()
3258 config->base + MST_IER); in cdns_i3c_bus_init()
3270 if (!ctrl_config->is_secondary) { in cdns_i3c_bus_init()
3274 ret = i3c_bus_init(dev, &config->common.dev_list); in cdns_i3c_bus_init()
3277 sys_write32(CTRL_HJ_ACK | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_bus_init()