// SPDX-License-Identifier: GPL-2.0
/*
* K3 NAVSS DMA glue interface
*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
*
*/
#include <linux/atomic.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/soc/ti/k3-ringacc.h>
#include <linux/dma/ti-cppi5.h>
#include <linux/dma/k3-udma-glue.h>
#include "k3-udma.h"
#include "k3-psil-priv.h"
struct k3_udma_glue_common {
struct device *dev;
struct udma_dev *udmax;
const struct udma_tisci_rm *tisci_rm;
struct k3_ringacc *ringacc;
u32 src_thread;
u32 dst_thread;
u32 hdesc_size;
bool epib;
u32 psdata_size;
u32 swdata_size;
u32 atype;
};
struct k3_udma_glue_tx_channel {
struct k3_udma_glue_common common;
struct udma_tchan *udma_tchanx;
int udma_tchan_id;
struct k3_ring *ringtx;
struct k3_ring *ringtxcq;
bool psil_paired;
int virq;
atomic_t free_pkts;
bool tx_pause_on_err;
bool tx_filt_einfo;
bool tx_filt_pswords;
bool tx_supr_tdpkt;
};
struct k3_udma_glue_rx_flow {
struct udma_rflow *udma_rflow;
int udma_rflow_id;
struct k3_ring *ringrx;
struct k3_ring *ringrxfdq;
int virq;
};
struct k3_udma_glue_rx_channel {
struct k3_udma_glue_common common;
struct udma_rchan *udma_rchanx;
int udma_rchan_id;
bool remote;
bool psil_paired;
u32 swdata_size;
int flow_id_base;
struct k3_udma_glue_rx_flow *flows;
u32 flow_num;
u32 flows_ready;
};
#define K3_UDMAX_TDOWN_TIMEOUT_US 1000
static int of_k3_udma_glue_parse(struct device_node *udmax_np,
struct k3_udma_glue_common *common)
{
common->ringacc = of_k3_ringacc_get_by_phandle(udmax_np,
"ti,ringacc");
if (IS_ERR(common->ringacc))
return PTR_ERR(common->ringacc);
common->udmax = of_xudma_dev_get(udmax_np, NULL);
if (IS_ERR(common->udmax))
return PTR_ERR(common->udmax);
common->tisci_rm = xudma_dev_get_tisci_rm(common->udmax);
return 0;
}
static int of_k3_udma_glue_parse_chn(struct device_node *chn_np,
const char *name, struct k3_udma_glue_common *common,
bool tx_chn)
{
struct psil_endpoint_config *ep_config;
struct of_phandle_args dma_spec;
u32 thread_id;
int ret = 0;
int index;
if (unlikely(!name))
return -EINVAL;
index = of_property_match_string(chn_np, "dma-names", name);
if (index < 0)
return index;
if (of_parse_phandle_with_args(chn_np,