/*
 * 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__

#include <linux/dmaengine.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_DESC_EFLAGS_MASK		MASK(4)
#define KNAV_DMA_DESC_EFLAGS_SHIFT		20

#define KNAV_DMA_NUM_EPIB_WORDS			4
#define KNAV_DMA_NUM_PS_WORDS			16
#define KNAV_DMA_NUM_SW_DATA_WORDS		4
#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
 * @sw_data:			Software private data not touched by h/w
 */
struct knav_dma_desc {
	__le32	desc_info;
	__le32	tag_info;
	__le32	packet_info;
	__le32	buff_len;
	__le32	buff;
	__le32	next_desc;
	__le32	orig_len;
	__le32	orig_buff;
	__le32	epib[KNAV_DMA_NUM_EPIB_WORDS];
	__le32	psdata[KNAV_DMA_NUM_PS_WORDS];
	u32	sw_data[KNAV_DMA_NUM_SW_DATA_WORDS];
} ____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);
int knav_dma_get_flow(void *channel);
bool knav_dma_device_ready(void);
#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)
{}

static inline int knav_dma_get_flow(void *channel)
{
	return -EINVAL;
}

static inline bool knav_dma_device_ready(void)
{
	return false;
}

#endif

#endif /* __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__ */
