/*
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*
* QCOM BAM DMA engine driver
*
* QCOM BAM DMA blocks are distributed amongst a number of the on-chip
* peripherals on the MSM 8x74. The configuration of the channels are dependent
* on the way they are hard wired to that specific peripheral. The peripheral
* device tree entries specify the configuration of each channel.
*
* The DMA controller requires the use of external memory for storage of the
* hardware descriptors for each channel. The descriptor FIFO is accessed as a
* circular buffer and operations are managed according to the offset within the
* FIFO. After pipe/channel reset, all of the pipe registers and internal state
* are back to defaults.
*
* During DMA operations, we write descriptors to the FIFO, being careful to
* handle wrapping and then write the last FIFO offset to that channel's
* P_EVNT_REG register to kick off the transaction. The P_SW_OFSTS register
* indicates the current FIFO offset that is being processed, so there is some
* indication of where the hardware is currently working.
*/
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_dma.h>
#include <linux/circ_buf.h>
#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/pm_runtime.h>
#include "../dmaengine.h"
#include "../virt-dma.h"
struct bam_desc_hw {
__le32 addr; /* Buffer physical address */
__le16 size; /* Buffer size in bytes */
__le16 flags;
};
#define BAM_DMA_AUTOSUSPEND_DELAY 100
#define DESC_FLAG_INT BIT(15)
#define DESC_FLAG_EOT BIT(14)
#define DESC_FLAG_EOB BIT(13)
#define DESC_FLAG_NWD BIT(12)
#define DESC_FLAG_CMD BIT(11)
struct bam_async_desc {
struct virt_dma_desc vd;
u32 num_desc;
u32 xfer_len;
/* transaction flags, EOT|EOB|NWD */
u16 flags;
struct bam_desc_hw *curr_desc;
/* list node for the desc in the bam_chan list of descriptors */
struct list_head