linux/drivers/dma/mediatek/mtk-hsdma.c

// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017-2018 MediaTek Inc.

/*
 * Driver for MediaTek High-Speed DMA Controller
 *
 * Author: Sean Wang <[email protected]>
 *
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/iopoll.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/refcount.h>
#include <linux/slab.h>

#include "../virt-dma.h"

#define MTK_HSDMA_USEC_POLL
#define MTK_HSDMA_TIMEOUT_POLL
#define MTK_HSDMA_DMA_BUSWIDTHS

/* The default number of virtual channel */
#define MTK_HSDMA_NR_VCHANS

/* Only one physical channel supported */
#define MTK_HSDMA_NR_MAX_PCHANS

/* Macro for physical descriptor (PD) manipulation */
/* The number of PD which must be 2 of power */
#define MTK_DMA_SIZE
#define MTK_HSDMA_NEXT_DESP_IDX(x, y)
#define MTK_HSDMA_LAST_DESP_IDX(x, y)
#define MTK_HSDMA_MAX_LEN
#define MTK_HSDMA_ALIGN_SIZE
#define MTK_HSDMA_PLEN_MASK
#define MTK_HSDMA_DESC_PLEN(x)
#define MTK_HSDMA_DESC_PLEN_GET(x)

/* Registers for underlying ring manipulation */
#define MTK_HSDMA_TX_BASE
#define MTK_HSDMA_TX_CNT
#define MTK_HSDMA_TX_CPU
#define MTK_HSDMA_TX_DMA
#define MTK_HSDMA_RX_BASE
#define MTK_HSDMA_RX_CNT
#define MTK_HSDMA_RX_CPU
#define MTK_HSDMA_RX_DMA

/* Registers for global setup */
#define MTK_HSDMA_GLO
#define MTK_HSDMA_GLO_MULTI_DMA
#define MTK_HSDMA_TX_WB_DDONE
#define MTK_HSDMA_BURST_64BYTES
#define MTK_HSDMA_GLO_RX_BUSY
#define MTK_HSDMA_GLO_RX_DMA
#define MTK_HSDMA_GLO_TX_BUSY
#define MTK_HSDMA_GLO_TX_DMA
#define MTK_HSDMA_GLO_DMA
#define MTK_HSDMA_GLO_BUSY
#define MTK_HSDMA_GLO_DEFAULT

/* Registers for reset */
#define MTK_HSDMA_RESET
#define MTK_HSDMA_RST_TX
#define MTK_HSDMA_RST_RX

/* Registers for interrupt control */
#define MTK_HSDMA_DLYINT
#define MTK_HSDMA_RXDLY_INT_EN

/* Interrupt fires when the pending number's more than the specified */
#define MTK_HSDMA_RXMAX_PINT(x)

/* Interrupt fires when the pending time's more than the specified in 20 us */
#define MTK_HSDMA_RXMAX_PTIME(x)
#define MTK_HSDMA_DLYINT_DEFAULT
#define MTK_HSDMA_INT_STATUS
#define MTK_HSDMA_INT_ENABLE
#define MTK_HSDMA_INT_RXDONE

enum mtk_hsdma_vdesc_flag {};

#define IS_MTK_HSDMA_VDESC_FINISHED(x)

/**
 * struct mtk_hsdma_pdesc - This is the struct holding info describing physical
 *			    descriptor (PD) and its placement must be kept at
 *			    4-bytes alignment in little endian order.
 * @desc1:		    | The control pad used to indicate hardware how to
 * @desc2:		    | deal with the descriptor such as source and
 * @desc3:		    | destination address and data length. The maximum
 * @desc4:		    | data length each pdesc can handle is 0x3f80 bytes
 */
struct mtk_hsdma_pdesc {} __packed __aligned();

/**
 * struct mtk_hsdma_vdesc - This is the struct holding info describing virtual
 *			    descriptor (VD)
 * @vd:			    An instance for struct virt_dma_desc
 * @len:		    The total data size device wants to move
 * @residue:		    The remaining data size device will move
 * @dest:		    The destination address device wants to move to
 * @src:		    The source address device wants to move from
 */
struct mtk_hsdma_vdesc {};

/**
 * struct mtk_hsdma_cb - This is the struct holding extra info required for RX
 *			 ring to know what relevant VD the PD is being
 *			 mapped to.
 * @vd:			 Pointer to the relevant VD.
 * @flag:		 Flag indicating what action should be taken when VD
 *			 is completed.
 */
struct mtk_hsdma_cb {};

/**
 * struct mtk_hsdma_ring - This struct holds info describing underlying ring
 *			   space
 * @txd:		   The descriptor TX ring which describes DMA source
 *			   information
 * @rxd:		   The descriptor RX ring which describes DMA
 *			   destination information
 * @cb:			   The extra information pointed at by RX ring
 * @tphys:		   The physical addr of TX ring
 * @rphys:		   The physical addr of RX ring
 * @cur_tptr:		   Pointer to the next free descriptor used by the host
 * @cur_rptr:		   Pointer to the last done descriptor by the device
 */
struct mtk_hsdma_ring {};

