Lines Matching +full:max +full:- +full:xfer +full:- +full:size

4  * SPDX-License-Identifier: Apache-2.0
475 /* Target T_LOW period in open-drain mode. */
479 * MIPI I3C v1.1.1 Spec defines SDA Signal Data Hold in Push Pull max as the
487 /* command tx fifo threshold - unused */
489 /* in-band-interrupt response queue threshold */
491 /* tx data threshold - unused */
585 struct cdns_i3c_xfer xfer; member
620 for (i = 15; i >= 0; --i) { in i3c_cdns_crc5()
669 /* Returns [7:1] 7-bit addr, [0] even/xor parity */
677 b = b & (b - 1); in cdns_i3c_even_parity_byte()
687 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_cmd_rsp_fifo_empty()
695 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_cmd_fifo_empty()
703 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_cmd_fifo_full()
711 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_ibi_rsp_fifo_empty()
719 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_tx_fifo_full()
727 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_rx_fifo_full()
735 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_rx_fifo_empty()
743 uint32_t mst_st = sys_read32(config->base + MST_STATUS0); in cdns_i3c_ibi_fifo_empty()
751 sys_write32(MST_INT_MASK, config->base + MST_IDR); in cdns_i3c_interrupts_disable()
756 sys_write32(MST_INT_MASK, config->base + MST_ICR); in cdns_i3c_interrupts_clear()
766 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_write_tx_fifo()
768 sys_write32(val, config->base + TX_FIFO); in cdns_i3c_write_tx_fifo()
774 sys_write32(val, config->base + TX_FIFO); in cdns_i3c_write_tx_fifo()
784 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_write_ddr_tx_fifo()
786 sys_write32(val, config->base + SLV_DDR_TX_FIFO); in cdns_i3c_write_ddr_tx_fifo()
792 sys_write32(val, config->base + SLV_DDR_TX_FIFO); in cdns_i3c_write_ddr_tx_fifo()
803 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_write_ibi_fifo()
805 sys_write32(val, config->base + IBI_DATA_FIFO); in cdns_i3c_write_ibi_fifo()
811 sys_write32(val, config->base + IBI_DATA_FIFO); in cdns_i3c_write_ibi_fifo()
818 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_read_rx_fifo()
819 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_read_rx_fifo()
820 const struct i3c_target_callbacks *target_cb = data->target_config->callbacks; in cdns_i3c_target_read_rx_fifo()
823 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_read_rx_fifo()
825 SLV_STATUS0_XFRD_BYTES(sys_read32(config->base + SLV_STATUS0)); in cdns_i3c_target_read_rx_fifo()
827 for (int i = data->fifo_bytes_read; i < xferred_bytes; i += 4) { in cdns_i3c_target_read_rx_fifo()
828 uint32_t rx_data = sys_read32(config->base + RX_FIFO); in cdns_i3c_target_read_rx_fifo()
830 for (int j = 0; j < MIN(4, xferred_bytes - i); j++) { in cdns_i3c_target_read_rx_fifo()
831 target_cb->write_received_cb(data->target_config, in cdns_i3c_target_read_rx_fifo()
836 * store the xfer bytes as the thr interrupt may trigger again as xferred_bytes will in cdns_i3c_target_read_rx_fifo()
839 data->fifo_bytes_read = xferred_bytes; in cdns_i3c_target_read_rx_fifo()
845 uint8_t rx_data = (uint8_t)sys_read32(config->base + RX_FIFO); in cdns_i3c_target_read_rx_fifo()
847 target_cb->write_received_cb(data->target_config, rx_data); in cdns_i3c_target_read_rx_fifo()
856 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_read_rx_fifo()
858 return -EIO; in cdns_i3c_read_rx_fifo()
860 val = sys_le32_to_cpu(sys_read32(config->base + RX_FIFO)); in cdns_i3c_read_rx_fifo()
866 return -EIO; in cdns_i3c_read_rx_fifo()
868 val = sys_le32_to_cpu(sys_read32(config->base + RX_FIFO)); in cdns_i3c_read_rx_fifo()
891 return -EIO; in cdns_i3c_read_rx_fifo_ddr_xfer()
893 val = sys_read32(config->base + RX_FIFO); in cdns_i3c_read_rx_fifo_ddr_xfer()
906 return -EIO; in cdns_i3c_read_rx_fifo_ddr_xfer()
916 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_wait_for_idle()
924 while (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_IDLE)) { in cdns_i3c_wait_for_idle()
925 if (k_cycle_get_32() - start_time > I3C_IDLE_TIMEOUT_CYC) { in cdns_i3c_wait_for_idle()
926 return -EAGAIN; in cdns_i3c_wait_for_idle()
935 struct cdns_i3c_data *data = dev->data; in cdns_i3c_set_prescalers()
936 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_set_prescalers()
937 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_set_prescalers()
940 uint32_t prescl_i3c = DIV_ROUND_UP(config->input_frequency, in cdns_i3c_set_prescalers()
941 (ctrl_config->scl.i3c * I3C_PRESCL_REG_SCALE)) - in cdns_i3c_set_prescalers()
943 uint32_t prescl_i2c = DIV_ROUND_UP(config->input_frequency, in cdns_i3c_set_prescalers()
944 (ctrl_config->scl.i2c * I2C_PRESCL_REG_SCALE)) - in cdns_i3c_set_prescalers()
948 ctrl_config->scl.i3c = config->input_frequency / ((prescl_i3c + 1) * I3C_PRESCL_REG_SCALE); in cdns_i3c_set_prescalers()
949 ctrl_config->scl.i2c = config->input_frequency / ((prescl_i2c + 1) * I2C_PRESCL_REG_SCALE); in cdns_i3c_set_prescalers()
951 LOG_DBG("%s: I3C speed = %u, PRESCL_CTRL0.i3c = 0x%x", dev->name, ctrl_config->scl.i3c, in cdns_i3c_set_prescalers()
953 LOG_DBG("%s: I2C speed = %u, PRESCL_CTRL0.i2c = 0x%x", dev->name, ctrl_config->scl.i2c, in cdns_i3c_set_prescalers()
957 uint32_t pres_step = 1000000000 / (ctrl_config->scl.i3c * 4); in cdns_i3c_set_prescalers()
958 int32_t od_low = DIV_ROUND_UP(I3C_BUS_TLOW_OD_MIN_NS, pres_step) - 2; in cdns_i3c_set_prescalers()
963 LOG_DBG("%s: PRESCL_CTRL1.od_low = 0x%x", dev->name, od_low); in cdns_i3c_set_prescalers()
966 uint32_t ctrl = sys_read32(config->base + CTRL); in cdns_i3c_set_prescalers()
969 sys_write32(~CTRL_DEV_EN & ctrl, config->base + CTRL); in cdns_i3c_set_prescalers()
973 config->base + PRESCL_CTRL0); in cdns_i3c_set_prescalers()
975 /* Sets the open drain low time relative to the push-pull. */ in cdns_i3c_set_prescalers()
977 config->base + PRESCL_CTRL1); in cdns_i3c_set_prescalers()
981 sys_write32(CTRL_DEV_EN | ctrl, config->base + CTRL); in cdns_i3c_set_prescalers()
1017 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_program_controller_retaining_reg()
1018 struct cdns_i3c_data *data = dev->data; in cdns_i3c_program_controller_retaining_reg()
1022 if (!i3c_addr_slots_is_free(&data->common.attached_dev.addr_slots, controller_da)) { in cdns_i3c_program_controller_retaining_reg()
1024 i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots, 0); in cdns_i3c_program_controller_retaining_reg()
1025 LOG_DBG("%s: 0x%02x DA selected for controller", dev->name, controller_da); in cdns_i3c_program_controller_retaining_reg()
1028 config->base + DEV_ID_RR0(0)); in cdns_i3c_program_controller_retaining_reg()
1030 i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, controller_da); in cdns_i3c_program_controller_retaining_reg()
1036 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_ibi_hj_response()
1039 sys_write32(CTRL_HJ_ACK | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_ibi_hj_response()
1041 sys_write32(~CTRL_HJ_ACK & sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_ibi_hj_response()
1051 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_controller_ibi_enable()
1052 struct cdns_i3c_i2c_dev_data *cdns_i3c_device_data = target->controller_priv; in cdns_i3c_controller_ibi_enable()
1058 ret = -EINVAL; in cdns_i3c_controller_ibi_enable()
1064 sir_cfg = SIR_MAP_DEV_ROLE(I3C_BCR_DEVICE_ROLE(target->bcr)) | in cdns_i3c_controller_ibi_enable()
1065 SIR_MAP_DEV_DA(target->dynamic_addr) | in cdns_i3c_controller_ibi_enable()
1066 SIR_MAP_DEV_PL(target->data_length.max_ibi); in cdns_i3c_controller_ibi_enable()
1068 if ((target->ibi_cb != NULL) || i3c_device_is_controller_capable(target)) { in cdns_i3c_controller_ibi_enable()
1071 if (target->bcr & I3C_BCR_MAX_DATA_SPEED_LIMIT) { in cdns_i3c_controller_ibi_enable()
1075 LOG_DBG("%s: IBI enabling for 0x%02x (BCR 0x%02x)", dev->name, target->dynamic_addr, in cdns_i3c_controller_ibi_enable()
1076 target->bcr); in cdns_i3c_controller_ibi_enable()
1082 LOG_ERR("%s: Error sending IBI ENEC for 0x%02x (%d)", dev->name, in cdns_i3c_controller_ibi_enable()
1083 target->dynamic_addr, ret); in cdns_i3c_controller_ibi_enable()
1087 sir_map = sys_read32(config->base + SIR_MAP_DEV_REG(cdns_i3c_device_data->id - 1)); in cdns_i3c_controller_ibi_enable()
1088 sir_map &= ~SIR_MAP_DEV_CONF_MASK(cdns_i3c_device_data->id - 1); in cdns_i3c_controller_ibi_enable()
1089 sir_map |= SIR_MAP_DEV_CONF(cdns_i3c_device_data->id - 1, sir_cfg); in cdns_i3c_controller_ibi_enable()
1091 sys_write32(sir_map, config->base + SIR_MAP_DEV_REG(cdns_i3c_device_data->id - 1)); in cdns_i3c_controller_ibi_enable()
1099 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_controller_ibi_disable()
1100 struct cdns_i3c_i2c_dev_data *cdns_i3c_device_data = target->controller_priv; in cdns_i3c_controller_ibi_disable()
1105 ret = -EINVAL; in cdns_i3c_controller_ibi_disable()
1113 LOG_ERR("%s: Error sending IBI DISEC for 0x%02x (%d)", dev->name, in cdns_i3c_controller_ibi_disable()
1114 target->dynamic_addr, ret); in cdns_i3c_controller_ibi_disable()
1118 sir_map = sys_read32(config->base + SIR_MAP_DEV_REG(cdns_i3c_device_data->id - 1)); in cdns_i3c_controller_ibi_disable()
1119 sir_map &= ~SIR_MAP_DEV_CONF_MASK(cdns_i3c_device_data->id - 1); in cdns_i3c_controller_ibi_disable()
1121 SIR_MAP_DEV_CONF(cdns_i3c_device_data->id - 1, SIR_MAP_DEV_DA(I3C_BROADCAST_ADDR)); in cdns_i3c_controller_ibi_disable()
1122 sys_write32(sir_map, config->base + SIR_MAP_DEV_REG(cdns_i3c_device_data->id - 1)); in cdns_i3c_controller_ibi_disable()
1129 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_ibi_raise_hj()
1130 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_raise_hj()
1131 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_target_ibi_raise_hj()
1134 if (!ctrl_config->is_secondary) { in cdns_i3c_target_ibi_raise_hj()
1135 LOG_ERR("%s: controller is primary, HJ not available", dev->name); in cdns_i3c_target_ibi_raise_hj()
1136 return -ENOTSUP; in cdns_i3c_target_ibi_raise_hj()
1139 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_HAS_DA) { in cdns_i3c_target_ibi_raise_hj()
1140 LOG_ERR("%s: HJ not available, DA already assigned", dev->name); in cdns_i3c_target_ibi_raise_hj()
1141 return -EACCES; in cdns_i3c_target_ibi_raise_hj()
1144 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_HJ_DIS) { in cdns_i3c_target_ibi_raise_hj()
1145 LOG_ERR("%s: HJ requests are currently disabled by DISEC", dev->name); in cdns_i3c_target_ibi_raise_hj()
1146 return -EAGAIN; in cdns_i3c_target_ibi_raise_hj()
1149 sys_write32(CTRL_HJ_INIT | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_target_ibi_raise_hj()
1150 k_sem_reset(&data->ibi_hj_complete); in cdns_i3c_target_ibi_raise_hj()
1151 if (k_sem_take(&data->ibi_hj_complete, K_MSEC(500)) != 0) { in cdns_i3c_target_ibi_raise_hj()
1152 LOG_ERR("%s: timeout waiting for DAA after HJ", dev->name); in cdns_i3c_target_ibi_raise_hj()
1153 return -ETIMEDOUT; in cdns_i3c_target_ibi_raise_hj()
1160 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_ibi_raise_cr()
1161 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_raise_cr()
1164 if (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_HAS_DA)) { in cdns_i3c_target_ibi_raise_cr()
1165 LOG_ERR("%s: CR not available, DA not assigned", dev->name); in cdns_i3c_target_ibi_raise_cr()
1166 return -EACCES; in cdns_i3c_target_ibi_raise_cr()
1169 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_MR_DIS) { in cdns_i3c_target_ibi_raise_cr()
1170 LOG_ERR("%s: CR requests are currently disabled by DISEC", dev->name); in cdns_i3c_target_ibi_raise_cr()
1171 return -EAGAIN; in cdns_i3c_target_ibi_raise_cr()
1174 sys_write32(CTRL_MST_INIT | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_target_ibi_raise_cr()
1175 k_sem_reset(&data->ibi_cr_complete); in cdns_i3c_target_ibi_raise_cr()
1176 if (k_sem_take(&data->ibi_cr_complete, K_MSEC(500)) != 0) { in cdns_i3c_target_ibi_raise_cr()
1177 LOG_ERR("%s: timeout waiting for GETACCCR after CR", dev->name); in cdns_i3c_target_ibi_raise_cr()
1178 return -ETIMEDOUT; in cdns_i3c_target_ibi_raise_cr()
1185 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_ibi_raise_intr()
1186 const struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_raise_intr()
1189 LOG_DBG("%s: issuing IBI TIR", dev->name); in cdns_i3c_target_ibi_raise_intr()
1192 if (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_HAS_DA)) { in cdns_i3c_target_ibi_raise_intr()
1193 LOG_ERR("%s: TIR not available, DA not assigned", dev->name); in cdns_i3c_target_ibi_raise_intr()
1194 return -EACCES; in cdns_i3c_target_ibi_raise_intr()
1197 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_IBI_DIS) { in cdns_i3c_target_ibi_raise_intr()
1198 LOG_ERR("%s: TIR requests are currently disabled by DISEC", dev->name); in cdns_i3c_target_ibi_raise_intr()
1199 return -EAGAIN; in cdns_i3c_target_ibi_raise_intr()
1209 if (request->payload_len > data->hw_cfg.ibi_mem_depth) { in cdns_i3c_target_ibi_raise_intr()
1210 LOG_ERR("%s: payload too large for IBI TIR", dev->name); in cdns_i3c_target_ibi_raise_intr()
1211 return -ENOMEM; in cdns_i3c_target_ibi_raise_intr()
1214 cdns_i3c_write_ibi_fifo(config, request->payload, request->payload_len); in cdns_i3c_target_ibi_raise_intr()
1217 ibi_ctrl_val = sys_read32(config->base + SLV_IBI_CTRL); in cdns_i3c_target_ibi_raise_intr()
1218 ibi_ctrl_val |= SLV_IBI_PL(request->payload_len); in cdns_i3c_target_ibi_raise_intr()
1220 sys_write32(ibi_ctrl_val, config->base + SLV_IBI_CTRL); in cdns_i3c_target_ibi_raise_intr()
1226 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_ibi_raise()
1227 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_raise()
1232 if (sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE) { in cdns_i3c_target_ibi_raise()
1233 return -EACCES; in cdns_i3c_target_ibi_raise()
1236 switch (request->ibi_type) { in cdns_i3c_target_ibi_raise()
1239 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_ibi_raise()
1242 return -ENOTSUP; in cdns_i3c_target_ibi_raise()
1249 return -EINVAL; in cdns_i3c_target_ibi_raise()
1256 struct cdns_i3c_data *data = dev->data; in cdns_i3c_cancel_transfer()
1257 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_cancel_transfer()
1262 sys_write32(MST_INT_CMDD_EMP, config->base + MST_IDR); in cdns_i3c_cancel_transfer()
1265 if (data->xfer.num_cmds == 0) { in cdns_i3c_cancel_transfer()
1269 data->xfer.num_cmds = 0; in cdns_i3c_cancel_transfer()
1272 sys_write32(~CTRL_DEV_EN & sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_cancel_transfer()
1280 while (retry_count--) { in cdns_i3c_cancel_transfer()
1281 val = sys_read32(config->base + MST_STATUS0); in cdns_i3c_cancel_transfer()
1288 data->xfer.ret = -ETIMEDOUT; in cdns_i3c_cancel_transfer()
1295 config->base + FLUSH_CTRL); in cdns_i3c_cancel_transfer()
1297 /* Re-enable device */ in cdns_i3c_cancel_transfer()
1298 sys_write32(CTRL_DEV_EN | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_cancel_transfer()
1311 struct cdns_i3c_data *data = dev->data; in cdns_i3c_start_transfer()
1312 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_start_transfer()
1313 struct cdns_i3c_xfer *xfer = &data->xfer; in cdns_i3c_start_transfer() local
1316 sys_write32(MST_INT_CMDD_EMP, config->base + MST_ICR); in cdns_i3c_start_transfer()
1320 (void)sys_read32(config->base + RX_FIFO); in cdns_i3c_start_transfer()
1324 (void)sys_read32(config->base + CMDR); in cdns_i3c_start_transfer()
1328 for (unsigned int i = 0; i < xfer->num_cmds; i++) { in cdns_i3c_start_transfer()
1329 if (xfer->cmds[i].hdr == I3C_DATA_RATE_SDR) { in cdns_i3c_start_transfer()
1330 if (!(xfer->cmds[i].cmd0 & CMD0_FIFO_RNW)) { in cdns_i3c_start_transfer()
1331 cdns_i3c_write_tx_fifo(config, xfer->cmds[i].buf, in cdns_i3c_start_transfer()
1332 xfer->cmds[i].len); in cdns_i3c_start_transfer()
1334 } else if (xfer->cmds[i].hdr == I3C_DATA_RATE_HDR_DDR) { in cdns_i3c_start_transfer()
1335 /* DDR Xfer requires sending header block*/ in cdns_i3c_start_transfer()
1336 cdns_i3c_write_tx_fifo(config, &xfer->cmds[i].ddr_header, in cdns_i3c_start_transfer()
1339 if (!(DDR_DATA(xfer->cmds[i].ddr_header) & HDR_CMD_RD)) { in cdns_i3c_start_transfer()
1340 uint8_t *buf = (uint8_t *)xfer->cmds[i].buf; in cdns_i3c_start_transfer()
1343 /* HDR-DDR Data Words */ in cdns_i3c_start_transfer()
1348 for (int j = 2; j < ((xfer->cmds[i].len - 2) * 2); j += 2) { in cdns_i3c_start_transfer()
1355 /* HDR-DDR CRC Word */ in cdns_i3c_start_transfer()
1356 cdns_i3c_write_tx_fifo(config, &xfer->cmds[i].ddr_crc, in cdns_i3c_start_transfer()
1360 xfer->ret = -ENOTSUP; in cdns_i3c_start_transfer()
1366 for (unsigned int i = 0; i < xfer->num_cmds; i++) { in cdns_i3c_start_transfer()
1368 xfer->cmds[i].cmd1 |= CMD1_FIFO_CMDID(i); in cdns_i3c_start_transfer()
1369 sys_write32(xfer->cmds[i].cmd1, config->base + CMD1_FIFO); in cdns_i3c_start_transfer()
1370 sys_write32(xfer->cmds[i].cmd0, config->base + CMD0_FIFO); in cdns_i3c_start_transfer()
1372 if (xfer->cmds[i].hdr == I3C_DATA_RATE_HDR_DDR) { in cdns_i3c_start_transfer()
1373 sys_write32(0x00, config->base + CMD1_FIFO); in cdns_i3c_start_transfer()
1374 if ((DDR_DATA(xfer->cmds[i].ddr_header) & HDR_CMD_RD)) { in cdns_i3c_start_transfer()
1376 config->base + CMD0_FIFO); in cdns_i3c_start_transfer()
1378 sys_write32(CMD0_FIFO_IS_DDR | CMD0_FIFO_PL_LEN(xfer->cmds[i].len), in cdns_i3c_start_transfer()
1379 config->base + CMD0_FIFO); in cdns_i3c_start_transfer()
1385 sys_write32(CTRL_MCS | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_start_transfer()
1386 sys_write32(MST_INT_CMDD_EMP, config->base + MST_IER); in cdns_i3c_start_transfer()
1401 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_do_ccc()
1402 struct cdns_i3c_data *data = dev->data; in cdns_i3c_do_ccc()
1408 if (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE)) { in cdns_i3c_do_ccc()
1409 return -EACCES; in cdns_i3c_do_ccc()
1413 return -EINVAL; in cdns_i3c_do_ccc()
1424 1 + ((payload->ccc.data_len > 0) ? payload->targets.num_targets in cdns_i3c_do_ccc()
1425 : MAX(payload->targets.num_targets - 1, 0)); in cdns_i3c_do_ccc()
1426 if (num_msgs > data->hw_cfg.cmd_mem_depth || num_msgs > data->hw_cfg.cmdr_mem_depth) { in cdns_i3c_do_ccc()
1427 LOG_ERR("%s: Too many messages", dev->name); in cdns_i3c_do_ccc()
1428 return -ENOMEM; in cdns_i3c_do_ccc()
1434 i3c_ccc_is_payload_broadcast(payload) ? ROUND_UP(payload->ccc.data_len, 4) : 0; in cdns_i3c_do_ccc()
1436 for (int i = 0; i < payload->targets.num_targets; i++) { in cdns_i3c_do_ccc()
1437 if (payload->targets.payloads[i].rnw) { in cdns_i3c_do_ccc()
1438 rxsize += ROUND_UP(payload->targets.payloads[i].data_len, 4); in cdns_i3c_do_ccc()
1440 txsize += ROUND_UP(payload->targets.payloads[i].data_len, 4); in cdns_i3c_do_ccc()
1443 if ((rxsize > data->hw_cfg.rx_mem_depth) || (txsize > data->hw_cfg.tx_mem_depth)) { in cdns_i3c_do_ccc()
1444 LOG_ERR("%s: Total RX and/or TX transfer larger than FIFO", dev->name); in cdns_i3c_do_ccc()
1445 return -ENOMEM; in cdns_i3c_do_ccc()
1448 LOG_DBG("%s: CCC[0x%02x]", dev->name, payload->ccc.id); in cdns_i3c_do_ccc()
1450 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_do_ccc()
1463 for (int i = 0; i < payload->targets.num_targets; i++) { in cdns_i3c_do_ccc()
1464 cmd = &data->xfer.cmds[i]; in cdns_i3c_do_ccc()
1466 cmd->cmd1 = CMD1_FIFO_CCC(payload->ccc.id); in cdns_i3c_do_ccc()
1467 cmd->cmd0 = CMD0_FIFO_IS_CCC; in cdns_i3c_do_ccc()
1469 if (payload->ccc.data_len == 1) { in cdns_i3c_do_ccc()
1471 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_do_ccc()
1472 cmd->cmd0 |= CMD0_FIFO_IS_DB; in cdns_i3c_do_ccc()
1473 cmd->cmd1 |= CMD1_FIFO_DB(payload->ccc.data[0]); in cdns_i3c_do_ccc()
1477 dev->name, REV_ID_REV_MAJOR(data->hw_cfg.rev_id), in cdns_i3c_do_ccc()
1478 REV_ID_REV_MINOR(data->hw_cfg.rev_id)); in cdns_i3c_do_ccc()
1479 ret = -ENOTSUP; in cdns_i3c_do_ccc()
1482 } else if (payload->ccc.data_len > 1) { in cdns_i3c_do_ccc()
1483 LOG_ERR("%s: Defining Byte length greater than 1", dev->name); in cdns_i3c_do_ccc()
1484 ret = -EINVAL; in cdns_i3c_do_ccc()
1492 cmd->cmd0 |= CMD0_FIFO_BCH; in cdns_i3c_do_ccc()
1494 if (i < (payload->targets.num_targets - 1)) { in cdns_i3c_do_ccc()
1495 cmd->cmd0 |= CMD0_FIFO_RSBC; in cdns_i3c_do_ccc()
1497 cmd->buf = payload->targets.payloads[i].data; in cdns_i3c_do_ccc()
1498 cmd->len = payload->targets.payloads[i].data_len; in cdns_i3c_do_ccc()
1499 cmd->cmd0 |= CMD0_FIFO_DEV_ADDR(payload->targets.payloads[i].addr) | in cdns_i3c_do_ccc()
1500 CMD0_FIFO_PL_LEN(payload->targets.payloads[i].data_len); in cdns_i3c_do_ccc()
1501 if (payload->targets.payloads[i].rnw) { in cdns_i3c_do_ccc()
1502 cmd->cmd0 |= CMD0_FIFO_RNW; in cdns_i3c_do_ccc()
1504 cmd->hdr = I3C_DATA_RATE_SDR; in cdns_i3c_do_ccc()
1509 cmd->num_xfer = &(payload->targets.payloads[i].num_xfer); in cdns_i3c_do_ccc()
1510 cmd->sdr_err = &(payload->targets.payloads[i].err); in cdns_i3c_do_ccc()
1513 cmd = &data->xfer.cmds[0]; in cdns_i3c_do_ccc()
1515 cmd->cmd1 = CMD1_FIFO_CCC(payload->ccc.id); in cdns_i3c_do_ccc()
1516 cmd->cmd0 = CMD0_FIFO_IS_CCC | CMD0_FIFO_BCH; in cdns_i3c_do_ccc()
1517 cmd->hdr = I3C_DATA_RATE_SDR; in cdns_i3c_do_ccc()
1519 if (payload->ccc.data_len > 0) { in cdns_i3c_do_ccc()
1521 cmd->buf = payload->ccc.data; in cdns_i3c_do_ccc()
1522 cmd->len = payload->ccc.data_len; in cdns_i3c_do_ccc()
1523 cmd->cmd0 |= CMD0_FIFO_PL_LEN(payload->ccc.data_len); in cdns_i3c_do_ccc()
1527 cmd->num_xfer = &(payload->ccc.num_xfer); in cdns_i3c_do_ccc()
1530 cmd->len = 0; in cdns_i3c_do_ccc()
1531 cmd->num_xfer = NULL; in cdns_i3c_do_ccc()
1533 cmd->sdr_err = &(payload->ccc.err); in cdns_i3c_do_ccc()
1536 data->xfer.ret = -ETIMEDOUT; in cdns_i3c_do_ccc()
1537 data->xfer.num_cmds = num_cmds; in cdns_i3c_do_ccc()
1540 if (k_sem_take(&data->xfer.complete, K_MSEC(1000)) != 0) { in cdns_i3c_do_ccc()
1544 if (data->xfer.ret < 0) { in cdns_i3c_do_ccc()
1545 LOG_ERR("%s: CCC[0x%02x] error (%d)", dev->name, payload->ccc.id, data->xfer.ret); in cdns_i3c_do_ccc()
1548 ret = data->xfer.ret; in cdns_i3c_do_ccc()
1552 if (payload->ccc.id == I3C_CCC_GETACCCR) { in cdns_i3c_do_ccc()
1553 ret = k_sem_take(&data->ch_complete, K_MSEC(1000)); in cdns_i3c_do_ccc()
1556 k_mutex_unlock(&data->bus_lock); in cdns_i3c_do_ccc()
1572 struct cdns_i3c_data *data = dev->data; in cdns_i3c_do_daa()
1573 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_do_daa()
1574 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_do_daa()
1578 if (ctrl_config->is_secondary) { in cdns_i3c_do_daa()
1579 return -EACCES; in cdns_i3c_do_daa()
1583 uint32_t olddevs = sys_read32(config->base + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; in cdns_i3c_do_daa()
1589 for (uint8_t i = find_lsb_set(~olddevs); i <= data->max_devs; i++) { in cdns_i3c_do_daa()
1590 uint8_t rr_idx = i - 1; in cdns_i3c_do_daa()
1595 &data->common.attached_dev.addr_slots, last_addr + 1); in cdns_i3c_do_daa()
1598 config->base + DEV_ID_RR0(rr_idx)); in cdns_i3c_do_daa()
1599 sys_write32(0, config->base + DEV_ID_RR1(rr_idx)); in cdns_i3c_do_daa()
1600 sys_write32(0, config->base + DEV_ID_RR2(rr_idx)); in cdns_i3c_do_daa()
1617 uint32_t newdevs = sys_read32(config->base + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; in cdns_i3c_do_daa()
1624 uint8_t rr_idx = i - 1; in cdns_i3c_do_daa()
1628 uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(rr_idx)); in cdns_i3c_do_daa()
1629 uint32_t dev_id_rr1 = sys_read32(config->base + DEV_ID_RR1(rr_idx)); in cdns_i3c_do_daa()
1630 uint32_t dev_id_rr2 = sys_read32(config->base + DEV_ID_RR2(rr_idx)); in cdns_i3c_do_daa()
1648 *(const struct device **)&target->bus = dev; in cdns_i3c_do_daa()
1649 *(uint64_t *)&target->pid = pid; in cdns_i3c_do_daa()
1650 target->dynamic_addr = dyn_addr; in cdns_i3c_do_daa()
1651 target->bcr = bcr; in cdns_i3c_do_daa()
1652 target->dcr = dcr; in cdns_i3c_do_daa()
1655 &data->common.attached_dev.devices.i3c, in cdns_i3c_do_daa()
1656 &target->node); in cdns_i3c_do_daa()
1658 data->cdns_i3c_i2c_priv_data[rr_idx].id = rr_idx; in cdns_i3c_do_daa()
1659 target->controller_priv = in cdns_i3c_do_daa()
1660 &(data->cdns_i3c_i2c_priv_data[rr_idx]); in cdns_i3c_do_daa()
1665 dev->name, pid, dyn_addr); in cdns_i3c_do_daa()
1667 target->dynamic_addr = dyn_addr; in cdns_i3c_do_daa()
1668 target->bcr = bcr; in cdns_i3c_do_daa()
1669 target->dcr = dcr; in cdns_i3c_do_daa()
1671 data->cdns_i3c_i2c_priv_data[rr_idx].id = rr_idx; in cdns_i3c_do_daa()
1672 target->controller_priv = in cdns_i3c_do_daa()
1673 &(data->cdns_i3c_i2c_priv_data[rr_idx]); in cdns_i3c_do_daa()
1676 dev->name, pid, dyn_addr); in cdns_i3c_do_daa()
1678 i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, in cdns_i3c_do_daa()
1683 LOG_DBG("%s: ENTDAA: No devices found", dev->name); in cdns_i3c_do_daa()
1687 data->free_rr_slots &= ~newdevs; in cdns_i3c_do_daa()
1689 /* Unmask Hot-Join request interrupts. HJ will send DISEC HJ from the CTRL value */ in cdns_i3c_do_daa()
1695 LOG_DBG("%s: Broadcast ENEC was NACK", dev->name); in cdns_i3c_do_daa()
1708 * @retval -EINVAL If invalid configure parameters.
1709 * @retval -EIO General Input/Output errors.
1710 * @retval -ENOSYS If not implemented.
1714 struct cdns_i3c_data *data = dev->data; in cdns_i3c_i2c_api_configure()
1715 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_i2c_api_configure()
1719 ctrl_config->scl.i2c = 100000; in cdns_i3c_i2c_api_configure()
1722 ctrl_config->scl.i2c = 400000; in cdns_i3c_i2c_api_configure()
1725 ctrl_config->scl.i2c = 1000000; in cdns_i3c_i2c_api_configure()
1728 ctrl_config->scl.i2c = 3400000; in cdns_i3c_i2c_api_configure()
1731 ctrl_config->scl.i2c = 5000000; in cdns_i3c_i2c_api_configure()
1737 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_i2c_api_configure()
1739 k_mutex_unlock(&data->bus_lock); in cdns_i3c_i2c_api_configure()
1753 * @retval -EINVAL If invalid configure parameters.
1754 * @retval -EIO General Input/Output errors.
1755 * @retval -ENOSYS If not implemented.
1759 struct cdns_i3c_data *data = dev->data; in cdns_i3c_configure()
1762 if ((ctrl_cfg->scl.i2c == 0U) || (ctrl_cfg->scl.i3c == 0U)) { in cdns_i3c_configure()
1763 return -EINVAL; in cdns_i3c_configure()
1766 data->common.ctrl_config.scl.i3c = ctrl_cfg->scl.i3c; in cdns_i3c_configure()
1767 data->common.ctrl_config.scl.i2c = ctrl_cfg->scl.i2c; in cdns_i3c_configure()
1769 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_configure()
1771 k_mutex_unlock(&data->bus_lock); in cdns_i3c_configure()
1787 struct cdns_i3c_data *data = dev->data; in cdns_i3c_complete_transfer()
1788 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_complete_transfer()
1791 uint32_t xfer = 0; in cdns_i3c_complete_transfer() local
1800 sys_write32(MST_INT_CMDD_EMP, config->base + MST_IDR); in cdns_i3c_complete_transfer()
1803 if (data->xfer.num_cmds == 0) { in cdns_i3c_complete_transfer()
1808 for (uint32_t status0 = sys_read32(config->base + MST_STATUS0); in cdns_i3c_complete_transfer()
1809 !(status0 & MST_STATUS0_CMDR_EMP); status0 = sys_read32(config->base + MST_STATUS0)) { in cdns_i3c_complete_transfer()
1810 cmdr = sys_read32(config->base + CMDR); in cdns_i3c_complete_transfer()
1814 id >= data->xfer.num_cmds) { in cdns_i3c_complete_transfer()
1818 cmd = &data->xfer.cmds[id]; in cdns_i3c_complete_transfer()
1820 xfer = MIN(CMDR_XFER_BYTES(cmdr), cmd->len); in cdns_i3c_complete_transfer()
1821 if (cmd->num_xfer != NULL) { in cdns_i3c_complete_transfer()
1822 *cmd->num_xfer = xfer; in cdns_i3c_complete_transfer()
1825 if (cmd->cmd0 & CMD0_FIFO_RNW) { in cdns_i3c_complete_transfer()
1826 ret = cdns_i3c_read_rx_fifo(config, cmd->buf, xfer); in cdns_i3c_complete_transfer()
1829 if ((cmd->hdr == I3C_DATA_RATE_HDR_DDR) && in cdns_i3c_complete_transfer()
1830 (DDR_DATA(cmd->ddr_header) & HDR_CMD_RD)) { in cdns_i3c_complete_transfer()
1831 ret = cdns_i3c_read_rx_fifo_ddr_xfer(config, cmd->buf, xfer, in cdns_i3c_complete_transfer()
1832 cmd->ddr_header); in cdns_i3c_complete_transfer()
1836 cmd->error = CMDR_ERROR(cmdr); in cdns_i3c_complete_transfer()
1839 for (int i = 0; i < data->xfer.num_cmds; i++) { in cdns_i3c_complete_transfer()
1840 switch (data->xfer.cmds[i].error) { in cdns_i3c_complete_transfer()
1842 if (data->xfer.cmds[i].sdr_err) { in cdns_i3c_complete_transfer()
1843 *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_NONE; in cdns_i3c_complete_transfer()
1857 * some targets will just auto-increment the read address in cdns_i3c_complete_transfer()
1860 if ((was_full) && (data->xfer.cmds[i].len > *data->xfer.cmds[i].num_xfer)) { in cdns_i3c_complete_transfer()
1861 ret = -ENOSPC; in cdns_i3c_complete_transfer()
1865 dev->name); in cdns_i3c_complete_transfer()
1867 if (data->xfer.cmds[i].sdr_err) { in cdns_i3c_complete_transfer()
1868 *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_NONE; in cdns_i3c_complete_transfer()
1873 uint8_t ccc = data->xfer.cmds[i].cmd1 & 0xFF; in cdns_i3c_complete_transfer()
1889 if ((*data->xfer.cmds[i].num_xfer != in cdns_i3c_complete_transfer()
1891 (*data->xfer.cmds[i].num_xfer != in cdns_i3c_complete_transfer()
1893 ret = -EIO; in cdns_i3c_complete_transfer()
1896 /* GETCAPS can only return 1-4 bytes */ in cdns_i3c_complete_transfer()
1897 if (*data->xfer.cmds[i].num_xfer > sizeof(union i3c_ccc_getcaps)) { in cdns_i3c_complete_transfer()
1898 ret = -EIO; in cdns_i3c_complete_transfer()
1901 if (data->xfer.cmds[i].sdr_err) { in cdns_i3c_complete_transfer()
1902 *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE0; in cdns_i3c_complete_transfer()
1904 ret = -EIO; in cdns_i3c_complete_transfer()
1910 if (data->xfer.cmds[i].sdr_err) { in cdns_i3c_complete_transfer()
1911 *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE1; in cdns_i3c_complete_transfer()
1913 ret = -EIO; in cdns_i3c_complete_transfer()
1916 if (data->xfer.cmds[i].sdr_err) { in cdns_i3c_complete_transfer()
1917 *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE2; in cdns_i3c_complete_transfer()
1919 ret = -EIO; in cdns_i3c_complete_transfer()
1926 if (data->xfer.cmds[i].sdr_err) { in cdns_i3c_complete_transfer()
1927 *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_UNKNOWN; in cdns_i3c_complete_transfer()
1929 ret = -EIO; in cdns_i3c_complete_transfer()
1934 if (data->xfer.cmds[i].sdr_err) { in cdns_i3c_complete_transfer()
1935 *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_UNKNOWN; in cdns_i3c_complete_transfer()
1937 ret = -ENOSPC; in cdns_i3c_complete_transfer()
1942 if (data->xfer.cmds[i].sdr_err) { in cdns_i3c_complete_transfer()
1943 *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_UNKNOWN; in cdns_i3c_complete_transfer()
1945 ret = -EINVAL; in cdns_i3c_complete_transfer()
1950 data->xfer.ret = ret; in cdns_i3c_complete_transfer()
1953 data->xfer.num_cmds = 0; in cdns_i3c_complete_transfer()
1955 k_sem_give(&data->xfer.complete); in cdns_i3c_complete_transfer()
1967 * @retval -EIO General input / output error.
1968 * @retval -EINVAL Address not registered
1973 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_i2c_transfer()
1974 struct cdns_i3c_data *data = dev->data; in cdns_i3c_i2c_transfer()
1980 if (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE)) { in cdns_i3c_i2c_transfer()
1981 return -EACCES; in cdns_i3c_i2c_transfer()
1988 if (num_msgs > data->hw_cfg.cmd_mem_depth || num_msgs > data->hw_cfg.cmdr_mem_depth) { in cdns_i3c_i2c_transfer()
1989 LOG_ERR("%s: Too many messages", dev->name); in cdns_i3c_i2c_transfer()
1990 return -ENOMEM; in cdns_i3c_i2c_transfer()
2003 if ((rxsize > data->hw_cfg.rx_mem_depth) || (txsize > data->hw_cfg.tx_mem_depth)) { in cdns_i3c_i2c_transfer()
2004 LOG_ERR("%s: Total RX and/or TX transfer larger than FIFO", dev->name); in cdns_i3c_i2c_transfer()
2005 return -ENOMEM; in cdns_i3c_i2c_transfer()
2008 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_i2c_transfer()
2017 struct cdns_i3c_cmd *cmd = &data->xfer.cmds[i]; in cdns_i3c_i2c_transfer()
2019 cmd->len = msgs[i].len; in cdns_i3c_i2c_transfer()
2020 cmd->buf = msgs[i].buf; in cdns_i3c_i2c_transfer()
2022 cmd->hdr = I3C_DATA_RATE_SDR; in cdns_i3c_i2c_transfer()
2024 cmd->cmd0 = CMD0_FIFO_PRIV_XMIT_MODE(XMIT_BURST_WITHOUT_SUBADDR); in cdns_i3c_i2c_transfer()
2025 cmd->cmd0 |= CMD0_FIFO_DEV_ADDR(i2c_dev->addr); in cdns_i3c_i2c_transfer()
2026 cmd->cmd0 |= CMD0_FIFO_PL_LEN(msgs[i].len); in cdns_i3c_i2c_transfer()
2029 if ((i < (num_msgs - 1)) && ((msgs[i].flags & I2C_MSG_STOP) == 0)) { in cdns_i3c_i2c_transfer()
2030 cmd->cmd0 |= CMD0_FIFO_RSBC; in cdns_i3c_i2c_transfer()
2034 cmd->cmd0 |= CMD0_FIFO_IS_10B; in cdns_i3c_i2c_transfer()
2038 cmd->cmd0 |= CMD0_FIFO_RNW; in cdns_i3c_i2c_transfer()
2042 cmd->num_xfer = NULL; in cdns_i3c_i2c_transfer()
2043 cmd->sdr_err = NULL; in cdns_i3c_i2c_transfer()
2046 data->xfer.ret = -ETIMEDOUT; in cdns_i3c_i2c_transfer()
2047 data->xfer.num_cmds = num_msgs; in cdns_i3c_i2c_transfer()
2050 if (k_sem_take(&data->xfer.complete, K_MSEC(1000)) != 0) { in cdns_i3c_i2c_transfer()
2054 ret = data->xfer.ret; in cdns_i3c_i2c_transfer()
2056 k_mutex_unlock(&data->bus_lock); in cdns_i3c_i2c_transfer()
2063 struct cdns_i3c_data *data = dev->data; in cdns_i3c_master_get_rr_slot()
2064 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_master_get_rr_slot()
2070 if (!data->free_rr_slots) { in cdns_i3c_master_get_rr_slot()
2071 return -ENOSPC; in cdns_i3c_master_get_rr_slot()
2074 return find_lsb_set(data->free_rr_slots) - 1; in cdns_i3c_master_get_rr_slot()
2078 activedevs = sys_read32(config->base + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; in cdns_i3c_master_get_rr_slot()
2084 rr_idx = i - 1; in cdns_i3c_master_get_rr_slot()
2086 rr = sys_read32(config->base + DEV_ID_RR0(rr_idx)); in cdns_i3c_master_get_rr_slot()
2093 return -EINVAL; in cdns_i3c_master_get_rr_slot()
2107 if ((desc->static_addr != 0) || (desc->dynamic_addr != 0)) { in cdns_i3c_attach_device()
2108 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_attach_device()
2109 struct cdns_i3c_data *data = dev->data; in cdns_i3c_attach_device()
2111 int slot = cdns_i3c_master_get_rr_slot(dev, desc->dynamic_addr); in cdns_i3c_attach_device()
2114 LOG_ERR("%s: no space for i3c device: %s", dev->name, desc->dev->name); in cdns_i3c_attach_device()
2118 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_attach_device()
2120 sys_write32(sys_read32(config->base + DEVS_CTRL) | DEVS_CTRL_DEV_ACTIVE(slot), in cdns_i3c_attach_device()
2121 config->base + DEVS_CTRL); in cdns_i3c_attach_device()
2123 data->cdns_i3c_i2c_priv_data[slot].id = slot; in cdns_i3c_attach_device()
2124 desc->controller_priv = &(data->cdns_i3c_i2c_priv_data[slot]); in cdns_i3c_attach_device()
2125 data->free_rr_slots &= ~BIT(slot); in cdns_i3c_attach_device()
2129 prepare_rr0_dev_address(desc->dynamic_addr ? desc->dynamic_addr in cdns_i3c_attach_device()
2130 : desc->static_addr); in cdns_i3c_attach_device()
2131 uint32_t dev_id_rr1 = DEV_ID_RR1_PID_MSB((desc->pid & 0xFFFFFFFF0000) >> 16); in cdns_i3c_attach_device()
2132 uint32_t dev_id_rr2 = DEV_ID_RR2_PID_LSB(desc->pid & 0xFFFF); in cdns_i3c_attach_device()
2134 sys_write32(dev_id_rr0, config->base + DEV_ID_RR0(slot)); in cdns_i3c_attach_device()
2135 sys_write32(dev_id_rr1, config->base + DEV_ID_RR1(slot)); in cdns_i3c_attach_device()
2136 sys_write32(dev_id_rr2, config->base + DEV_ID_RR2(slot)); in cdns_i3c_attach_device()
2138 k_mutex_unlock(&data->bus_lock); in cdns_i3c_attach_device()
2147 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_reattach_device()
2148 struct cdns_i3c_data *data = dev->data; in cdns_i3c_reattach_device()
2149 struct cdns_i3c_i2c_dev_data *cdns_i3c_device_data = desc->controller_priv; in cdns_i3c_reattach_device()
2152 LOG_ERR("%s: %s: device not attached", dev->name, desc->dev->name); in cdns_i3c_reattach_device()
2153 return -EINVAL; in cdns_i3c_reattach_device()
2156 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_reattach_device()
2158 uint32_t dev_id_rr0 = DEV_ID_RR0_IS_I3C | prepare_rr0_dev_address(desc->dynamic_addr); in cdns_i3c_reattach_device()
2159 uint32_t dev_id_rr1 = DEV_ID_RR1_PID_MSB((desc->pid & 0xFFFFFFFF0000) >> 16); in cdns_i3c_reattach_device()
2160 uint32_t dev_id_rr2 = DEV_ID_RR2_PID_LSB(desc->pid & 0xFFFF) | DEV_ID_RR2_BCR(desc->bcr) | in cdns_i3c_reattach_device()
2161 DEV_ID_RR2_DCR(desc->dcr); in cdns_i3c_reattach_device()
2163 sys_write32(dev_id_rr0, config->base + DEV_ID_RR0(cdns_i3c_device_data->id)); in cdns_i3c_reattach_device()
2164 sys_write32(dev_id_rr1, config->base + DEV_ID_RR1(cdns_i3c_device_data->id)); in cdns_i3c_reattach_device()
2165 sys_write32(dev_id_rr2, config->base + DEV_ID_RR2(cdns_i3c_device_data->id)); in cdns_i3c_reattach_device()
2167 k_mutex_unlock(&data->bus_lock); in cdns_i3c_reattach_device()
2174 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_detach_device()
2175 struct cdns_i3c_data *data = dev->data; in cdns_i3c_detach_device()
2176 struct cdns_i3c_i2c_dev_data *cdns_i3c_device_data = desc->controller_priv; in cdns_i3c_detach_device()
2179 LOG_ERR("%s: %s: device not attached", dev->name, desc->dev->name); in cdns_i3c_detach_device()
2180 return -EINVAL; in cdns_i3c_detach_device()
2183 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_detach_device()
2185 sys_write32(sys_read32(config->base + DEVS_CTRL) | in cdns_i3c_detach_device()
2186 DEVS_CTRL_DEV_CLR(cdns_i3c_device_data->id), in cdns_i3c_detach_device()
2187 config->base + DEVS_CTRL); in cdns_i3c_detach_device()
2188 data->free_rr_slots |= BIT(cdns_i3c_device_data->id); in cdns_i3c_detach_device()
2189 desc->controller_priv = NULL; in cdns_i3c_detach_device()
2191 k_mutex_unlock(&data->bus_lock); in cdns_i3c_detach_device()
2198 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_i2c_attach_device()
2199 struct cdns_i3c_data *data = dev->data; in cdns_i3c_i2c_attach_device()
2204 LOG_ERR("%s: no space for i2c device: addr 0x%02x", dev->name, desc->addr); in cdns_i3c_i2c_attach_device()
2208 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_i2c_attach_device()
2210 uint32_t dev_id_rr0 = prepare_rr0_dev_address(desc->addr); in cdns_i3c_i2c_attach_device()
2211 uint32_t dev_id_rr2 = DEV_ID_RR2_LVR(desc->lvr); in cdns_i3c_i2c_attach_device()
2213 sys_write32(dev_id_rr0, config->base + DEV_ID_RR0(slot)); in cdns_i3c_i2c_attach_device()
2214 sys_write32(0, config->base + DEV_ID_RR1(slot)); in cdns_i3c_i2c_attach_device()
2215 sys_write32(dev_id_rr2, config->base + DEV_ID_RR2(slot)); in cdns_i3c_i2c_attach_device()
2217 data->cdns_i3c_i2c_priv_data[slot].id = slot; in cdns_i3c_i2c_attach_device()
2218 desc->controller_priv = &(data->cdns_i3c_i2c_priv_data[slot]); in cdns_i3c_i2c_attach_device()
2219 data->free_rr_slots &= ~BIT(slot); in cdns_i3c_i2c_attach_device()
2221 sys_write32(sys_read32(config->base + DEVS_CTRL) | DEVS_CTRL_DEV_ACTIVE(slot), in cdns_i3c_i2c_attach_device()
2222 config->base + DEVS_CTRL); in cdns_i3c_i2c_attach_device()
2224 k_mutex_unlock(&data->bus_lock); in cdns_i3c_i2c_attach_device()
2231 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_i2c_detach_device()
2232 struct cdns_i3c_data *data = dev->data; in cdns_i3c_i2c_detach_device()
2233 struct cdns_i3c_i2c_dev_data *cdns_i2c_device_data = desc->controller_priv; in cdns_i3c_i2c_detach_device()
2236 LOG_ERR("%s: device not attached", dev->name); in cdns_i3c_i2c_detach_device()
2237 return -EINVAL; in cdns_i3c_i2c_detach_device()
2240 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_i2c_detach_device()
2242 sys_write32(sys_read32(config->base + DEVS_CTRL) | in cdns_i3c_i2c_detach_device()
2243 DEVS_CTRL_DEV_CLR(cdns_i2c_device_data->id), in cdns_i3c_i2c_detach_device()
2244 config->base + DEVS_CTRL); in cdns_i3c_i2c_detach_device()
2245 data->free_rr_slots |= BIT(cdns_i2c_device_data->id); in cdns_i3c_i2c_detach_device()
2246 desc->controller_priv = NULL; in cdns_i3c_i2c_detach_device()
2248 k_mutex_unlock(&data->bus_lock); in cdns_i3c_i2c_detach_device()
2268 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_transfer()
2269 struct cdns_i3c_data *data = dev->data; in cdns_i3c_transfer()
2275 if (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE)) { in cdns_i3c_transfer()
2276 return -EACCES; in cdns_i3c_transfer()
2283 if (num_msgs > data->hw_cfg.cmd_mem_depth || num_msgs > data->hw_cfg.cmdr_mem_depth) { in cdns_i3c_transfer()
2284 LOG_ERR("%s: Too many messages", dev->name); in cdns_i3c_transfer()
2285 return -ENOMEM; in cdns_i3c_transfer()
2302 if ((rxsize > data->hw_cfg.rx_mem_depth) || (txsize > data->hw_cfg.tx_mem_depth)) { in cdns_i3c_transfer()
2303 LOG_ERR("%s: Total RX and/or TX transfer larger than FIFO", dev->name); in cdns_i3c_transfer()
2304 return -ENOMEM; in cdns_i3c_transfer()
2307 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_transfer()
2317 * in-flight but it would be possible to keep a queue of transfers. If so, in cdns_i3c_transfer()
2324 struct cdns_i3c_cmd *cmd = &data->xfer.cmds[i]; in cdns_i3c_transfer()
2331 cmd->len = pl; in cdns_i3c_transfer()
2332 cmd->buf = msgs[i].buf; in cdns_i3c_transfer()
2334 cmd->cmd0 = CMD0_FIFO_PRIV_XMIT_MODE(XMIT_BURST_WITHOUT_SUBADDR); in cdns_i3c_transfer()
2335 cmd->cmd0 |= CMD0_FIFO_DEV_ADDR(target->dynamic_addr); in cdns_i3c_transfer()
2337 cmd->cmd0 |= CMD0_FIFO_RNW; in cdns_i3c_transfer()
2342 cmd->cmd0 |= CMD0_FIFO_PL_LEN(pl + 1); in cdns_i3c_transfer()
2344 cmd->cmd0 |= CMD0_FIFO_PL_LEN(pl); in cdns_i3c_transfer()
2349 cmd->cmd0 |= CMD0_FIFO_BCH; in cdns_i3c_transfer()
2357 if ((i < (num_msgs - 1)) && ((msgs[i].flags & I3C_MSG_STOP) == 0)) { in cdns_i3c_transfer()
2358 cmd->cmd0 |= CMD0_FIFO_RSBC; in cdns_i3c_transfer()
2367 cmd->num_xfer = &(msgs[i].num_xfer); in cdns_i3c_transfer()
2368 cmd->sdr_err = &(msgs[i].err); in cdns_i3c_transfer()
2369 cmd->hdr = I3C_DATA_RATE_SDR; in cdns_i3c_transfer()
2370 } else if ((data->common.ctrl_config.supported_hdr & I3C_MSG_HDR_DDR) && in cdns_i3c_transfer()
2376 ret = -EINVAL; in cdns_i3c_transfer()
2380 cmd->buf = msgs[i].buf; in cdns_i3c_transfer()
2382 /* HDR-DDR Read */ in cdns_i3c_transfer()
2385 (target->dynamic_addr << 1); in cdns_i3c_transfer()
2389 /* HDR-DDR Command Word */ in cdns_i3c_transfer()
2390 cmd->ddr_header = in cdns_i3c_transfer()
2394 /* HDR-DDR Write */ in cdns_i3c_transfer()
2396 (target->dynamic_addr << 1); in cdns_i3c_transfer()
2397 /* HDR-DDR Command Word */ in cdns_i3c_transfer()
2398 cmd->ddr_header = in cdns_i3c_transfer()
2405 sys_get_be16((void *)((uintptr_t)cmd->buf + j))); in cdns_i3c_transfer()
2407 cmd->ddr_crc = DDR_PREAMBLE_CMD_CRC | DDR_CRC_TOKEN | (crc5 << 9) | in cdns_i3c_transfer()
2413 cmd->len = ((pl / 2) + 2); in cdns_i3c_transfer()
2416 cmd->cmd0 = CMD0_FIFO_IS_CCC; in cdns_i3c_transfer()
2417 cmd->cmd1 = I3C_CCC_ENTHDR0; in cdns_i3c_transfer()
2421 cmd->num_xfer = &(msgs[i].num_xfer); in cdns_i3c_transfer()
2422 cmd->sdr_err = &(msgs[i].err); in cdns_i3c_transfer()
2423 cmd->hdr = I3C_DATA_RATE_HDR_DDR; in cdns_i3c_transfer()
2425 LOG_ERR("%s: Unsupported HDR Mode %d", dev->name, msgs[i].hdr_mode); in cdns_i3c_transfer()
2426 ret = -ENOTSUP; in cdns_i3c_transfer()
2431 data->xfer.ret = -ETIMEDOUT; in cdns_i3c_transfer()
2432 data->xfer.num_cmds = num_msgs; in cdns_i3c_transfer()
2435 if (k_sem_take(&data->xfer.complete, K_MSEC(1000)) != 0) { in cdns_i3c_transfer()
2436 LOG_ERR("%s: transfer timed out", dev->name); in cdns_i3c_transfer()
2440 ret = data->xfer.ret; in cdns_i3c_transfer()
2442 k_mutex_unlock(&data->bus_lock); in cdns_i3c_transfer()
2453 for (remain = len; remain >= 4; remain -= 4) { in cdns_i3c_read_ibi_fifo()
2455 return -EIO; in cdns_i3c_read_ibi_fifo()
2457 val = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); in cdns_i3c_read_ibi_fifo()
2463 return -EIO; in cdns_i3c_read_ibi_fifo()
2465 val = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); in cdns_i3c_read_ibi_fifo()
2474 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_handle_ibi()
2475 struct cdns_i3c_data *data = dev->data; in cdns_i3c_handle_ibi()
2487 uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(slave_id + 1)); in cdns_i3c_handle_ibi()
2499 LOG_DBG("%s: NAK for slave ID %u", dev->name, (unsigned int)slave_id); in cdns_i3c_handle_ibi()
2504 LOG_ERR("%s: IBI Data overflow", dev->name); in cdns_i3c_handle_ibi()
2511 if (ibi_len - data->ibi_buf.ibi_data_cnt > 0) { in cdns_i3c_handle_ibi()
2513 config, &data->ibi_buf.ibi_data[data->ibi_buf.ibi_data_cnt], in cdns_i3c_handle_ibi()
2514 ibi_len - data->ibi_buf.ibi_data_cnt) < 0) { in cdns_i3c_handle_ibi()
2515 LOG_ERR("%s: Failed to get payload", dev->name); in cdns_i3c_handle_ibi()
2518 data->ibi_buf.ibi_data_cnt = 0; in cdns_i3c_handle_ibi()
2521 if (i3c_ibi_work_enqueue_target_irq(desc, data->ibi_buf.ibi_data, ibi_len) != 0) { in cdns_i3c_handle_ibi()
2522 LOG_ERR("%s: Error enqueue IBI IRQ work", dev->name); in cdns_i3c_handle_ibi()
2528 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_handle_cr()
2540 uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(slave_id + 1)); in cdns_i3c_handle_cr()
2552 LOG_DBG("%s: NAK for slave ID %u", dev->name, (unsigned int)slave_id); in cdns_i3c_handle_cr()
2556 LOG_ERR("%s: Data overflow", dev->name); in cdns_i3c_handle_cr()
2561 LOG_ERR("%s: Error enqueue IBI IRQ work", dev->name); in cdns_i3c_handle_cr()
2568 LOG_DBG("%s: NAK for HJ", dev->name); in cdns_i3c_handle_hj()
2572 /* TODO: disable CTRL_HJ_DISEC and process auto-ENTDAA*/ in cdns_i3c_handle_hj()
2574 LOG_ERR("%s: Error enqueue IBI HJ work", dev->name); in cdns_i3c_handle_hj()
2580 const struct cdns_i3c_config *config = dev->config; in cnds_i3c_master_demux_ibis()
2582 for (uint32_t status0 = sys_read32(config->base + MST_STATUS0); in cnds_i3c_master_demux_ibis()
2583 !(status0 & MST_STATUS0_IBIR_EMP); status0 = sys_read32(config->base + MST_STATUS0)) { in cnds_i3c_master_demux_ibis()
2584 uint32_t ibir = sys_read32(config->base + IBIR); in cnds_i3c_master_demux_ibis()
2604 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_hj_complete()
2606 k_sem_give(&data->ibi_hj_complete); in cdns_i3c_target_ibi_hj_complete()
2611 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_ibi_cr_complete()
2613 k_sem_give(&data->ibi_cr_complete); in cdns_i3c_target_ibi_cr_complete()
2621 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_sdr_tx_thr_int_handler()
2622 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_sdr_tx_thr_int_handler()
2624 if (target_cb != NULL && target_cb->read_processed_cb) { in cdns_i3c_target_sdr_tx_thr_int_handler()
2628 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_sdr_tx_thr_int_handler()
2630 while ((!(sys_read32(config->base + SLV_STATUS1) & in cdns_i3c_target_sdr_tx_thr_int_handler()
2642 status = target_cb->read_processed_cb(data->target_config, in cdns_i3c_target_sdr_tx_thr_int_handler()
2655 while ((!(sys_read32(config->base + SLV_STATUS1) & in cdns_i3c_target_sdr_tx_thr_int_handler()
2662 status = target_cb->read_processed_cb(data->target_config, &byte); in cdns_i3c_target_sdr_tx_thr_int_handler()
2673 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_irq_handler()
2674 struct cdns_i3c_data *data = dev->data; in cdns_i3c_irq_handler()
2675 uint32_t int_st = sys_read32(config->base + MST_ISR); in cdns_i3c_irq_handler()
2677 sys_write32(int_st, config->base + MST_ICR); in cdns_i3c_irq_handler()
2689 /* In-band interrupt */ in cdns_i3c_irq_handler()
2694 LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", dev->name); in cdns_i3c_irq_handler()
2698 /* In-band interrupt data threshold */ in cdns_i3c_irq_handler()
2704 (uint32_t *)&data->ibi_buf.ibi_data[data->ibi_buf.ibi_data_cnt]; in cdns_i3c_irq_handler()
2705 *ptr = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); in cdns_i3c_irq_handler()
2706 data->ibi_buf.ibi_data_cnt += 4; in cdns_i3c_irq_handler()
2709 LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", dev->name); in cdns_i3c_irq_handler()
2713 /* In-band interrupt response overflow */ in cdns_i3c_irq_handler()
2715 LOG_ERR("%s: controller ibir overflow,", dev->name); in cdns_i3c_irq_handler()
2718 /* In-band interrupt data */ in cdns_i3c_irq_handler()
2720 LOG_ERR("%s: controller tx buffer overflow,", dev->name); in cdns_i3c_irq_handler()
2723 /* In-band interrupt data */ in cdns_i3c_irq_handler()
2725 LOG_ERR("%s: controller rx buffer underflow,", dev->name); in cdns_i3c_irq_handler()
2729 LOG_DBG("%s: controller CR Handoff done,", dev->name); in cdns_i3c_irq_handler()
2730 k_sem_give(&data->ch_complete); in cdns_i3c_irq_handler()
2733 uint32_t int_sl = sys_read32(config->base + SLV_ISR); in cdns_i3c_irq_handler()
2735 data->target_config ? data->target_config->callbacks : NULL; in cdns_i3c_irq_handler()
2737 sys_write32(int_sl, config->base + SLV_ICR); in cdns_i3c_irq_handler()
2742 while (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_SDR_RX_EMPTY)) { in cdns_i3c_irq_handler()
2743 if (target_cb != NULL && target_cb->write_received_cb != NULL) { in cdns_i3c_irq_handler()
2757 (void)sys_read32(config->base + SLV_STATUS0); in cdns_i3c_irq_handler()
2759 if (target_cb != NULL && target_cb->stop_cb) { in cdns_i3c_irq_handler()
2760 target_cb->stop_cb(data->target_config); in cdns_i3c_irq_handler()
2767 (void)sys_read32(config->base + SLV_STATUS0); in cdns_i3c_irq_handler()
2769 data->fifo_bytes_read = 0; in cdns_i3c_irq_handler()
2771 if (target_cb != NULL && target_cb->stop_cb) { in cdns_i3c_irq_handler()
2772 target_cb->stop_cb(data->target_config); in cdns_i3c_irq_handler()
2778 LOG_INF("%s: DA updated to 0x%02lx", dev->name, in cdns_i3c_irq_handler()
2779 SLV_STATUS1_DA(sys_read32(config->base + SLV_STATUS1))); in cdns_i3c_irq_handler()
2795 if (target_cb != NULL && target_cb->controller_handoff_cb) { in cdns_i3c_irq_handler()
2796 target_cb->controller_handoff_cb(data->target_config); in cdns_i3c_irq_handler()
2812 LOG_ERR("%s: slave sdr rx buffer underflow", dev->name); in cdns_i3c_irq_handler()
2817 LOG_ERR("%s: slave sdr tx buffer overflow,", dev->name); in cdns_i3c_irq_handler()
2825 /* initial value of CRC5 for HDR-DDR is 0x1F */ in cdns_i3c_irq_handler()
2828 while (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_DDR_RX_EMPTY)) { in cdns_i3c_irq_handler()
2829 uint32_t ddr_rx_data = sys_read32(config->base + SLV_DDR_RX_FIFO); in cdns_i3c_irq_handler()
2838 LOG_ERR("%s: Received incorrect DDR Parity", dev->name); in cdns_i3c_irq_handler()
2843 if (target_cb != NULL && target_cb->write_received_cb != NULL) { in cdns_i3c_irq_handler()
2845 target_cb->write_received_cb( in cdns_i3c_irq_handler()
2846 data->target_config, in cdns_i3c_irq_handler()
2848 target_cb->write_received_cb(data->target_config, in cdns_i3c_irq_handler()
2856 LOG_ERR("%s: Received incorrect DDR CRC5", dev->name); in cdns_i3c_irq_handler()
2866 if (target_cb != NULL && target_cb->stop_cb != NULL) { in cdns_i3c_irq_handler()
2867 target_cb->stop_cb(data->target_config); in cdns_i3c_irq_handler()
2874 (void)sys_read32(config->base + SLV_STATUS0); in cdns_i3c_irq_handler()
2876 if (target_cb != NULL && target_cb->stop_cb) { in cdns_i3c_irq_handler()
2877 target_cb->stop_cb(data->target_config); in cdns_i3c_irq_handler()
2885 if (target_cb != NULL && target_cb->read_processed_cb) { in cdns_i3c_irq_handler()
2887 while ((!(sys_read32(config->base + SLV_STATUS1) & in cdns_i3c_irq_handler()
2895 status = target_cb->read_processed_cb(data->target_config, &byte); in cdns_i3c_irq_handler()
2906 k_work_submit(&data->deftgts_work); in cdns_i3c_irq_handler()
2912 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_read_hw_cfg()
2913 struct cdns_i3c_data *data = dev->data; in cdns_i3c_read_hw_cfg()
2915 uint32_t devid = sys_read32(config->base + DEV_ID); in cdns_i3c_read_hw_cfg()
2916 uint32_t revid = sys_read32(config->base + REV_ID); in cdns_i3c_read_hw_cfg()
2922 dev->name, REV_ID_VID(revid), REV_ID_PID(revid), REV_ID_REV_MAJOR(revid), in cdns_i3c_read_hw_cfg()
2928 uint32_t cfg0 = sys_read32(config->base + CONF_STATUS0); in cdns_i3c_read_hw_cfg()
2929 uint32_t cfg1 = sys_read32(config->base + CONF_STATUS1); in cdns_i3c_read_hw_cfg()
2931 data->hw_cfg.rev_id = revid; in cdns_i3c_read_hw_cfg()
2932 data->hw_cfg.cmdr_mem_depth = CONF_STATUS0_CMDR_DEPTH(cfg0) * 4; in cdns_i3c_read_hw_cfg()
2933 data->hw_cfg.cmd_mem_depth = CONF_STATUS1_CMD_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2934 data->hw_cfg.rx_mem_depth = CONF_STATUS1_RX_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2935 data->hw_cfg.tx_mem_depth = CONF_STATUS1_TX_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2936 data->hw_cfg.ddr_rx_mem_depth = CONF_STATUS1_SLV_DDR_RX_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2937 data->hw_cfg.ddr_tx_mem_depth = CONF_STATUS1_SLV_DDR_TX_DEPTH(cfg1) * 4; in cdns_i3c_read_hw_cfg()
2938 data->hw_cfg.ibir_mem_depth = CONF_STATUS0_IBIR_DEPTH(cfg0) * 4; in cdns_i3c_read_hw_cfg()
2939 data->hw_cfg.ibi_mem_depth = CONF_STATUS1_IBI_DEPTH(cfg0) * 4; in cdns_i3c_read_hw_cfg()
2950 dev->name, data->hw_cfg.cmd_mem_depth, data->hw_cfg.cmdr_mem_depth, in cdns_i3c_read_hw_cfg()
2951 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()
2952 data->hw_cfg.ddr_tx_mem_depth, data->hw_cfg.ibi_mem_depth, in cdns_i3c_read_hw_cfg()
2953 data->hw_cfg.ibir_mem_depth); in cdns_i3c_read_hw_cfg()
2955 /* Regardless of the cmd depth size we are limited by our cmd array length. */ in cdns_i3c_read_hw_cfg()
2956 data->hw_cfg.cmd_mem_depth = MIN(data->hw_cfg.cmd_mem_depth, ARRAY_SIZE(data->xfer.cmds)); in cdns_i3c_read_hw_cfg()
2976 * @retval -EIO General Input/Output errors.
2977 * @retval -ENOSYS If not implemented.
2981 const struct cdns_i3c_config *dev_config = dev->config; in cdns_i3c_config_get()
2982 struct cdns_i3c_data *data = dev->data; in cdns_i3c_config_get()
2987 (void)memcpy(config, &data->common.ctrl_config, sizeof(data->common.ctrl_config)); in cdns_i3c_config_get()
2991 uint32_t dev_id_rr0 = sys_read32(dev_config->base + DEV_ID_RR0(0)); in cdns_i3c_config_get()
2992 uint32_t dev_id_rr1 = sys_read32(dev_config->base + DEV_ID_RR1(0)); in cdns_i3c_config_get()
2993 uint32_t dev_id_rr2 = sys_read32(dev_config->base + DEV_ID_RR2(0)); in cdns_i3c_config_get()
2994 uint32_t slv_status1 = sys_read32(dev_config->base + SLV_STATUS1); in cdns_i3c_config_get()
2997 target_config->enabled = in cdns_i3c_config_get()
2998 !!!(sys_read32(dev_config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE); in cdns_i3c_config_get()
2999 if (data->common.ctrl_config.is_secondary) { in cdns_i3c_config_get()
3000 target_config->dynamic_addr = SLV_STATUS1_DA(slv_status1); in cdns_i3c_config_get()
3002 target_config->dynamic_addr = (dev_id_rr0 & 0xFE) >> 1; in cdns_i3c_config_get()
3004 target_config->static_addr = 0; in cdns_i3c_config_get()
3005 target_config->pid = ((uint64_t)dev_id_rr1 << 16) + (dev_id_rr2 >> 16); in cdns_i3c_config_get()
3006 target_config->pid_random = !!(slv_status1 & SLV_STATUS1_VEN_TM); in cdns_i3c_config_get()
3007 target_config->bcr = dev_id_rr2 >> 8; in cdns_i3c_config_get()
3008 target_config->dcr = dev_id_rr2 & 0xFF; in cdns_i3c_config_get()
3010 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_config_get()
3011 target_config->max_read_len = in cdns_i3c_config_get()
3012 SLV_STATUS2_MRL(sys_read32(dev_config->base + SLV_STATUS2)); in cdns_i3c_config_get()
3013 target_config->max_write_len = in cdns_i3c_config_get()
3014 SLV_STATUS3_MWL(sys_read32(dev_config->base + SLV_STATUS3)); in cdns_i3c_config_get()
3016 target_config->max_read_len = 0; in cdns_i3c_config_get()
3017 target_config->max_write_len = 0; in cdns_i3c_config_get()
3019 target_config->supported_hdr = data->common.ctrl_config.supported_hdr; in cdns_i3c_config_get()
3021 return -EINVAL; in cdns_i3c_config_get()
3029 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_tx_ddr_write()
3030 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_tx_ddr_write()
3036 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_DDR_TX_FULL) { in cdns_i3c_target_tx_ddr_write()
3037 return -ENOSPC; in cdns_i3c_target_tx_ddr_write()
3042 return -EINVAL; in cdns_i3c_target_tx_ddr_write()
3046 uint8_t slave_da = SLV_STATUS1_DA(sys_read32(config->base + SLV_STATUS1)); in cdns_i3c_target_tx_ddr_write()
3054 i < len && (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_DDR_TX_FULL)); in cdns_i3c_target_tx_ddr_write()
3060 sys_write32(data_word, config->base + SLV_DDR_TX_FIFO); in cdns_i3c_target_tx_ddr_write()
3063 if ((i == len) && (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_DDR_TX_FULL))) { in cdns_i3c_target_tx_ddr_write()
3065 config->base + SLV_DDR_TX_FIFO); in cdns_i3c_target_tx_ddr_write()
3069 uint32_t thr_ctrl = sys_read32(config->base + SLV_DDR_TX_RX_THR_CTRL); in cdns_i3c_target_tx_ddr_write()
3077 thr_ctrl |= TX_THR(MIN((data->hw_cfg.tx_mem_depth / 4) / 2, len / 2)); in cdns_i3c_target_tx_ddr_write()
3079 sys_write32(thr_ctrl, config->base + SLV_DDR_TX_RX_THR_CTRL); in cdns_i3c_target_tx_ddr_write()
3096 * @retval -EACCES Not in Target Mode
3097 * @retval -ENOSPC No space in Tx FIFO
3102 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_tx_write()
3103 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_tx_write()
3104 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_target_tx_write()
3111 if (sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE) { in cdns_i3c_target_tx_write()
3112 return -EACCES; in cdns_i3c_target_tx_write()
3116 if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_SDR_TX_FULL) { in cdns_i3c_target_tx_write()
3117 return -ENOSPC; in cdns_i3c_target_tx_write()
3120 k_mutex_lock(&data->bus_lock, K_FOREVER); in cdns_i3c_target_tx_write()
3123 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_tx_write()
3124 sys_write32(len, config->base + SLV_CTRL); in cdns_i3c_target_tx_write()
3127 if (ctrl_config->supported_hdr & I3C_MSG_HDR_DDR) { in cdns_i3c_target_tx_write()
3131 LOG_ERR("%s: HDR-DDR not supported", dev->name); in cdns_i3c_target_tx_write()
3132 i = -ENOTSUP; in cdns_i3c_target_tx_write()
3137 (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_SDR_TX_FULL))) { in cdns_i3c_target_tx_write()
3141 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_target_tx_write()
3142 remain = len - i; in cdns_i3c_target_tx_write()
3149 sys_write32(val, config->base + TX_FIFO); in cdns_i3c_target_tx_write()
3152 sys_write32((uint32_t)buf[i], config->base + TX_FIFO); in cdns_i3c_target_tx_write()
3158 uint32_t thr_ctrl = sys_read32(config->base + TX_RX_THR_CTRL); in cdns_i3c_target_tx_write()
3166 thr_ctrl |= TX_THR(MIN((data->hw_cfg.tx_mem_depth / 4) / 2, len / 2)); in cdns_i3c_target_tx_write()
3167 sys_write32(thr_ctrl, config->base + TX_RX_THR_CTRL); in cdns_i3c_target_tx_write()
3169 LOG_ERR("%s: Unsupported HDR Mode %d", dev->name, hdr_mode); in cdns_i3c_target_tx_write()
3170 i = -ENOTSUP; in cdns_i3c_target_tx_write()
3173 k_mutex_unlock(&data->bus_lock); in cdns_i3c_target_tx_write()
3193 struct cdns_i3c_data *data = dev->data; in cdns_i3c_target_register()
3195 data->target_config = cfg; in cdns_i3c_target_register()
3232 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_device_find()
3234 return i3c_dev_list_find(&config->common.dev_list, id); in cdns_i3c_device_find()
3274 ret = -ENODEV; in cdns_i3c_i2c_api_transfer()
3295 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_target_controller_handoff()
3296 uint32_t ctrl = sys_read32(config->base + CTRL); in cdns_i3c_target_controller_handoff()
3299 sys_write32(ctrl | CTRL_MST_ACK, config->base + CTRL); in cdns_i3c_target_controller_handoff()
3301 sys_write32(ctrl & ~CTRL_MST_ACK, config->base + CTRL); in cdns_i3c_target_controller_handoff()
3321 for (int i = 0; i < dev_list->num_i2c; i++) { in i3c_bus_mode()
3322 switch (I3C_LVR_I2C_DEV_IDX(dev_list->i2c[i].lvr)) { in i3c_bus_mode()
3357 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_sda_data_hold()
3358 uint32_t input_clock_frequency = config->input_frequency; in cdns_i3c_sda_data_hold()
3366 return (THD_DELAY_MAX - thd_delay); in cdns_i3c_sda_data_hold()
3379 dev = data->dev; in i3c_cdns_deftgts_work_fn()
3380 config = dev->config; in i3c_cdns_deftgts_work_fn()
3381 data = dev->data; in i3c_cdns_deftgts_work_fn()
3383 devs = sys_read32(config->base + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; in i3c_cdns_deftgts_work_fn()
3384 data->free_rr_slots = GENMASK(data->max_devs, 1) & ~devs; in i3c_cdns_deftgts_work_fn()
3391 count = POPCOUNT(devs) - 1; in i3c_cdns_deftgts_work_fn()
3394 if (data->common.deftgts) { in i3c_cdns_deftgts_work_fn()
3395 free(data->common.deftgts); in i3c_cdns_deftgts_work_fn()
3396 data->common.deftgts = NULL; in i3c_cdns_deftgts_work_fn()
3400 data->common.deftgts = in i3c_cdns_deftgts_work_fn()
3403 if (!data->common.deftgts) { in i3c_cdns_deftgts_work_fn()
3404 LOG_ERR("%s: Failed to allocate memory for DEFTGTS", dev->name); in i3c_cdns_deftgts_work_fn()
3408 data->common.deftgts->count = count; in i3c_cdns_deftgts_work_fn()
3411 uint8_t rr_idx = i - 1; in i3c_cdns_deftgts_work_fn()
3415 uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(rr_idx)); in i3c_cdns_deftgts_work_fn()
3416 uint32_t dev_id_rr2 = sys_read32(config->base + DEV_ID_RR2(rr_idx)); in i3c_cdns_deftgts_work_fn()
3426 data->common.deftgts->active_controller.addr = addr; in i3c_cdns_deftgts_work_fn()
3427 data->common.deftgts->active_controller.dcr = dcr_lvr; in i3c_cdns_deftgts_work_fn()
3428 data->common.deftgts->active_controller.bcr = bcr; in i3c_cdns_deftgts_work_fn()
3429 data->common.deftgts->active_controller.static_addr = 0; in i3c_cdns_deftgts_work_fn()
3431 data->common.deftgts->targets[n].addr = addr; in i3c_cdns_deftgts_work_fn()
3432 data->common.deftgts->targets[n].dcr = dcr_lvr; in i3c_cdns_deftgts_work_fn()
3433 data->common.deftgts->targets[n].bcr = bcr; in i3c_cdns_deftgts_work_fn()
3434 data->common.deftgts->targets[n].static_addr = 0; in i3c_cdns_deftgts_work_fn()
3437 data->common.deftgts->targets[n].addr = 0; in i3c_cdns_deftgts_work_fn()
3438 data->common.deftgts->targets[n].lvr = dcr_lvr; in i3c_cdns_deftgts_work_fn()
3439 data->common.deftgts->targets[n].bcr = 0; in i3c_cdns_deftgts_work_fn()
3440 data->common.deftgts->targets[n].static_addr = addr; in i3c_cdns_deftgts_work_fn()
3445 data->common.deftgts_refreshed = true; in i3c_cdns_deftgts_work_fn()
3446 LOG_HEXDUMP_DBG((uint8_t *)data->common.deftgts, in i3c_cdns_deftgts_work_fn()
3448 (data->common.deftgts->count * sizeof(struct i3c_ccc_deftgts_target)), in i3c_cdns_deftgts_work_fn()
3459 struct cdns_i3c_data *data = dev->data; in cdns_i3c_bus_init()
3460 const struct cdns_i3c_config *config = dev->config; in cdns_i3c_bus_init()
3461 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in cdns_i3c_bus_init()
3463 data->dev = dev; in cdns_i3c_bus_init()
3468 sys_write32(DEVS_CTRL_DEV_CLR_ALL, config->base + DEVS_CTRL); in cdns_i3c_bus_init()
3470 uint32_t conf0 = sys_read32(config->base + CONF_STATUS0); in cdns_i3c_bus_init()
3471 uint32_t conf1 = sys_read32(config->base + CONF_STATUS1); in cdns_i3c_bus_init()
3472 data->max_devs = CONF_STATUS0_DEVS_NUM(conf0); in cdns_i3c_bus_init()
3473 data->free_rr_slots = GENMASK(data->max_devs, 1); in cdns_i3c_bus_init()
3476 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { in cdns_i3c_bus_init()
3477 ctrl_config->supported_hdr = in cdns_i3c_bus_init()
3479 ctrl_config->is_secondary = in cdns_i3c_bus_init()
3483 ctrl_config->supported_hdr = in cdns_i3c_bus_init()
3485 ctrl_config->is_secondary = (conf0 & CONF_STATUS0_SEC_MASTER) ? true : false; in cdns_i3c_bus_init()
3487 k_mutex_init(&data->bus_lock); in cdns_i3c_bus_init()
3488 k_sem_init(&data->xfer.complete, 0, 1); in cdns_i3c_bus_init()
3489 k_sem_init(&data->ch_complete, 0, 1); in cdns_i3c_bus_init()
3490 k_work_init(&data->deftgts_work, i3c_cdns_deftgts_work_fn); in cdns_i3c_bus_init()
3492 k_sem_init(&data->ibi_hj_complete, 0, 1); in cdns_i3c_bus_init()
3493 k_sem_init(&data->ibi_cr_complete, 0, 1); in cdns_i3c_bus_init()
3499 config->irq_config_func(dev); in cdns_i3c_bus_init()
3502 sys_write32(~CTRL_DEV_EN & sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_bus_init()
3507 enum i3c_bus_mode mode = i3c_bus_mode(&config->common.dev_list); in cdns_i3c_bus_init()
3509 LOG_DBG("%s: i3c bus mode %d", dev->name, mode); in cdns_i3c_bus_init()
3524 return -EINVAL; in cdns_i3c_bus_init()
3528 * When a Hot-Join request happens, disable all events coming from this device. in cdns_i3c_bus_init()
3540 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 4)) { in cdns_i3c_bus_init()
3549 if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 5)) { in cdns_i3c_bus_init()
3554 sys_write32(ctrl, config->base + CTRL); in cdns_i3c_bus_init()
3557 sys_write32(CTRL_DEV_EN | ctrl, config->base + CTRL); in cdns_i3c_bus_init()
3560 sys_write32(CMD_THR(I3C_CMDD_THR) | IBI_THR(config->ibid_thr) | CMDR_THR(I3C_CMDR_THR) | in cdns_i3c_bus_init()
3562 config->base + CMD_IBI_THR_CTRL); in cdns_i3c_bus_init()
3565 if (sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE) { in cdns_i3c_bus_init()
3566 sys_write32(TX_THR(I3C_TX_THR) | RX_THR(data->hw_cfg.rx_mem_depth), in cdns_i3c_bus_init()
3567 config->base + TX_RX_THR_CTRL); in cdns_i3c_bus_init()
3569 sys_write32(TX_THR(1) | RX_THR(1), config->base + TX_RX_THR_CTRL); in cdns_i3c_bus_init()
3571 config->base + SLV_DDR_TX_RX_THR_CTRL); in cdns_i3c_bus_init()
3580 config->base + SLV_IER); in cdns_i3c_bus_init()
3585 config->base + MST_IER); in cdns_i3c_bus_init()
3594 if (!ctrl_config->is_secondary) { in cdns_i3c_bus_init()
3600 ret = i3c_bus_init(dev, &config->common.dev_list); in cdns_i3c_bus_init()
3603 sys_write32(CTRL_HJ_ACK | sys_read32(config->base + CTRL), config->base + CTRL); in cdns_i3c_bus_init()