/*
 * Copyright (C) 2014 Texas Instruments Incorporated
 * Authors:	Sandeep Nair <sandeep_n@ti.com
 *		Cyril Chemparathy <cyril@ti.com
		Santosh Shilimkar <santosh.shilimkar@ti.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__
#define __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__

/*
 * PKTDMA descriptor manipulation macros for host packet descriptor
 */
#define MASK(x)					(BIT(x) - 1)
#define KNAV_DMA_DESC_PKT_LEN_MASK		MASK(22)
#define KNAV_DMA_DESC_PKT_LEN_SHIFT		0
#define KNAV_DMA_DESC_PS_INFO_IN_SOP		BIT(22)
#define KNAV_DMA_DESC_PS_INFO_IN_DESC		0
#define KNAV_DMA_DESC_TAG_MASK			MASK(8)
#define KNAV_DMA_DESC_SAG_HI_SHIFT		24
#define KNAV_DMA_DESC_STAG_LO_SHIFT		16
#define KNAV_DMA_DESC_DTAG_HI_SHIFT		8
#define KNAV_DMA_DESC_DTAG_LO_SHIFT		0
#define KNAV_DMA_DESC_HAS_EPIB			BIT(31)
#define KNAV_DMA_DESC_NO_EPIB			0
#define KNAV_DMA_DESC_PSLEN_SHIFT		24
#define KNAV_DMA_DESC_PSLEN_MASK		MASK(6)
#define KNAV_DMA_DESC_ERR_FLAG_SHIFT		20
#define KNAV_DMA_DESC_ERR_FLAG_MASK		MASK(4)
#define KNAV_DMA_DESC_PSFLAG_SHIFT		16
#define KNAV_DMA_DESC_PSFLAG_MASK		MASK(4)
#define KNAV_DMA_DESC_RETQ_SHIFT		0
#define KNAV_DMA_DESC_RETQ_MASK			MASK(14)
#define KNAV_DMA_DESC_BUF_LEN_MASK		MASK(22)

#define KNAV_DMA_NUM_EPIB_WORDS			4
#define KNAV_DMA_NUM_PS_WORDS			16
#define KNAV_DMA_FDQ_PER_CHAN			4

/* Tx channel scheduling priority */
enum knav_dma_tx_priority {
	DMA_PRIO_HIGH	= 0,
	DMA_PRIO_MED_H,
	DMA_PRIO_MED_L,
	DMA_PRIO_LOW
};

/* Rx channel error handling mode during buffer starvation */
enum knav_dma_rx_err_mode {
	DMA_DROP = 0,
	DMA_RETRY
};

/* Rx flow size threshold configuration */
enum knav_dma_rx_thresholds {
	DMA_THRESH_NONE		= 0,
	DMA_THRESH_0		= 1,
	DMA_THRESH_0_1		= 3,
	DMA_THRESH_0_1_2	= 7
};

/* Descriptor type */
enum knav_dma_desc_type {
	DMA_DESC_HOST = 0,
	DMA_DESC_MONOLITHIC = 2
};

/**
 * struct knav_dma_tx_cfg:	Tx channel configuration
 * @filt_einfo:			Filter extended packet info
 * @filt_pswords:		Filter PS words present
 * @knav_dma_tx_priority:	Tx channel scheduling priority
 */
struct knav_dma_tx_cfg {
	bool				filt_einfo;
	bool				filt_pswords;
	enum knav_dma_tx_priority	priority;
};

/**
 * struct knav_dma_rx_cfg:	Rx flow configuration
 * @einfo_present:		Extended packet info present
 * @psinfo_present:		PS words present
 * @knav_dma_rx_err_mode:	Error during buffer starvation
 * @knav_dma_desc_type:	Host or Monolithic desc
 * @psinfo_at_sop:		PS word located at start of packet
 * @sop_offset:			Start of packet offset
 * @dst_q:			Destination queue for a given flow
 * @thresh:			Rx flow size threshold
 * @fdq[]:			Free desc Queue array
 * @sz_thresh0:			RX packet size threshold 0
 * @sz_thresh1:			RX packet size threshold 1
 * @sz_thresh2:			RX packet size threshold 2
 */
struct knav_dma_rx_cfg {
	bool				einfo_present;
	bool				psinfo_present;
	enum knav_dma_rx_err_mode	err_mode;
	enum knav_dma_desc_type		desc_type;
	bool				psinfo_at_sop;
	unsigned int			sop_offset;
	unsigned int			dst_q;
	enum knav_dma_rx_thresholds	thresh;
	unsigned int			fdq[KNAV_DMA_FDQ_PER_CHAN];
	unsigned int			sz_thresh0;
	unsigned int			sz_thresh1;
	unsigned int			sz_thresh2;
};

/**
 * struct knav_dma_cfg:	Pktdma channel configuration
 * @sl_cfg:			Slave configuration
 * @tx:				Tx channel configuration
 * @rx:				Rx flow configuration
 */
struct knav_dma_cfg {
	enum dma_transfer_direction direction;
	union {
		struct knav_dma_tx_cfg	tx;
		struct knav_dma_rx_cfg	rx;
	} u;
};

/**
 * struct knav_dma_desc:	Host packet descriptor layout
 * @desc_info:			Descriptor information like id, type, length
 * @tag_info:			Flow tag info written in during RX
 * @packet_info:		Queue Manager, policy, flags etc
 * @buff_len:			Buffer length in bytes
 * @buff:			Buffer pointer
 * @next_desc:			For chaining the descriptors
 * @orig_len:			length since 'buff_len' can be overwritten
 * @orig_buff:			buff pointer since 'buff' can be overwritten
 * @epib:			Extended packet info block
 * @psdata:			Protocol specific
 */
struct knav_dma_desc {
	u32	desc_info;
	u32	tag_info;
	u32	packet_info;
	u32	buff_len;
	u32	buff;
	u32	next_desc;
	u32	orig_len;
	u32	orig_buff;
	u32	epib[KNAV_DMA_NUM_EPIB_WORDS];
	u32	psdata[KNAV_DMA_NUM_PS_WORDS];
	u32	pad[4];
} ____cacheline_aligned;

#if IS_ENABLED(CONFIG_KEYSTONE_NAVIGATOR_DMA)
void *knav_dma_open_channel(struct device *dev, const char *name,
				struct knav_dma_cfg *config);
void knav_dma_close_channel(void *channel);
#else
static inline void *knav_dma_open_channel(struct device *dev, const char *name,
				struct knav_dma_cfg *config)
{
	return (void *) NULL;
}
static inline void knav_dma_close_channel(void *channel)
{}

#endif

#endif /* __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__ */
