From 54d102fc3af508152542b2e664480d3da943f9ea Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 9 Jul 2010 23:41:31 +0530 Subject: [arm/tegra] nvrm dma: Option to select peripheral bus width. It is require to change the peripheral bus width dynamically. Provide option to select the peripheral bus width through the structure NvRmDmaClientBuffer. The bus width information is passed with upper 16 bit of the wrapsize parameter which is member of struct NvRmDmaClientBuffer. Change-Id: I3e1dc84c08b98d7337ca7e661715abb3dc54667a Reviewed-on: http://git-master.nvidia.com/r/3243 Reviewed-by: Laxman Dewangan Reviewed-by: Vinod Gopalakrishnakurup Tested-by: Vinod Gopalakrishnakurup Reviewed-by: Gary King --- arch/arm/mach-tegra/include/nvrm_dma.h | 22 +++++++++++++++++----- arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c | 27 +++++++++++++++++++++------ 2 files changed, 38 insertions(+), 11 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-tegra/include/nvrm_dma.h b/arch/arm/mach-tegra/include/nvrm_dma.h index 2ff199ae03f5..c4d54ce6172f 100644 --- a/arch/arm/mach-tegra/include/nvrm_dma.h +++ b/arch/arm/mach-tegra/include/nvrm_dma.h @@ -95,6 +95,8 @@ typedef struct NvRmDmaCapabilitiesRec NvU32 DmaAddressAlignmentSize; } NvRmDmaCapabilities; +#define ADDRESS_WRAP(bus_width_bits, wrap_size_byte) \ + (((bus_width_bits/8) << 16) | (wrap_size_byte & 0xFFFF)) /** * @brief Defines the DMA client buffer information which is transferred * recently. The direction of data transfer decides based on this address. The @@ -111,14 +113,24 @@ typedef struct NvRmDmaClientBufferRec /// Specifies the dma destination buffer physical address for dma transfer. NvRmPhysAddr DestinationBufferPhyAddress; - /// Source address wrap size in bytes. It tells that after how much bytes, - /// it will be wrapped. + /// Source address wrap size in bytes and source bus width. + /// The lower 16 bytes tells that after how much bytes, it will be wrapped. /// If it is zero then wrapping for source address is disabled. + /// The upper 16 bytes tells that what is the bus width of the source side. + /// The value of 0 is for default, 1 for 8 bit, 2 for 16 bit and 4 for 32 bit. + /// The default bus width of memory side is 32 bit and + /// for apb side: 8 bit for uart client and 32 bit for other client. + /// Use macro ADDRESS_WRAP to set this parameter. NvU32 SourceAddressWrapSize; - /// Destination address wrap size in bytes. It tells that after how much - /// bytes, it will be wrapped. If it is zero then wrapping for destination - /// address is disabled. + /// Destination address wrap size in bytes and source bus width. + /// The lower 16 bytes tells that after how much bytes, it will be wrapped. + /// If it is zero then wrapping for destination address is disabled. + /// The upper 16 bytes tells that what is the bus width of the source side. + /// The value of 0 is for default, 1 for 8 bit, 2 for 16 bit and 4 for 32 bit. + /// The default bus width of memory side is 32 bit and + /// for apb side: 8 bit for uart client and 32 bit for other client. + /// Use macro ADDRESS_WRAP to set this parameter. NvU32 DestinationAddressWrapSize; /// Specifies the size of the buffer in bytes which is requested for diff --git a/arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c b/arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c index 2943c1895442..42e003ed8ec8 100644 --- a/arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c +++ b/arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c @@ -202,6 +202,8 @@ NvError NvRmDmaStartDmaTransfer(NvRmDmaHandle dma, NvRmDmaClientBuffer *b, { bool periph_src, periph_dst; unsigned long src, dst; + unsigned long src_width, dst_width, periph_width; + unsigned long src_wrap, dst_wrap; struct dma_action *action; NvError e = NvSuccess; DECLARE_COMPLETION_ONSTACK(dma_done); @@ -219,6 +221,12 @@ NvError NvRmDmaStartDmaTransfer(NvRmDmaHandle dma, NvRmDmaClientBuffer *b, src = b->SourceBufferPhyAddress; dst = b->DestinationBufferPhyAddress; + src_wrap = b->SourceAddressWrapSize & 0xFFFF; + dst_wrap = b->DestinationAddressWrapSize & 0xFFFF; + + src_width = (b->SourceAddressWrapSize >> 16) & 0xFFFF; + dst_width = (b->DestinationAddressWrapSize >> 16) & 0xFFFF; + WARN_ON_ONCE((src < PAGE_SIZE) || (dst < PAGE_SIZE)); periph_src = (src - IO_APB_PHYS < IO_APB_SIZE); @@ -239,27 +247,34 @@ NvError NvRmDmaStartDmaTransfer(NvRmDmaHandle dma, NvRmDmaClientBuffer *b, action->req.threshold = NULL; action->dma = dma; + if (periph_src && src_width) + periph_width = src_width*8; + else if (periph_dst && dst_width) + periph_width = dst_width*8; + else + periph_width = dma->mod_width; + if ((periph_src && dir==NvRmDmaDirection_Forward) || (periph_dst && dir==NvRmDmaDirection_Reverse)) { action->req.to_memory = 1; action->req.dest_bus_width = 32; - action->req.source_bus_width = dma->mod_width; + action->req.source_bus_width = periph_width; } else { action->req.to_memory = 0; - action->req.dest_bus_width = dma->mod_width; + action->req.dest_bus_width = periph_width; action->req.source_bus_width = 32; } if (dir==NvRmDmaDirection_Forward) { action->req.dest_addr = dst; action->req.source_addr = src; - action->req.dest_wrap = b->DestinationAddressWrapSize; - action->req.source_wrap = b->SourceAddressWrapSize; + action->req.dest_wrap = dst_wrap; + action->req.source_wrap = src_wrap; } else { action->req.dest_addr = src; action->req.source_addr = dst; - action->req.dest_wrap = b->SourceAddressWrapSize; - action->req.source_wrap = b->DestinationAddressWrapSize; + action->req.dest_wrap = src_wrap; + action->req.source_wrap = dst_wrap; } if (timeout) { -- cgit v1.2.3