/**
 * struct mtk_hsdma_pchan - This is the struct holding info describing physical
 *			   channel (PC)
 * @ring:		   An instance for the underlying ring
 * @sz_ring:		   Total size allocated for the ring
 * @nr_free:		   Total number of free rooms in the ring. It would
 *			   be accessed and updated frequently between IRQ
 *			   context and user context to reflect whether ring
 *			   can accept requests from VD.
 */
struct mtk_hsdma_pchan {};

/**
 * struct mtk_hsdma_vchan - This is the struct holding info describing virtual
 *			   channel (VC)
 * @vc:			   An instance for struct virt_dma_chan
 * @issue_completion:	   The wait for all issued descriptors completited
 * @issue_synchronize:	   Bool indicating channel synchronization starts
 * @desc_hw_processing:	   List those descriptors the hardware is processing,
 *			   which is protected by vc.lock
 */
struct mtk_hsdma_vchan {};

/**
 * struct mtk_hsdma_soc - This is the struct holding differences among SoCs
 * @ddone:		  Bit mask for DDONE
 * @ls0:		  Bit mask for LS0
 */
struct mtk_hsdma_soc {};

/**
 * struct mtk_hsdma_device - This is the struct holding info describing HSDMA
 *			     device
 * @ddev:		     An instance for struct dma_device
 * @base:		     The mapped register I/O base
 * @clk:		     The clock that device internal is using
 * @irq:		     The IRQ that device are using
 * @dma_requests:	     The number of VCs the device supports to
 * @vc:			     The pointer to all available VCs
 * @pc:			     The pointer to the underlying PC
 * @pc_refcnt:		     Track how many VCs are using the PC
 * @lock:		     Lock protect agaisting multiple VCs access PC
 * @soc:		     The pointer to area holding differences among
 *			     various platform
 */
struct mtk_hsdma_device {};

static struct mtk_hsdma_device *to_hsdma_dev(struct dma_chan *chan)
{}

static inline struct mtk_hsdma_vchan *to_hsdma_vchan(struct dma_chan *chan)
{}

static struct mtk_hsdma_vdesc *to_hsdma_vdesc(struct virt_dma_desc *vd)
{}

static struct device *hsdma2dev(struct mtk_hsdma_device *hsdma)
{}

static u32 mtk_dma_read(struct mtk_hsdma_device *hsdma, u32 reg)
{}

static void mtk_dma_write(struct mtk_hsdma_device *hsdma, u32 reg, u32 val)
{}

static void mtk_dma_rmw(struct mtk_hsdma_device *hsdma, u32 reg,
			u32 mask, u32 set)
{}

static void mtk_dma_set(struct mtk_hsdma_device *hsdma, u32 reg, u32 val)
{}

static void mtk_dma_clr(struct mtk_hsdma_device *hsdma, u32 reg, u32 val)
{}

static void mtk_hsdma_vdesc_free(struct virt_dma_desc *vd)
{}

static int mtk_hsdma_busy_wait(struct mtk_hsdma_device *hsdma)
{}

static int mtk_hsdma_alloc_pchan(struct mtk_hsdma_device *hsdma,
				 struct mtk_hsdma_pchan *pc)
{}

static void mtk_hsdma_free_pchan(struct mtk_hsdma_device *hsdma,
				 struct mtk_hsdma_pchan *pc)
{}

static int mtk_hsdma_issue_pending_vdesc(struct mtk_hsdma_device *hsdma,
					 struct mtk_hsdma_pchan *pc,
					 struct mtk_hsdma_vdesc *hvd)
{}

static void mtk_hsdma_issue_vchan_pending(struct mtk_hsdma_device *hsdma,
					  struct mtk_hsdma_vchan *hvc)
{}

static void mtk_hsdma_free_rooms_in_ring(struct mtk_hsdma_device *hsdma)
{}

static irqreturn_t mtk_hsdma_irq(int irq, void *devid)
{}

static struct virt_dma_desc *mtk_hsdma_find_active_desc(struct dma_chan *c,
							dma_cookie_t cookie)
{}

static enum dma_status mtk_hsdma_tx_status(struct dma_chan *c,
					   dma_cookie_t cookie,
					   struct dma_tx_state *txstate)
{}

static void mtk_hsdma_issue_pending(struct dma_chan *c)
{}

static struct dma_async_tx_descriptor *
mtk_hsdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest,
			  dma_addr_t src, size_t len, unsigned long flags)
{}

static int mtk_hsdma_free_inactive_desc(struct dma_chan *c)
{}

static void mtk_hsdma_free_active_desc(struct dma_chan *c)
{}

static int mtk_hsdma_terminate_all(struct dma_chan *c)
{}

static int mtk_hsdma_alloc_chan_resources(struct dma_chan *c)
{}

static void mtk_hsdma_free_chan_resources(struct dma_chan *c)
{}

static int mtk_hsdma_hw_init(struct mtk_hsdma_device *hsdma)
{}

static int mtk_hsdma_hw_deinit(struct mtk_hsdma_device *hsdma)
{}

static const struct mtk_hsdma_soc mt7623_soc =;

static const struct mtk_hsdma_soc mt7622_soc =;

static const struct of_device_id mtk_hsdma_match[] =;
MODULE_DEVICE_TABLE(of, mtk_hsdma_match);

static int mtk_hsdma_probe(struct platform_device *pdev)
{}

static void mtk_hsdma_remove(struct platform_device *pdev)
{}

static struct platform_driver mtk_hsdma_driver =;
module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();