bsptemplate/asspandvariant/template_assp/dmapsl.cpp
changeset 36 538db54a451d
parent 0 a41df078684a
child 117 5b5d147c7838
equal deleted inserted replaced
34:f497542af8e4 36:538db54a451d
     9 // Nokia Corporation - initial contribution.
     9 // Nokia Corporation - initial contribution.
    10 //
    10 //
    11 // Contributors:
    11 // Contributors:
    12 //
    12 //
    13 // Description:
    13 // Description:
    14 // template\template_assp\dmapsl.cpp
    14 // bsptemplate/asspvariant/template_assp/dmapsl.cpp
    15 // Template DMA Platform Specific Layer (PSL).
    15 // Template DMA Platform Specific Layer (PSL).
    16 // 
    16 //
    17 //
    17 //
    18 
    18 
    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 #include <drivers/dma.h>
    23 #include <drivers/dma.h>
       
    24 #include <drivers/dma_hai.h>
       
    25 
    23 
    26 
    24 // Debug support
    27 // Debug support
    25 static const char KDmaPanicCat[] = "DMA PSL";
    28 static const char KDmaPanicCat[] = "DMA PSL - " __FILE__;
    26 
    29 
    27 static const TInt KMaxTransferLen = 0x1FE0;					// max transfer length for this DMAC
    30 static const TInt KMaxTransferLen = 0x1FE0;	// max transfer length for this DMAC
    28 static const TInt KMemAlignMask = 7;				  // memory addresses passed to DMAC must be multiple of 8
    31 static const TInt KMemAlignMask = 7; // memory addresses passed to DMAC must be multiple of 8
    29 static const TInt KChannelCount = 16;						// we got 16 channels
    32 static const TInt KChannelCount = 16;			// we got 16 channels
    30 static const TInt KDesCount = 1024;							// DMA descriptor count
    33 static const TInt KDesCount = 160;				// Initial DMA descriptor count
    31 
    34 
    32 
    35 
    33 class TDmaDesc
    36 class TDmaDesc
    34 //
    37 //
    35 // Hardware DMA descriptor
    38 // Hardware DMA descriptor
    47 
    50 
    48 //////////////////////////////////////////////////////////////////////////////
    51 //////////////////////////////////////////////////////////////////////////////
    49 // Test Support
    52 // Test Support
    50 //////////////////////////////////////////////////////////////////////////////
    53 //////////////////////////////////////////////////////////////////////////////
    51 
    54 
       
    55 /**
       
    56 TO DO: Fill in to provide information to the V1 test harness (t_dma.exe)
       
    57 */
    52 TDmaTestInfo TestInfo =
    58 TDmaTestInfo TestInfo =
    53 	{
    59 	{
    54 	0,
    60 	0,
    55 	0,
    61 	0,
    56 	0,
    62 	0,
    69 //
    75 //
    70 	{
    76 	{
    71 	return TestInfo;
    77 	return TestInfo;
    72 	}
    78 	}
    73 
    79 
       
    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 	}
    74 
   100 
    75 //////////////////////////////////////////////////////////////////////////////
   101 //////////////////////////////////////////////////////////////////////////////
    76 // Helper Functions
   102 // Helper Functions
    77 //////////////////////////////////////////////////////////////////////////////
   103 //////////////////////////////////////////////////////////////////////////////
    78 
   104 
    83 	{
   109 	{
    84 	return ((TLinAddr)aDes & 0xF) == 0;
   110 	return ((TLinAddr)aDes & 0xF) == 0;
    85 	}
   111 	}
    86 
   112 
    87 
   113 
    88 static TUint32 DcmdReg(TInt aCount, TUint aFlags, TUint32 aPslInfo)
   114 static TUint32 DmaCmdReg(TUint aCount, TUint aFlags, TUint32 aSrcPslInfo, TUint32 aDstPslInfo)
    89 //
   115 //
    90 // Returns value to set in DMA command register or in descriptor command field.
   116 // Returns value to set in DMA command register or in descriptor command field.
    91 //
   117 //
    92 	{
   118 	{
    93 	// TO DO: Construct CMD word from input values.
   119 	// TO DO: Construct CMD word from input values.
    94 	// The return value should reflect the actual control word.
   120 	// The return value should reflect the actual control word.
    95 	return (aCount | aFlags | aPslInfo);
   121 	return (aCount | aFlags | aSrcPslInfo | aDstPslInfo);
    96 	}
   122 	}
    97 
   123 
    98 
   124 
    99 //////////////////////////////////////////////////////////////////////////////
   125 //////////////////////////////////////////////////////////////////////////////
   100 // Derived Channel (Scatter/Gather)
   126 // Derived Channel (Scatter/Gather)
   117 public:
   143 public:
   118 	TTemplateDmac();
   144 	TTemplateDmac();
   119 	TInt Create();
   145 	TInt Create();
   120 private:
   146 private:
   121 	// from TDmac (PIL pure virtual)
   147 	// from TDmac (PIL pure virtual)
   122 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
       
   123 	virtual void StopTransfer(const TDmaChannel& aChannel);
   148 	virtual void StopTransfer(const TDmaChannel& aChannel);
   124 	virtual TBool IsIdle(const TDmaChannel& aChannel);
   149 	virtual TBool IsIdle(const TDmaChannel& aChannel);
   125 	virtual TInt MaxTransferSize(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo);
   150 	virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags,
   126 	virtual TUint MemAlignMask(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo);
   151 									TUint aDstFlags, TUint32 aPslInfo);
       
   152 	virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags,
       
   153 								   TUint aDstFlags, TUint32 aPslInfo);
   127 	// from TDmac (PIL virtual)
   154 	// from TDmac (PIL virtual)
   128 	virtual void InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount,
   155 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
   129  						   TUint aFlags, TUint32 aPslInfo, TUint32 aCookie);
   156 	virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
   130 	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
   157 	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
   131 	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   158 	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   132 							 const SDmaDesHdr& aNewHdr);
   159 							 const SDmaDesHdr& aNewHdr);
   133 	virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
   160 	virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
   134 	// other
   161 	// other
   138 	static const SCreateInfo KInfo;
   165 	static const SCreateInfo KInfo;
   139 public:
   166 public:
   140 	TTemplateSgChannel iChannels[KChannelCount];
   167 	TTemplateSgChannel iChannels[KChannelCount];
   141 	};
   168 	};
   142 
   169 
       
   170 
   143 static TTemplateDmac Controller;
   171 static TTemplateDmac Controller;
   144 
   172 
       
   173 
   145 const TDmac::SCreateInfo TTemplateDmac::KInfo =
   174 const TDmac::SCreateInfo TTemplateDmac::KInfo =
   146 	{
   175 	{
   147 	KChannelCount,
   176 	ETrue,													// iCapsHwDes
   148 	KDesCount,
   177 	KDesCount,												// iDesCount
   149 	TDmac::KCapsBitHwDes,
   178 	sizeof(TDmaDesc),										// iDesSize
   150 	sizeof(TDmaDesc),
   179 	EMapAttrSupRw | EMapAttrFullyBlocking					// iDesChunkAttribs
   151 	EMapAttrSupRw | EMapAttrFullyBlocking
       
   152 	};
   180 	};
   153 
   181 
   154 
   182 
   155 TTemplateDmac::TTemplateDmac()
   183 TTemplateDmac::TTemplateDmac()
   156 //
   184 //
   171 		__DMA_ASSERTA(ReserveSetOfDes(KChannelCount) == KErrNone);
   199 		__DMA_ASSERTA(ReserveSetOfDes(KChannelCount) == KErrNone);
   172 		for (TInt i=0; i < KChannelCount; ++i)
   200 		for (TInt i=0; i < KChannelCount; ++i)
   173 			{
   201 			{
   174 			TDmaDesc* pD = HdrToHwDes(*iFreeHdr);
   202 			TDmaDesc* pD = HdrToHwDes(*iFreeHdr);
   175 			iChannels[i].iTmpDes = pD;
   203 			iChannels[i].iTmpDes = pD;
   176 			iChannels[i].iTmpDesPhysAddr = DesLinToPhys(pD);
   204 			iChannels[i].iTmpDesPhysAddr = HwDesLinToPhys(pD);
   177 			iFreeHdr = iFreeHdr->iNext;
   205 			iFreeHdr = iFreeHdr->iNext;
   178 			}
   206 			}
   179 		r = Interrupt::Bind(EAsspIntIdDma, Isr, this);
   207 		r = Interrupt::Bind(EAsspIntIdDma, Isr, this);
   180 		if (r == KErrNone)
   208 		if (r == KErrNone)
   181 			{
   209 			{
   235 
   263 
   236 	return ETrue;
   264 	return ETrue;
   237 	}
   265 	}
   238 
   266 
   239 
   267 
   240 TInt TTemplateDmac::MaxTransferSize(TDmaChannel& /*aChannel*/, TUint /*aFlags*/, TUint32 /*aPslInfo*/)
   268 TUint TTemplateDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/,
   241 //
   269 									   TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
   242 // Returns the maximum transfer size for a given transfer.
   270 //
       
   271 // Returns the maximum transfer length in bytes for a given transfer.
   243 //
   272 //
   244 	{
   273 	{
   245 	// TO DO: Determine the proper return value, based on the arguments.
   274 	// TO DO: Determine the proper return value, based on the arguments.
   246 
   275 
   247 	// For instance:
   276 	// For instance:
   248 	return KMaxTransferLen;
   277 	return KMaxTransferLen;
   249 	}
   278 	}
   250 
   279 
   251 
   280 
   252 TUint TTemplateDmac::MemAlignMask(TDmaChannel& /*aChannel*/, TUint /*aFlags*/, TUint32 /*aPslInfo*/)
   281 TUint TTemplateDmac::AddressAlignMask(TDmaChannel& aChannel, TUint /*aSrcFlags*/,
       
   282 									  TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
   253 //
   283 //
   254 // Returns the memory buffer alignment restrictions mask for a given transfer.
   284 // Returns the memory buffer alignment restrictions mask for a given transfer.
   255 //
   285 //
   256 	{
   286 	{
   257 	// TO DO: Determine the proper return value, based on the arguments.
   287 	// TO DO: Determine the proper return value, based on the arguments.
   259 	// For instance:
   289 	// For instance:
   260 	return KMemAlignMask;
   290 	return KMemAlignMask;
   261 	}
   291 	}
   262 
   292 
   263 
   293 
   264 void TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount,
   294 TInt TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs)
   265 							  TUint aFlags, TUint32 aPslInfo, TUint32 /*aCookie*/)
   295 //
   266 //
   296 // Sets up (from a passed in request) the descriptor with that fragment's
   267 // Sets up (from a passed in request) the descriptor with that fragment's source and destination address,
   297 // source and destination address, the fragment size, and the (driver/DMA
   268 // the fragment size, and the (driver/DMA controller) specific transfer parameters (mem/peripheral,
   298 // controller) specific transfer parameters (mem/peripheral, burst size,
   269 // burst size, transfer width).
   299 // transfer width).
   270 //
   300 //
   271 	{
   301 	{
   272 	TDmaDesc* pD = HdrToHwDes(aHdr);
   302 	TDmaDesc* pD = HdrToHwDes(aHdr);
   273 
   303 
   274 	__KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::InitHwDes 0x%08X", pD));
   304 	__KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::InitHwDes 0x%08X", pD));
   275 
   305 
   276 	// Unaligned descriptor? Bug in generic layer!
   306 	// Unaligned descriptor? Bug in generic layer!
   277 	__DMA_ASSERTD(IsHwDesAligned(pD));
   307 	__DMA_ASSERTD(IsHwDesAligned(pD));
   278 
   308 
   279 	pD->iSrcAddr = (aFlags & KDmaPhysAddrSrc) ? aSrc : Epoc::LinearToPhysical(aSrc);
   309 	const TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
   280 	pD->iDestAddr = (aFlags & KDmaPhysAddrDest) ? aDest : Epoc::LinearToPhysical(aDest);
   310 	const TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
   281 	pD->iCmd = DcmdReg(aCount, aFlags, aPslInfo);
   311 	pD->iSrcAddr  = (src.iFlags & KDmaPhysAddr) ? src.iAddr : Epoc::LinearToPhysical(src.iAddr);
       
   312 	pD->iDestAddr = (dst.iFlags & KDmaPhysAddr) ? dst.iAddr : Epoc::LinearToPhysical(dst.iAddr);
       
   313 	pD->iCmd = DmaCmdReg(aTransferArgs.iTransferCount, aTransferArgs.iFlags,
       
   314 					   src.iPslTargetInfo, dst.iPslTargetInfo);
   282 	pD->iDescAddr = TDmaDesc::KStopBitMask;
   315 	pD->iDescAddr = TDmaDesc::KStopBitMask;
       
   316 
       
   317 	return KErrNone;
   283 	}
   318 	}
   284 
   319 
   285 
   320 
   286 void TTemplateDmac::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr)
   321 void TTemplateDmac::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr)
   287 //
   322 //
   297 	// Unaligned descriptor? Bug in generic layer!
   332 	// Unaligned descriptor? Bug in generic layer!
   298 	__DMA_ASSERTD(IsHwDesAligned(pD) && IsHwDesAligned(pN));
   333 	__DMA_ASSERTD(IsHwDesAligned(pD) && IsHwDesAligned(pN));
   299 
   334 
   300 	// TO DO: Modify pD->iCmd so that no end-of-transfer interrupt gets raised any longer.
   335 	// TO DO: Modify pD->iCmd so that no end-of-transfer interrupt gets raised any longer.
   301 
   336 
   302 	pD->iDescAddr = DesLinToPhys(pN);
   337 	pD->iDescAddr = HwDesLinToPhys(pN);
   303 	}
   338 	}
   304 
   339 
   305 
   340 
   306 void TTemplateDmac::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   341 void TTemplateDmac::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   307 								const SDmaDesHdr& aNewHdr)
   342 								const SDmaDesHdr& aNewHdr)
   317 	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::AppendHwDes channel=%d last des=0x%08X new des=0x%08X",
   352 	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::AppendHwDes channel=%d last des=0x%08X new des=0x%08X",
   318 									i, pL, pN));
   353 									i, pL, pN));
   319 	// Unaligned descriptor? Bug in generic layer!
   354 	// Unaligned descriptor? Bug in generic layer!
   320 	__DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN));
   355 	__DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN));
   321 
   356 
   322 	TPhysAddr newPhys = DesLinToPhys(pN);
   357 	TPhysAddr newPhys = HwDesLinToPhys(pN);
   323 
   358 
   324 	const TInt irq = NKern::DisableAllInterrupts();
   359 	const TInt irq = NKern::DisableAllInterrupts();
   325 	StopTransfer(aChannel);
   360 	StopTransfer(aChannel);
   326 
   361 
   327 	pL->iDescAddr = newPhys;
   362 	pL->iDescAddr = newPhys;
   361 	{
   396 	{
   362 	TTemplateDmac& me = *static_cast<TTemplateDmac*>(aThis);
   397 	TTemplateDmac& me = *static_cast<TTemplateDmac*>(aThis);
   363 
   398 
   364 	// TO DO: Implement the behaviour described above, call HandleIsr().
   399 	// TO DO: Implement the behaviour described above, call HandleIsr().
   365 
   400 
   366 	HandleIsr(me.iChannels[5], 0);							// Example
   401 	HandleIsr(me.iChannels[5], EDmaCallbackRequestCompletion, ETrue); // Example
   367 
   402 
   368 	}
   403 	}
   369 
   404 
   370 
   405 
   371 inline TDmaDesc* TTemplateDmac::HdrToHwDes(const SDmaDesHdr& aHdr)
   406 inline TDmaDesc* TTemplateDmac::HdrToHwDes(const SDmaDesHdr& aHdr)
   379 
   414 
   380 //////////////////////////////////////////////////////////////////////////////
   415 //////////////////////////////////////////////////////////////////////////////
   381 // Channel Opening/Closing (Channel Allocator)
   416 // Channel Opening/Closing (Channel Allocator)
   382 //////////////////////////////////////////////////////////////////////////////
   417 //////////////////////////////////////////////////////////////////////////////
   383 
   418 
   384 TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId)
   419 TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId, TBool /*aDynChannel*/, TUint /*aPriority*/)
   385 //
   420 //
   386 //
   421 //
   387 //
   422 //
   388 	{
   423 	{
   389 	__KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId));
   424 	__KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId));
   390 
   425 
   391 	__DMA_ASSERTA(aOpenId < static_cast<TUint32>(KChannelCount));
   426 	__DMA_ASSERTA(aOpenId < static_cast<TUint32>(KChannelCount));
   392 
   427 
   393 	TDmaChannel* pC = Controller.iChannels + aOpenId;
   428 	TDmaChannel* pC = Controller.iChannels + aOpenId;
   394 	if (pC->IsOpened())
   429 	if (pC->IsOpened())
       
   430 		{
   395 		pC = NULL;
   431 		pC = NULL;
       
   432 		}
   396 	else
   433 	else
   397 		{
   434 		{
   398 		pC->iController = &Controller;
   435 		pC->iController = &Controller;
   399 		pC->iPslId = aOpenId;
   436 		pC->iPslId = aOpenId;
   400 		}
   437 		}
   401 
   438 
   402 	return pC;
   439 	return pC;
   403 	}
   440 	}
   404 
   441 
   405 
   442 
   406 void DmaChannelMgr::Close(TDmaChannel* /* aChannel */)
   443 void DmaChannelMgr::Close(TDmaChannel* /*aChannel*/)
   407 //
   444 //
   408 //
   445 //
   409 //
   446 //
   410 	{
   447 	{
   411 	// NOP
   448 	// NOP
   412 	}
   449 	}
   413 
   450 
   414 
   451 
   415 TInt DmaChannelMgr::StaticExtension(TInt /* aCmd */, TAny* /* aArg */)
   452 TInt DmaChannelMgr::StaticExtension(TInt /*aCmd*/, TAny* /*aArg*/)
   416 //
   453 //
   417 //
   454 //
   418 //
   455 //
   419 	{
   456 	{
   420 	return KErrNotSupported;
   457 	return KErrNotSupported;
   430 // Creates and initializes a new DMA controller object on the kernel heap.
   467 // Creates and initializes a new DMA controller object on the kernel heap.
   431 //
   468 //
   432 	{
   469 	{
   433 	__KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension"));
   470 	__KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension"));
   434 
   471 
       
   472 	const TInt r = DmaChannelMgr::Initialise();
       
   473 	if (r != KErrNone)
       
   474 		{
       
   475 		return r;
       
   476 		}
   435 	return Controller.Create();
   477 	return Controller.Create();
   436 	}
   478 	}