bsptemplate/asspandvariant/template_assp/dmapsl.cpp
branchRCL_3
changeset 28 5b5d147c7838
parent 8 538db54a451d
equal deleted inserted replaced
26:c734af59ce98 28:5b5d147c7838
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    19 
    19 
    20 #include <kernel/kern_priv.h>
    20 #include <kernel/kern_priv.h>
    21 #include <template_assp.h>									// /assp/template_assp/
    21 #include <template_assp.h>									// /assp/template_assp/
    22 
    22 
    23 #include <drivers/dma.h>
    23 #include <drivers/dma.h>
    24 #include <drivers/dma_hai.h>
       
    25 
    24 
    26 
    25 
    27 // Debug support
    26 // Debug support
    28 static const char KDmaPanicCat[] = "DMA PSL - " __FILE__;
    27 static const char KDmaPanicCat[] = "DMA PSL - " __FILE__;
    29 
    28 
    30 static const TInt KMaxTransferLen = 0x1FE0;	// max transfer length for this DMAC
    29 static const TInt KMaxTransferLen = 0x1FE0;					// max transfer length for this DMAC
    31 static const TInt KMemAlignMask = 7; // memory addresses passed to DMAC must be multiple of 8
    30 static const TInt KMemAlignMask = 7;				  // memory addresses passed to DMAC must be multiple of 8
    32 static const TInt KChannelCount = 16;			// we got 16 channels
    31 static const TInt KChannelCount = 16;						// we got 16 channels
    33 static const TInt KDesCount = 160;				// Initial DMA descriptor count
    32 static const TInt KDesCount = 1024;							// DMA descriptor count
    34 
    33 
    35 
    34 
    36 class TDmaDesc
    35 class TDmaDesc
    37 //
    36 //
    38 // Hardware DMA descriptor
    37 // Hardware DMA descriptor
    75 //
    74 //
    76 	{
    75 	{
    77 	return TestInfo;
    76 	return TestInfo;
    78 	}
    77 	}
    79 
    78 
    80 /**
       
    81 TO DO: Fill in to provide information to the V2 test harness (t_dma2.exe)
       
    82 */
       
    83 TDmaV2TestInfo TestInfov2 =
       
    84 	{
       
    85 	0,
       
    86 	0,
       
    87 	0,
       
    88 	0,
       
    89 	{0},
       
    90 	0,
       
    91 	{0},
       
    92 	0,
       
    93 	{0}
       
    94 	};
       
    95 
       
    96 EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2()
       
    97 	{
       
    98 	return TestInfov2;
       
    99 	}
       
   100 
    79 
   101 //////////////////////////////////////////////////////////////////////////////
    80 //////////////////////////////////////////////////////////////////////////////
   102 // Helper Functions
    81 // Helper Functions
   103 //////////////////////////////////////////////////////////////////////////////
    82 //////////////////////////////////////////////////////////////////////////////
   104 
    83 
   109 	{
    88 	{
   110 	return ((TLinAddr)aDes & 0xF) == 0;
    89 	return ((TLinAddr)aDes & 0xF) == 0;
   111 	}
    90 	}
   112 
    91 
   113 
    92 
   114 static TUint32 DmaCmdReg(TUint aCount, TUint aFlags, TUint32 aSrcPslInfo, TUint32 aDstPslInfo)
    93 static TUint32 DcmdReg(TInt aCount, TUint aFlags, TUint32 aPslInfo)
   115 //
    94 //
   116 // Returns value to set in DMA command register or in descriptor command field.
    95 // Returns value to set in DMA command register or in descriptor command field.
   117 //
    96 //
   118 	{
    97 	{
   119 	// TO DO: Construct CMD word from input values.
    98 	// TO DO: Construct CMD word from input values.
   120 	// The return value should reflect the actual control word.
    99 	// The return value should reflect the actual control word.
   121 	return (aCount | aFlags | aSrcPslInfo | aDstPslInfo);
   100 	return (aCount | aFlags | aPslInfo);
   122 	}
   101 	}
   123 
   102 
   124 
   103 
   125 //////////////////////////////////////////////////////////////////////////////
   104 //////////////////////////////////////////////////////////////////////////////
   126 // Derived Channel (Scatter/Gather)
   105 // Derived Channel (Scatter/Gather)
   143 public:
   122 public:
   144 	TTemplateDmac();
   123 	TTemplateDmac();
   145 	TInt Create();
   124 	TInt Create();
   146 private:
   125 private:
   147 	// from TDmac (PIL pure virtual)
   126 	// from TDmac (PIL pure virtual)
       
   127 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
   148 	virtual void StopTransfer(const TDmaChannel& aChannel);
   128 	virtual void StopTransfer(const TDmaChannel& aChannel);
   149 	virtual TBool IsIdle(const TDmaChannel& aChannel);
   129 	virtual TBool IsIdle(const TDmaChannel& aChannel);
   150 	virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags,
   130 	virtual TInt MaxTransferSize(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo);
   151 									TUint aDstFlags, TUint32 aPslInfo);
   131 	virtual TUint MemAlignMask(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo);
   152 	virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags,
       
   153 								   TUint aDstFlags, TUint32 aPslInfo);
       
   154 	// from TDmac (PIL virtual)
   132 	// from TDmac (PIL virtual)
   155 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
   133 	virtual void InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount,
   156 	virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
   134  						   TUint aFlags, TUint32 aPslInfo, TUint32 aCookie);
   157 	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
   135 	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
   158 	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   136 	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   159 							 const SDmaDesHdr& aNewHdr);
   137 							 const SDmaDesHdr& aNewHdr);
   160 	virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
   138 	virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
   161 	// other
   139 	// other
   171 static TTemplateDmac Controller;
   149 static TTemplateDmac Controller;
   172 
   150 
   173 
   151 
   174 const TDmac::SCreateInfo TTemplateDmac::KInfo =
   152 const TDmac::SCreateInfo TTemplateDmac::KInfo =
   175 	{
   153 	{
   176 	ETrue,													// iCapsHwDes
   154 	KChannelCount,
   177 	KDesCount,												// iDesCount
   155 	KDesCount,
   178 	sizeof(TDmaDesc),										// iDesSize
   156 	TDmac::KCapsBitHwDes,
   179 	EMapAttrSupRw | EMapAttrFullyBlocking					// iDesChunkAttribs
   157 	sizeof(TDmaDesc),
       
   158 	EMapAttrSupRw | EMapAttrFullyBlocking
   180 	};
   159 	};
   181 
   160 
   182 
   161 
   183 TTemplateDmac::TTemplateDmac()
   162 TTemplateDmac::TTemplateDmac()
   184 //
   163 //
   199 		__DMA_ASSERTA(ReserveSetOfDes(KChannelCount) == KErrNone);
   178 		__DMA_ASSERTA(ReserveSetOfDes(KChannelCount) == KErrNone);
   200 		for (TInt i=0; i < KChannelCount; ++i)
   179 		for (TInt i=0; i < KChannelCount; ++i)
   201 			{
   180 			{
   202 			TDmaDesc* pD = HdrToHwDes(*iFreeHdr);
   181 			TDmaDesc* pD = HdrToHwDes(*iFreeHdr);
   203 			iChannels[i].iTmpDes = pD;
   182 			iChannels[i].iTmpDes = pD;
   204 			iChannels[i].iTmpDesPhysAddr = HwDesLinToPhys(pD);
   183 			iChannels[i].iTmpDesPhysAddr = DesLinToPhys(pD);
   205 			iFreeHdr = iFreeHdr->iNext;
   184 			iFreeHdr = iFreeHdr->iNext;
   206 			}
   185 			}
   207 		r = Interrupt::Bind(EAsspIntIdDma, Isr, this);
   186 		r = Interrupt::Bind(EAsspIntIdDma, Isr, this);
   208 		if (r == KErrNone)
   187 		if (r == KErrNone)
   209 			{
   188 			{
   263 
   242 
   264 	return ETrue;
   243 	return ETrue;
   265 	}
   244 	}
   266 
   245 
   267 
   246 
   268 TUint TTemplateDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/,
   247 TInt TTemplateDmac::MaxTransferSize(TDmaChannel& /*aChannel*/, TUint /*aFlags*/, TUint32 /*aPslInfo*/)
   269 									   TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
   248 //
   270 //
   249 // Returns the maximum transfer size for a given transfer.
   271 // Returns the maximum transfer length in bytes for a given transfer.
       
   272 //
   250 //
   273 	{
   251 	{
   274 	// TO DO: Determine the proper return value, based on the arguments.
   252 	// TO DO: Determine the proper return value, based on the arguments.
   275 
   253 
   276 	// For instance:
   254 	// For instance:
   277 	return KMaxTransferLen;
   255 	return KMaxTransferLen;
   278 	}
   256 	}
   279 
   257 
   280 
   258 
   281 TUint TTemplateDmac::AddressAlignMask(TDmaChannel& aChannel, TUint /*aSrcFlags*/,
   259 TUint TTemplateDmac::MemAlignMask(TDmaChannel& /*aChannel*/, TUint /*aFlags*/, TUint32 /*aPslInfo*/)
   282 									  TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
       
   283 //
   260 //
   284 // Returns the memory buffer alignment restrictions mask for a given transfer.
   261 // Returns the memory buffer alignment restrictions mask for a given transfer.
   285 //
   262 //
   286 	{
   263 	{
   287 	// TO DO: Determine the proper return value, based on the arguments.
   264 	// TO DO: Determine the proper return value, based on the arguments.
   289 	// For instance:
   266 	// For instance:
   290 	return KMemAlignMask;
   267 	return KMemAlignMask;
   291 	}
   268 	}
   292 
   269 
   293 
   270 
   294 TInt TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs)
   271 void TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount,
       
   272 							  TUint aFlags, TUint32 aPslInfo, TUint32 /*aCookie*/)
   295 //
   273 //
   296 // Sets up (from a passed in request) the descriptor with that fragment's
   274 // Sets up (from a passed in request) the descriptor with that fragment's
   297 // source and destination address, the fragment size, and the (driver/DMA
   275 // source and destination address, the fragment size, and the (driver/DMA
   298 // controller) specific transfer parameters (mem/peripheral, burst size,
   276 // controller) specific transfer parameters (mem/peripheral, burst size,
   299 // transfer width).
   277 // transfer width).
   304 	__KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::InitHwDes 0x%08X", pD));
   282 	__KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::InitHwDes 0x%08X", pD));
   305 
   283 
   306 	// Unaligned descriptor? Bug in generic layer!
   284 	// Unaligned descriptor? Bug in generic layer!
   307 	__DMA_ASSERTD(IsHwDesAligned(pD));
   285 	__DMA_ASSERTD(IsHwDesAligned(pD));
   308 
   286 
   309 	const TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
   287 	pD->iSrcAddr = (aFlags & KDmaPhysAddrSrc) ? aSrc : Epoc::LinearToPhysical(aSrc);
   310 	const TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
   288 	__DMA_ASSERTD(pD->iSrcAddr != KPhysAddrInvalid);
   311 	pD->iSrcAddr  = (src.iFlags & KDmaPhysAddr) ? src.iAddr : Epoc::LinearToPhysical(src.iAddr);
   289 	pD->iDestAddr = (aFlags & KDmaPhysAddrDest) ? aDest : Epoc::LinearToPhysical(aDest);
   312 	pD->iDestAddr = (dst.iFlags & KDmaPhysAddr) ? dst.iAddr : Epoc::LinearToPhysical(dst.iAddr);
   290 	__DMA_ASSERTD(pD->iDestAddr != KPhysAddrInvalid);
   313 	pD->iCmd = DmaCmdReg(aTransferArgs.iTransferCount, aTransferArgs.iFlags,
   291 	pD->iCmd = DcmdReg(aCount, aFlags, aPslInfo);
   314 					   src.iPslTargetInfo, dst.iPslTargetInfo);
       
   315 	pD->iDescAddr = TDmaDesc::KStopBitMask;
   292 	pD->iDescAddr = TDmaDesc::KStopBitMask;
   316 
       
   317 	return KErrNone;
       
   318 	}
   293 	}
   319 
   294 
   320 
   295 
   321 void TTemplateDmac::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr)
   296 void TTemplateDmac::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr)
   322 //
   297 //
   332 	// Unaligned descriptor? Bug in generic layer!
   307 	// Unaligned descriptor? Bug in generic layer!
   333 	__DMA_ASSERTD(IsHwDesAligned(pD) && IsHwDesAligned(pN));
   308 	__DMA_ASSERTD(IsHwDesAligned(pD) && IsHwDesAligned(pN));
   334 
   309 
   335 	// TO DO: Modify pD->iCmd so that no end-of-transfer interrupt gets raised any longer.
   310 	// TO DO: Modify pD->iCmd so that no end-of-transfer interrupt gets raised any longer.
   336 
   311 
   337 	pD->iDescAddr = HwDesLinToPhys(pN);
   312 	pD->iDescAddr = DesLinToPhys(pN);
   338 	}
   313 	}
   339 
   314 
   340 
   315 
   341 void TTemplateDmac::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   316 void TTemplateDmac::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   342 								const SDmaDesHdr& aNewHdr)
   317 								const SDmaDesHdr& aNewHdr)
   352 	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::AppendHwDes channel=%d last des=0x%08X new des=0x%08X",
   327 	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::AppendHwDes channel=%d last des=0x%08X new des=0x%08X",
   353 									i, pL, pN));
   328 									i, pL, pN));
   354 	// Unaligned descriptor? Bug in generic layer!
   329 	// Unaligned descriptor? Bug in generic layer!
   355 	__DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN));
   330 	__DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN));
   356 
   331 
   357 	TPhysAddr newPhys = HwDesLinToPhys(pN);
   332 	TPhysAddr newPhys = DesLinToPhys(pN);
   358 
   333 
   359 	const TInt irq = NKern::DisableAllInterrupts();
   334 	const TInt irq = NKern::DisableAllInterrupts();
   360 	StopTransfer(aChannel);
   335 	StopTransfer(aChannel);
   361 
   336 
   362 	pL->iDescAddr = newPhys;
   337 	pL->iDescAddr = newPhys;
   396 	{
   371 	{
   397 	TTemplateDmac& me = *static_cast<TTemplateDmac*>(aThis);
   372 	TTemplateDmac& me = *static_cast<TTemplateDmac*>(aThis);
   398 
   373 
   399 	// TO DO: Implement the behaviour described above, call HandleIsr().
   374 	// TO DO: Implement the behaviour described above, call HandleIsr().
   400 
   375 
   401 	HandleIsr(me.iChannels[5], EDmaCallbackRequestCompletion, ETrue); // Example
   376 	HandleIsr(me.iChannels[5], 0);							// Example
   402 
   377 
   403 	}
   378 	}
   404 
   379 
   405 
   380 
   406 inline TDmaDesc* TTemplateDmac::HdrToHwDes(const SDmaDesHdr& aHdr)
   381 inline TDmaDesc* TTemplateDmac::HdrToHwDes(const SDmaDesHdr& aHdr)
   414 
   389 
   415 //////////////////////////////////////////////////////////////////////////////
   390 //////////////////////////////////////////////////////////////////////////////
   416 // Channel Opening/Closing (Channel Allocator)
   391 // Channel Opening/Closing (Channel Allocator)
   417 //////////////////////////////////////////////////////////////////////////////
   392 //////////////////////////////////////////////////////////////////////////////
   418 
   393 
   419 TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId, TBool /*aDynChannel*/, TUint /*aPriority*/)
   394 TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId)
   420 //
   395 //
   421 //
   396 //
   422 //
   397 //
   423 	{
   398 	{
   424 	__KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId));
   399 	__KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId));
   467 // Creates and initializes a new DMA controller object on the kernel heap.
   442 // Creates and initializes a new DMA controller object on the kernel heap.
   468 //
   443 //
   469 	{
   444 	{
   470 	__KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension"));
   445 	__KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension"));
   471 
   446 
   472 	const TInt r = DmaChannelMgr::Initialise();
       
   473 	if (r != KErrNone)
       
   474 		{
       
   475 		return r;
       
   476 		}
       
   477 	return Controller.Create();
   447 	return Controller.Create();
   478 	}
   448 	}