in ti/k3-udma-glue.c [656:787]
static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
u32 flow_idx,
struct k3_udma_glue_rx_flow_cfg *flow_cfg)
{
struct k3_udma_glue_rx_flow *flow = &rx_chn->flows[flow_idx];
const struct udma_tisci_rm *tisci_rm = rx_chn->common.tisci_rm;
struct device *dev = rx_chn->common.dev;
struct ti_sci_msg_rm_udmap_flow_cfg req;
int rx_ring_id;
int rx_ringfdq_id;
int ret = 0;
flow->udma_rflow = xudma_rflow_get(rx_chn->common.udmax,
flow->udma_rflow_id);
if (IS_ERR(flow->udma_rflow)) {
ret = PTR_ERR(flow->udma_rflow);
dev_err(dev, "UDMAX rflow get err %d\n", ret);
return ret;
}
if (flow->udma_rflow_id != xudma_rflow_get_id(flow->udma_rflow)) {
ret = -ENODEV;
goto err_rflow_put;
}
if (xudma_is_pktdma(rx_chn->common.udmax)) {
rx_ringfdq_id = flow->udma_rflow_id +
xudma_get_rflow_ring_offset(rx_chn->common.udmax);
rx_ring_id = 0;
} else {
rx_ring_id = flow_cfg->ring_rxq_id;
rx_ringfdq_id = flow_cfg->ring_rxfdq0_id;
}
/* request and cfg rings */
ret = k3_ringacc_request_rings_pair(rx_chn->common.ringacc,
rx_ringfdq_id, rx_ring_id,
&flow->ringrxfdq,
&flow->ringrx);
if (ret) {
dev_err(dev, "Failed to get RX/RXFDQ rings %d\n", ret);
goto err_rflow_put;
}
/* Set the dma_dev for the rings to be configured */
flow_cfg->rx_cfg.dma_dev = k3_udma_glue_rx_get_dma_device(rx_chn);
flow_cfg->rxfdq_cfg.dma_dev = flow_cfg->rx_cfg.dma_dev;
/* Set the ASEL value for DMA rings of PKTDMA */
if (xudma_is_pktdma(rx_chn->common.udmax)) {
flow_cfg->rx_cfg.asel = rx_chn->common.atype_asel;
flow_cfg->rxfdq_cfg.asel = rx_chn->common.atype_asel;
}
ret = k3_ringacc_ring_cfg(flow->ringrx, &flow_cfg->rx_cfg);
if (ret) {
dev_err(dev, "Failed to cfg ringrx %d\n", ret);
goto err_ringrxfdq_free;
}
ret = k3_ringacc_ring_cfg(flow->ringrxfdq, &flow_cfg->rxfdq_cfg);
if (ret) {
dev_err(dev, "Failed to cfg ringrxfdq %d\n", ret);
goto err_ringrxfdq_free;
}
if (rx_chn->remote) {
rx_ring_id = TI_SCI_RESOURCE_NULL;
rx_ringfdq_id = TI_SCI_RESOURCE_NULL;
} else {
rx_ring_id = k3_ringacc_get_ring_id(flow->ringrx);
rx_ringfdq_id = k3_ringacc_get_ring_id(flow->ringrxfdq);
}
memset(&req, 0, sizeof(req));
req.valid_params =
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_EINFO_PRESENT_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_PSINFO_PRESENT_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_ERROR_HANDLING_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DESC_TYPE_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_QNUM_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SRC_TAG_HI_SEL_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SRC_TAG_LO_SEL_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_TAG_HI_SEL_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_TAG_LO_SEL_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ0_SZ0_QNUM_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ1_QNUM_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ2_QNUM_VALID |
TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ3_QNUM_VALID;
req.nav_id = tisci_rm->tisci_dev_id;
req.flow_index = flow->udma_rflow_id;
if (rx_chn->common.epib)
req.rx_einfo_present = 1;
if (rx_chn->common.psdata_size)
req.rx_psinfo_present = 1;
if (flow_cfg->rx_error_handling)
req.rx_error_handling = 1;
req.rx_desc_type = 0;
req.rx_dest_qnum = rx_ring_id;
req.rx_src_tag_hi_sel = 0;
req.rx_src_tag_lo_sel = flow_cfg->src_tag_lo_sel;
req.rx_dest_tag_hi_sel = 0;
req.rx_dest_tag_lo_sel = 0;
req.rx_fdq0_sz0_qnum = rx_ringfdq_id;
req.rx_fdq1_qnum = rx_ringfdq_id;
req.rx_fdq2_qnum = rx_ringfdq_id;
req.rx_fdq3_qnum = rx_ringfdq_id;
ret = tisci_rm->tisci_udmap_ops->rx_flow_cfg(tisci_rm->tisci, &req);
if (ret) {
dev_err(dev, "flow%d config failed: %d\n", flow->udma_rflow_id,
ret);
goto err_ringrxfdq_free;
}
rx_chn->flows_ready++;
dev_dbg(dev, "flow%d config done. ready:%d\n",
flow->udma_rflow_id, rx_chn->flows_ready);
return 0;
err_ringrxfdq_free:
k3_ringacc_ring_free(flow->ringrxfdq);
k3_ringacc_ring_free(flow->ringrx);
err_rflow_put:
xudma_rflow_put(rx_chn->common.udmax, flow->udma_rflow);
flow->udma_rflow = NULL;
return ret;
}