Re: [Patch v4 2/2] dmaengine: Add ADM driver
On Mon, Mar 16, 2015 at 08:15:26AM -, sricha...@codeaurora.org wrote: > Hi, > > > > > >> > >> > +static int adm_get_blksize(unsigned int burst) > >> > +{ > >> > +int ret; > >> > + > >> > +switch (burst) { > >> > +case 16: > >> > +ret = 0; > >> > +break; > >> > +case 32: > >> > +ret = 1; > >> > +break; > >> > +case 64: > >> > +ret = 2; > >> > +break; > >> > +case 128: > >> > +ret = 3; > >> > +break; > >> > +case 192: > >> > +ret = 4; > >> > +break; > >> > +case 256: > >> > +ret = 5; > >> > +break; > >> ffs(burst>>4) ? > > > > that should work nicely. thanks. > > > Will not work for 192, 256 ? you are right. I'll have to separate those out into 2 more cases. Good catch! -- Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Patch v4 2/2] dmaengine: Add ADM driver
Hi, > >> >> > +static int adm_get_blksize(unsigned int burst) >> > +{ >> > + int ret; >> > + >> > + switch (burst) { >> > + case 16: >> > + ret = 0; >> > + break; >> > + case 32: >> > + ret = 1; >> > + break; >> > + case 64: >> > + ret = 2; >> > + break; >> > + case 128: >> > + ret = 3; >> > + break; >> > + case 192: >> > + ret = 4; >> > + break; >> > + case 256: >> > + ret = 5; >> > + break; >> ffs(burst>>4) ? > > that should work nicely. thanks. > Will not work for 192, 256 ? Regards, Sricharan -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Patch v4 2/2] dmaengine: Add ADM driver
On Fri, Mar 13, 2015 at 02:27:45PM +0530, Vinod Koul wrote: > On Wed, Feb 11, 2015 at 11:46:05PM -0600, Andy Gross wrote: > > +++ b/drivers/dma/qcom_adm.c > > @@ -0,0 +1,901 @@ > > +/* > > + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. > shouldn't this be 15 :) yeah, need to update. > > +/* ADM registers - calculated from channel number and security domain */ > > +#define HI_CH_CMD_PTR(chan, ee)(4*chan + 0x20800*ee) > > +#define HI_CH_RSLT(chan, ee) (0x40 + 4*chan + 0x20800*ee) > > +#define HI_CH_FLUSH_STATE0(chan, ee) (0x80 + 4*chan + 0x20800*ee) > > +#define HI_CH_FLUSH_STATE1(chan, ee) (0xc0 + 4*chan + 0x20800*ee) > > +#define HI_CH_FLUSH_STATE2(chan, ee) (0x100 + 4*chan + 0x20800*ee) > > +#define HI_CH_FLUSH_STATE3(chan, ee) (0x140 + 4*chan + 0x20800*ee) > > +#define HI_CH_FLUSH_STATE4(chan, ee) (0x180 + 4*chan + 0x20800*ee) > > +#define HI_CH_FLUSH_STATE5(chan, ee) (0x1c0 + 4*chan + 0x20800*ee) > > +#define HI_CH_STATUS_SD(chan, ee) (0x200 + 4*chan + 0x20800*ee) > > +#define HI_CH_CONF(chan) (0x240 + 4*chan) > > +#define HI_CH_RSLT_CONF(chan, ee) (0x300 + 4*chan + 0x20800*ee) > > +#define HI_SEC_DOMAIN_IRQ_STATUS(ee) (0x380 + 0x20800*ee) > > +#define HI_CI_CONF(ci) (0x390 + 4*ci) > > +#define HI_CRCI_CONF0 0x3d0 > > +#define HI_CRCI_CONF1 0x3d4 > > +#define HI_GP_CTL 0x3d8 > > +#define HI_CRCI_CTL(crci, ee) (0x400 + 0x4*crci + 0x20800*ee) > two things, one the names are quite generic and may cause conflicts so pls > fix that. Second the values, what is the deal with 4*chan, should that be a > define as well. Also rather than copy pasting a macros would be better for > this expansion Yeah there are sets of registers that have both channel and execution environment offsets. It is messy. I'll try to make it more sane. > > > + > > +/* channel status */ > > +#define CH_STATUS_VALIDBIT(1) > > + > > +/* channel result */ > > +#define CH_RSLT_VALID BIT(31) > > +#define CH_RSLT_ERRBIT(3) > > +#define CH_RSLT_FLUSH BIT(2) > > +#define CH_RSLT_TPDBIT(1) > > + > > +/* channel conf */ > > +#define CH_CONF_MPU_DISABLEBIT(11) > > +#define CH_CONF_PERM_MPU_CONF BIT(9) > > +#define CH_CONF_FLUSH_RSLT_EN BIT(8) > > +#define CH_CONF_FORCE_RSLT_EN BIT(7) > > +#define CH_CONF_IRQ_EN BIT(6) > > + > > +/* channel result conf */ > > +#define CH_RSLT_CONF_FLUSH_EN BIT(1) > > +#define CH_RSLT_CONF_IRQ_ENBIT(0) > > + > > +/* CRCI CTL */ > > +#define CRCI_CTL_MUX_SEL BIT(18) > > +#define CRCI_CTL_RST BIT(17) > > + > > +/* CI configuration */ > > +#define CI_RANGE_END(x)(x << 24) > > +#define CI_RANGE_START(x) (x << 16) > > +#define CI_BURST_4_WORDS 0x4 > > +#define CI_BURST_8_WORDS 0x8 > shouldn't you be consistent is usage of BIT() good catch > > + > > +/* GP CTL */ > > +#define GP_CTL_LP_EN BIT(12) > > +#define GP_CTL_LP_CNT(x) (x << 8) > > + > > +/* Command pointer list entry */ > > +#define CPLE_LPBIT(31) > > +#define CPLE_CMD_PTR_LIST BIT(29) > > + > > +/* Command list entry */ > > +#define CMD_LC BIT(31) > > +#define CMD_DST_CRCI(n)(((n) & 0xf) << 7) > > +#define CMD_SRC_CRCI(n)(((n) & 0xf) << 3) > > + > > +#define CMD_TYPE_SINGLE0x0 > > +#define CMD_TYPE_BOX 0x3a > naming issues... ok. will try to come up with something better > > +static int adm_alloc_chan(struct dma_chan *chan) > > +{ > > + return 0; > > +} > This is no longer mandatory, so can be dropped will remove > > > +static int adm_get_blksize(unsigned int burst) > > +{ > > + int ret; > > + > > + switch (burst) { > > + case 16: > > + ret = 0; > > + break; > > + case 32: > > + ret = 1; > > + break; > > + case 64: > > + ret = 2; > > + break; > > + case 128: > > + ret = 3; > > + break; > > + case 192: > > + ret = 4; > > + break; > > + case 256: > > + ret = 5; > > + break; > ffs(burst>>4) ? that should work nicely. thanks. > > +static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan > > *chan, > > + struct scatterlist *sgl, unsigned int sg_len, > > + enum dma_transfer_direction direction, unsigned long flags, > > + void *context) > > +{ > > + struct adm_chan *achan = to_adm_chan(chan); > > + struct adm_device *adev = achan->adev; > > + struct adm_async_desc *async_desc; > > + struct scatterlist *sg; > > + u32 i; > > + u32 single_count = 0, box_count = 0, desc_offset = 0, crci = 0; > > + struct adm_desc_hw_box *box_desc; > > + struct adm_desc_hw_single *single_desc; > > + void *desc; > > + u32 *cple, *last_cmd; > > + u32 burst; > > + int blk_size = 0; > > + >
Re: [Patch v4 2/2] dmaengine: Add ADM driver
On Wed, Feb 11, 2015 at 11:46:05PM -0600, Andy Gross wrote: > +++ b/drivers/dma/qcom_adm.c > @@ -0,0 +1,901 @@ > +/* > + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. shouldn't this be 15 :) +/* ADM registers - calculated from channel number and security domain */ > +#define HI_CH_CMD_PTR(chan, ee) (4*chan + 0x20800*ee) > +#define HI_CH_RSLT(chan, ee) (0x40 + 4*chan + 0x20800*ee) > +#define HI_CH_FLUSH_STATE0(chan, ee) (0x80 + 4*chan + 0x20800*ee) > +#define HI_CH_FLUSH_STATE1(chan, ee) (0xc0 + 4*chan + 0x20800*ee) > +#define HI_CH_FLUSH_STATE2(chan, ee) (0x100 + 4*chan + 0x20800*ee) > +#define HI_CH_FLUSH_STATE3(chan, ee) (0x140 + 4*chan + 0x20800*ee) > +#define HI_CH_FLUSH_STATE4(chan, ee) (0x180 + 4*chan + 0x20800*ee) > +#define HI_CH_FLUSH_STATE5(chan, ee) (0x1c0 + 4*chan + 0x20800*ee) > +#define HI_CH_STATUS_SD(chan, ee)(0x200 + 4*chan + 0x20800*ee) > +#define HI_CH_CONF(chan) (0x240 + 4*chan) > +#define HI_CH_RSLT_CONF(chan, ee)(0x300 + 4*chan + 0x20800*ee) > +#define HI_SEC_DOMAIN_IRQ_STATUS(ee) (0x380 + 0x20800*ee) > +#define HI_CI_CONF(ci) (0x390 + 4*ci) > +#define HI_CRCI_CONF00x3d0 > +#define HI_CRCI_CONF10x3d4 > +#define HI_GP_CTL0x3d8 > +#define HI_CRCI_CTL(crci, ee)(0x400 + 0x4*crci + 0x20800*ee) two things, one the names are quite generic and may cause conflicts so pls fix that. Second the values, what is the deal with 4*chan, should that be a define as well. Also rather than copy pasting a macros would be better for this expansion > + > +/* channel status */ > +#define CH_STATUS_VALID BIT(1) > + > +/* channel result */ > +#define CH_RSLT_VALIDBIT(31) > +#define CH_RSLT_ERR BIT(3) > +#define CH_RSLT_FLUSHBIT(2) > +#define CH_RSLT_TPD BIT(1) > + > +/* channel conf */ > +#define CH_CONF_MPU_DISABLE BIT(11) > +#define CH_CONF_PERM_MPU_CONFBIT(9) > +#define CH_CONF_FLUSH_RSLT_ENBIT(8) > +#define CH_CONF_FORCE_RSLT_ENBIT(7) > +#define CH_CONF_IRQ_EN BIT(6) > + > +/* channel result conf */ > +#define CH_RSLT_CONF_FLUSH_ENBIT(1) > +#define CH_RSLT_CONF_IRQ_EN BIT(0) > + > +/* CRCI CTL */ > +#define CRCI_CTL_MUX_SEL BIT(18) > +#define CRCI_CTL_RST BIT(17) > + > +/* CI configuration */ > +#define CI_RANGE_END(x) (x << 24) > +#define CI_RANGE_START(x)(x << 16) > +#define CI_BURST_4_WORDS 0x4 > +#define CI_BURST_8_WORDS 0x8 shouldn't you be consistent is usage of BIT() > + > +/* GP CTL */ > +#define GP_CTL_LP_EN BIT(12) > +#define GP_CTL_LP_CNT(x) (x << 8) > + > +/* Command pointer list entry */ > +#define CPLE_LP BIT(31) > +#define CPLE_CMD_PTR_LISTBIT(29) > + > +/* Command list entry */ > +#define CMD_LC BIT(31) > +#define CMD_DST_CRCI(n) (((n) & 0xf) << 7) > +#define CMD_SRC_CRCI(n) (((n) & 0xf) << 3) > + > +#define CMD_TYPE_SINGLE 0x0 > +#define CMD_TYPE_BOX 0x3a naming issues... > +static int adm_alloc_chan(struct dma_chan *chan) > +{ > + return 0; > +} This is no longer mandatory, so can be dropped > +static int adm_get_blksize(unsigned int burst) > +{ > + int ret; > + > + switch (burst) { > + case 16: > + ret = 0; > + break; > + case 32: > + ret = 1; > + break; > + case 64: > + ret = 2; > + break; > + case 128: > + ret = 3; > + break; > + case 192: > + ret = 4; > + break; > + case 256: > + ret = 5; > + break; ffs(burst>>4) ? > +static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan > *chan, > + struct scatterlist *sgl, unsigned int sg_len, > + enum dma_transfer_direction direction, unsigned long flags, > + void *context) > +{ > + struct adm_chan *achan = to_adm_chan(chan); > + struct adm_device *adev = achan->adev; > + struct adm_async_desc *async_desc; > + struct scatterlist *sg; > + u32 i; > + u32 single_count = 0, box_count = 0, desc_offset = 0, crci = 0; > + struct adm_desc_hw_box *box_desc; > + struct adm_desc_hw_single *single_desc; > + void *desc; > + u32 *cple, *last_cmd; > + u32 burst; > + int blk_size = 0; > + > + > + if (!is_slave_direction(direction)) { > + dev_err(adev->dev, "invalid dma direction\n"); > + return NULL; > + } > + > + /* > + * get burst value from slave configuration > + * If zero, default to maximum burst size > + * If larger than the max transfer size, set to ADM_MAX_XFER > + */ > + burst = (direction == DMA_MEM_TO_DEV) ? > + achan->slave.dst_maxburst : > + achan->slave.src_maxburst; > + > + if (!burst || burst > ADM_MAX_XFER) > +
[Patch v4 2/2] dmaengine: Add ADM driver
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA controller found in the MSM8x60 and IPQ/APQ8064 platforms. The ADM supports both memory to memory transactions and memory to/from peripheral device transactions. The controller also provides flow control capabilities for transactions to/from peripheral devices. The initial release of this driver supports slave transfers to/from peripherals and also incorporates CRCI (client rate control interface) flow control. Signed-off-by: Andy Gross --- drivers/dma/Kconfig| 10 + drivers/dma/Makefile |1 + drivers/dma/qcom_adm.c | 901 3 files changed, 912 insertions(+) create mode 100644 drivers/dma/qcom_adm.c diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index f2b2c4e..69bc15e 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -464,4 +464,14 @@ config QCOM_BAM_DMA Enable support for the QCOM BAM DMA controller. This controller provides DMA capabilities for a variety of on-chip devices. +config QCOM_ADM + tristate "Qualcomm ADM support" + depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM) + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + ---help--- + Enable support for the Qualcomm ADM DMA controller. This controller + provides DMA capabilities for both general purpose and on-chip + peripheral devices. + endif diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 2022b54..3b7ead6 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -50,3 +50,4 @@ obj-y += xilinx/ obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o obj-$(CONFIG_DMA_SUN6I) += sun6i-dma.o +obj-$(CONFIG_QCOM_ADM) += qcom_adm.o diff --git a/drivers/dma/qcom_adm.c b/drivers/dma/qcom_adm.c new file mode 100644 index 000..baea945 --- /dev/null +++ b/drivers/dma/qcom_adm.c @@ -0,0 +1,901 @@ +/* + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dmaengine.h" +#include "virt-dma.h" + +/* ADM registers - calculated from channel number and security domain */ +#define HI_CH_CMD_PTR(chan, ee)(4*chan + 0x20800*ee) +#define HI_CH_RSLT(chan, ee) (0x40 + 4*chan + 0x20800*ee) +#define HI_CH_FLUSH_STATE0(chan, ee) (0x80 + 4*chan + 0x20800*ee) +#define HI_CH_FLUSH_STATE1(chan, ee) (0xc0 + 4*chan + 0x20800*ee) +#define HI_CH_FLUSH_STATE2(chan, ee) (0x100 + 4*chan + 0x20800*ee) +#define HI_CH_FLUSH_STATE3(chan, ee) (0x140 + 4*chan + 0x20800*ee) +#define HI_CH_FLUSH_STATE4(chan, ee) (0x180 + 4*chan + 0x20800*ee) +#define HI_CH_FLUSH_STATE5(chan, ee) (0x1c0 + 4*chan + 0x20800*ee) +#define HI_CH_STATUS_SD(chan, ee) (0x200 + 4*chan + 0x20800*ee) +#define HI_CH_CONF(chan) (0x240 + 4*chan) +#define HI_CH_RSLT_CONF(chan, ee) (0x300 + 4*chan + 0x20800*ee) +#define HI_SEC_DOMAIN_IRQ_STATUS(ee) (0x380 + 0x20800*ee) +#define HI_CI_CONF(ci) (0x390 + 4*ci) +#define HI_CRCI_CONF0 0x3d0 +#define HI_CRCI_CONF1 0x3d4 +#define HI_GP_CTL 0x3d8 +#define HI_CRCI_CTL(crci, ee) (0x400 + 0x4*crci + 0x20800*ee) + +/* channel status */ +#define CH_STATUS_VALIDBIT(1) + +/* channel result */ +#define CH_RSLT_VALID BIT(31) +#define CH_RSLT_ERRBIT(3) +#define CH_RSLT_FLUSH BIT(2) +#define CH_RSLT_TPDBIT(1) + +/* channel conf */ +#define CH_CONF_MPU_DISABLEBIT(11) +#define CH_CONF_PERM_MPU_CONF BIT(9) +#define CH_CONF_FLUSH_RSLT_EN BIT(8) +#define CH_CONF_FORCE_RSLT_EN BIT(7) +#define CH_CONF_IRQ_EN BIT(6) + +/* channel result conf */ +#define CH_RSLT_CONF_FLUSH_EN BIT(1) +#define CH_RSLT_CONF_IRQ_ENBIT(0) + +/* CRCI CTL */ +#define CRCI_CTL_MUX_SEL BIT(18) +#define CRCI_CTL_RST BIT(17) + +/* CI configuration */ +#define CI_RANGE_END(x)(x << 24) +#define CI_RANGE_START(x) (x << 16) +#define CI_BURST_4_WORDS 0x4 +#define CI_BURST_8_WORDS 0x8 + +/* GP CTL */ +#define GP_CTL_LP_EN BIT(12) +#define GP_CTL_LP_CNT(x) (x << 8) + +/* Command pointer list entry */ +#define CPLE_LPBIT(31) +#define CPLE_CMD_PTR_LIST BIT(29) + +/* Command list entry */ +#def