omap3530/beagle_drivers/wb/api/hal/cyashalbeagleboard.cpp
changeset 27 117faf51deac
equal deleted inserted replaced
26:b7e488c49d0d 27:117faf51deac
       
     1 // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // omap3530/beagle_drivers/wb/cyashalbeagleboard_spi.cpp
       
    15 //
       
    16 
       
    17 #include <kern_priv.h>
       
    18 #include <beagle/beagle_gpio.h>
       
    19 #include <beagle/variant.h>
       
    20 #include <assp/omap3530_assp/omap3530_assp_priv.h>
       
    21 #include <assp/omap3530_assp/omap3530_irqmap.h> // GPIO interrupts
       
    22 #include <assp/omap3530_assp/omap3530_gpio.h>
       
    23 
       
    24 #include <assp.h> // Required for definition of TIsr
       
    25 
       
    26 #include <cyasregs.h> // Astoria register definitions
       
    27 
       
    28 #ifdef __CY_ASTORIA_BEAGLEBOARD_SPI__HAL__
       
    29 
       
    30 #include "cyashalbeagleboard_spi.h"
       
    31 #include "cyaserr.h"
       
    32 #include "cyasregs.h"
       
    33 #include "cyasdma.h"
       
    34 #include "cyasintr.h"
       
    35 #ifdef FIRMWARE_NOPPORT
       
    36 
       
    37 #ifdef OVERCLOCK_SD
       
    38 #include "cyastfw_sd_mmc_rel_nopport_Ast121_68.h"
       
    39 #else
       
    40 #include "cyastfw_sd_mmc_rel_nopport.h"
       
    41 #endif
       
    42 
       
    43 #else
       
    44 
       
    45 #ifdef OVERCLOCK_SD
       
    46 #include "cyastfw_sd_mmc_rel_silicon_Ast121_68.h"
       
    47 #else
       
    48 #include "cyastfw_sd_mmc_rel_silicon.h"
       
    49 #endif
       
    50 
       
    51 #endif
       
    52 
       
    53 #include "cyasusbinit.h"
       
    54 
       
    55 /*
       
    56  * For performance reasons, we handle storage endpoint transfers upto 4 KB
       
    57  * within the HAL itself.
       
    58  */
       
    59 #define CYASSTORAGE_WRITE_EP_NUM	(4)
       
    60 #define CYASSTORAGE_READ_EP_NUM		(8)
       
    61 #define CYASSTORAGE_MAX_XFER_SIZE	(2*32768)
       
    62 
       
    63 /*#define MONITOR_THREAD 1*/
       
    64 #define INT_DE 1
       
    65 
       
    66 /* DFC queue */
       
    67 TDfc* gpDfc;
       
    68 
       
    69 /*
       
    70  * The type of DMA operation, per endpoint
       
    71  */
       
    72 typedef enum CyAsHalDmaType
       
    73 {
       
    74     CyAsHalRead,
       
    75     CyAsHalWrite,
       
    76     CyAsHalNone
       
    77 } CyAsHalDmaType ;
       
    78 
       
    79 typedef struct CyAsHalEndpointDma
       
    80 {
       
    81     CyBool buffer_valid ;
       
    82     uint16_t *data_p ;
       
    83     uint32_t size ;
       
    84     /*struct scatterlist* sg_p ;
       
    85     uint16_t scatter_index ;*/
       
    86     uint32_t bytes_xfered ;
       
    87     uint16_t transfer_cnt ;
       
    88     CyAsHalDmaType type ;
       
    89     CyBool pending ;
       
    90 } CyAsHalEndpointDma ;
       
    91 
       
    92 /*
       
    93  * The list of OMAP devices (should be one)
       
    94  */
       
    95 static CyAsOmapDevKernel *m_omap_list_p = 0 ;
       
    96 
       
    97 /*
       
    98  * The callback to call after DMA operations are complete
       
    99  */
       
   100 static CyAsHalDmaCompleteCallback callback = 0 ;
       
   101 
       
   102 /*
       
   103  * Pending data size for the endpoints
       
   104  */
       
   105 static CyAsHalEndpointDma EndPoints[16] ;
       
   106 
       
   107 /* Forward declaration */
       
   108 static void CyHandleDRQInterrupt(CyAsOmapDevKernel *dev_p) ;
       
   109 
       
   110 static volatile uint32_t Intr_Disabled = 0 ;
       
   111 static volatile CyAsHalDeviceTag gDevTag = 0 ;
       
   112 
       
   113 #define CYAS_INT_MASK (CY_AS_MEM_P0_INTR_REG_MCUINT | CY_AS_MEM_P0_INTR_REG_MBINT | \
       
   114                        CY_AS_MEM_P0_INTR_REG_PMINT | CY_AS_MEM_P0_INTR_REG_PLLLOCKINT)
       
   115 #define CYAS_DRQ_MASK (CY_AS_MEM_P0_INTR_REG_DRQINT)
       
   116 
       
   117 
       
   118 static void
       
   119 CyAstoriaISR (
       
   120     void *dev_id)
       
   121 {
       
   122 #ifdef SPI_DEBUG_LOG
       
   123 	Kern::Printf("CyAstoriaISR...");
       
   124 #endif
       
   125 	gpDfc->Add();
       
   126 
       
   127 #ifdef SPI_DEBUG_LOG
       
   128 	Kern::Printf("Disable interrupt");
       
   129 #endif
       
   130 	/* Disable Interrupt Here, it will be re-enabled by DFCs */
       
   131 	GPIO::DisableInterrupt(KGPIO_INT) ;
       
   132 }
       
   133 
       
   134 static void
       
   135 CyAstoriaIntHandler_DFC (
       
   136     TAny *aPtr)
       
   137 {
       
   138     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)aPtr ;
       
   139     uint16_t          read_val = 0 ;
       
   140 #ifdef SPI_DEBUG_LOG
       
   141 	Kern::Printf("CyAstoriaIntHandler called...");
       
   142 #endif
       
   143     {
       
   144 		read_val = CyAsHalReadRegister((CyAsHalDeviceTag)dev_p, CY_AS_MEM_P0_INTR_REG) ;
       
   145 		if (read_val & CYAS_INT_MASK)
       
   146 		{
       
   147 			CyAsIntrServiceInterrupt((CyAsHalDeviceTag)dev_p) ;
       
   148 		}
       
   149 
       
   150 		if (read_val & CYAS_DRQ_MASK)
       
   151 		{
       
   152 			CyHandleDRQInterrupt(dev_p) ;
       
   153 		}
       
   154     }
       
   155 	GPIO::EnableInterrupt(KGPIO_INT) ;
       
   156 #ifdef SPI_DEBUG_LOG
       
   157 	Kern::Printf("Enable interrupt\n");
       
   158 #endif
       
   159 }
       
   160 
       
   161 extern TmtpAstDev * g_pAstDevice ;
       
   162 
       
   163 static int
       
   164 CyAsHalConfigureInterrupts (
       
   165     void *dev_p,
       
   166 	void *handler)
       
   167 {
       
   168 
       
   169     return CyAsHalBeagleBoard__SetupISR(handler, dev_p) ;
       
   170 }
       
   171 //nxz-debug
       
   172 void
       
   173 MyOmapStartIntr(CyAsHalDeviceTag tag)
       
   174 {
       
   175     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)tag ;
       
   176 	int ret ;
       
   177 
       
   178     const uint16_t mask = CY_AS_MEM_P0_INTR_REG_DRQINT | CY_AS_MEM_P0_INTR_REG_MBINT ;
       
   179 
       
   180 	/* Setup DFC */
       
   181 	gpDfc = new TDfc( CyAstoriaIntHandler_DFC, tag, Kern::DfcQue0(), 1 ) ;
       
   182 
       
   183     /* Register for interrupts */
       
   184     ret = CyAsHalConfigureInterrupts (dev_p,(void*)CyAstoriaISR) ;
       
   185 	if ( ret != 0 )
       
   186 		Kern::Printf("ERROR: CyAsHalConfigureInterrupts failed\n");
       
   187 
       
   188     /* enable only MBox & DRQ interrupts for now */
       
   189     CyAsHalWriteRegister((CyAsHalDeviceTag)dev_p, CY_AS_MEM_P0_INT_MASK_REG, mask) ;
       
   190 }
       
   191 
       
   192 volatile CyBool interrupt_fired = CyFalse;
       
   193 
       
   194 //This is the Diagnostics Interrupt Handler
       
   195 void
       
   196 MyIntTestHandler(
       
   197 	void *dev_id)
       
   198 {
       
   199     CyAsOmapDevKernel * dev_tag = (CyAsOmapDevKernel*) dev_id ;
       
   200 
       
   201 	Kern::Printf("Diag: CyAsDiagIntHandler called\n");
       
   202 
       
   203 	if(interrupt_fired == CyFalse)
       
   204 	{
       
   205 			Kern::Printf("Diag: CyAsDiagIntHandler, first instance of INT# \n");
       
   206 			interrupt_fired = CyTrue;
       
   207 
       
   208 			//return INT to high state, only called for override testing
       
   209 			CyAsHalWriteRegister(dev_tag, CY_AS_MEM_P0_VM_SET, 0x0745);
       
   210 	}
       
   211 	//return INT to high state, only called for override testing
       
   212 	CyAsHalWriteRegister(dev_tag, CY_AS_MEM_P0_VM_SET, 0x0745);
       
   213 
       
   214 }
       
   215 
       
   216 
       
   217 
       
   218 /*
       
   219 * These are the functions that are not part of the HAL layer, but are required to be called
       
   220 * for this HAL.
       
   221 */
       
   222 int StartOMAPKernel(const char *pgm, CyAsHalDeviceTag *tag, CyBool debug)
       
   223 {
       
   224     CyAsOmapDevKernel *dev_p ;
       
   225     CyAsHalSleepChannel channel ;
       
   226     int i;
       
   227 
       
   228     (void)debug ; /* No debug mode support as of now */
       
   229 
       
   230     Kern::Printf ("<1>startOMAPKernel called\n");
       
   231 
       
   232     /*
       
   233      * Initialize the HAL level endpoint DMA data.
       
   234      */
       
   235     for(i = 0 ; i < sizeof(EndPoints)/sizeof(EndPoints[0]) ; i++)
       
   236     {
       
   237         EndPoints[i].data_p = 0 ;
       
   238         EndPoints[i].pending = CyFalse ;
       
   239         EndPoints[i].size = 0 ;
       
   240         EndPoints[i].type = CyAsHalNone ;
       
   241 		EndPoints[i].bytes_xfered = 0 ;
       
   242 		EndPoints[i].transfer_cnt = 0 ;
       
   243     }
       
   244 
       
   245     dev_p = (CyAsOmapDevKernel *)CyAsHalAlloc(sizeof(CyAsOmapDevKernel)) ;
       
   246     if (dev_p == 0)
       
   247     {
       
   248 		Kern::Printf("<1>%s: out of memory allocating OMAP device structure\n", pgm) ;
       
   249 		return 0 ;
       
   250     }
       
   251     dev_p->m_sig = CY_AS_OMAP_KERNEL_HAL_SIG ;
       
   252     dev_p->m_addr_base = 0 ;
       
   253 
       
   254     CyAsHalBeagleBoard__ConfigureSPI();
       
   255 
       
   256 #ifdef HW_TEST
       
   257 {
       
   258     uint16_t readVal = 0 ;
       
   259 	uint16_t timeOutCounter = 0 ;
       
   260 	uint16_t errCnt = 0 ;
       
   261 
       
   262 	Kern::Printf( "<1> Regsiter Test ------------->\n") ;
       
   263 
       
   264 	readVal = CyAsHalReadRegister(dev_p, CY_AS_MEM_CM_WB_CFG_ID) ;
       
   265 	Kern::Printf("ID reg 0x%04x\n",readVal);
       
   266         if ( readVal != 0xa200 )
       
   267 	{
       
   268 		Kern::Printf("ERROR: Wrong Antioch ID reg value\n");
       
   269 		Kern::Printf("ERROR: Exp:  0x%04x\n",0xa200);
       
   270 		Kern::Printf("ERROR: Act:  0x%04x\n",readVal);
       
   271 		errCnt++;
       
   272 	}
       
   273 
       
   274 	readVal = CyAsHalReadRegister(dev_p, CY_AS_MEM_P0_VM_SET) ;
       
   275 	Kern::Printf("P0_VM_SET 0x%04x\n",readVal);
       
   276 	if ( readVal != 0x45 )
       
   277 	{
       
   278 		Kern::Printf("ERROR: Wrong Antioch P0_VM_SET reg value\n");
       
   279 		Kern::Printf("ERROR: Exp:  0x%04x\n",0x45);
       
   280 		Kern::Printf("ERROR: Act:  0x%04x\n",readVal);
       
   281 		errCnt++;
       
   282 	}
       
   283 
       
   284 	readVal = CyAsHalReadRegister(dev_p, CY_AS_MEM_P0_RSE_ALLOCATE) ;
       
   285 	Kern::Printf("P0_RSE_ALLOCATE 0x%04x\n",readVal);
       
   286 	if ( readVal != 0x26 )
       
   287 	{
       
   288 		Kern::Printf("ERROR: Wrong Antioch P0_RSE_ALLOCATE reg value\n");
       
   289 		Kern::Printf("ERROR: Exp:  0x%04x\n",0x26);
       
   290 		Kern::Printf("ERROR: Act:  0x%04x\n",readVal);
       
   291 		errCnt++;
       
   292 	}
       
   293 
       
   294 	CyAsHalWriteRegister(dev_p, CY_AS_MEM_MCU_MAILBOX0, 0x0);
       
   295 	CyAsHalWriteRegister(dev_p, CY_AS_MEM_MCU_MAILBOX1, 0xFFFF);
       
   296 	CyAsHalWriteRegister(dev_p, CY_AS_MEM_MCU_MAILBOX2, 0xAAAA);
       
   297 	CyAsHalWriteRegister(dev_p, CY_AS_MEM_MCU_MAILBOX3, 0x5555);
       
   298 
       
   299 	readVal = CyAsHalReadRegister(dev_p, CY_AS_MEM_MCU_MAILBOX0) ;
       
   300 	Kern::Printf("mailbox0 0x%04x\n",readVal);
       
   301 	if ( readVal != 0x0 )
       
   302 	{
       
   303 		Kern::Printf("ERROR: Wrong Antioch MAILBOX0 reg value\n");
       
   304 		Kern::Printf("ERROR: Exp:  0x%04x\n",0x0);
       
   305 		Kern::Printf("ERROR: Act:  0x%04x\n",readVal);
       
   306 		errCnt++;
       
   307 	}
       
   308 
       
   309 	readVal = CyAsHalReadRegister(dev_p, CY_AS_MEM_MCU_MAILBOX1) ;
       
   310 	Kern::Printf("mailbox1 0x%04x\n",readVal);
       
   311 	if ( readVal != 0xffff )
       
   312 	{
       
   313 		Kern::Printf("ERROR: Wrong Antioch MAILBOX1 reg value\n");
       
   314 		Kern::Printf("ERROR: Exp:  0x%04x\n",0xffff);
       
   315 		Kern::Printf("ERROR: Act:  0x%04x\n",readVal);
       
   316 		errCnt++;
       
   317 	}
       
   318 
       
   319 	readVal = CyAsHalReadRegister(dev_p, CY_AS_MEM_MCU_MAILBOX2) ;
       
   320     Kern::Printf("mailbox2 0x%04x\n",readVal);
       
   321 	if ( readVal != 0xaaaa )
       
   322 	{
       
   323 		Kern::Printf("ERROR: Wrong Antioch MAILBOX2 reg value\n");
       
   324 		Kern::Printf("ERROR: Exp:  0x%04x\n",0xaaaa);
       
   325 		Kern::Printf("ERROR: Act:  0x%04x\n",readVal);
       
   326 		errCnt++;
       
   327 	}
       
   328 
       
   329 	readVal = CyAsHalReadRegister(dev_p, CY_AS_MEM_MCU_MAILBOX3) ;
       
   330     Kern::Printf("mailbox3 0x%04x\n",readVal);
       
   331 	if ( readVal != 0x5555 )
       
   332 	{
       
   333 		Kern::Printf("ERROR: Wrong Antioch MAILBOX3 reg value\n");
       
   334 		Kern::Printf("ERROR: Exp:  0x%04x\n",0x5555);
       
   335 		Kern::Printf("ERROR: Act:  0x%04x\n",readVal);
       
   336 		errCnt++;
       
   337 	}
       
   338 
       
   339 	Kern::Printf( "<1> Interrupt Test ------------->\n") ;
       
   340 	Kern::Printf("Checking that INT# can execute Procesor ISR:\n");
       
   341 
       
   342 	CyAsHalConfigureInterrupts (dev_p,(void*)MyIntTestHandler) ;
       
   343 
       
   344 	//overrid default INT# value, cause Astoria to assert INT#
       
   345 	CyAsHalWriteRegister(dev_p, CY_AS_MEM_P0_VM_SET, 0x0545);
       
   346 
       
   347 	do {
       
   348 		timeOutCounter++;
       
   349 	}while((interrupt_fired == CyFalse) && (timeOutCounter < 255));
       
   350 
       
   351 	if(interrupt_fired == CyTrue)
       
   352 	{
       
   353 		Kern::Printf("INT# fired Processor ISR\n");
       
   354 	}
       
   355 	else
       
   356 	{
       
   357 		Kern::Printf("ERROR: INT# did not fire processor ISR %i\n", interrupt_fired);
       
   358 		errCnt++;
       
   359 	}
       
   360 
       
   361 	if ( errCnt == 0 )
       
   362 	{
       
   363 		Kern::Printf("HW test passed!!\n") ;
       
   364 	}
       
   365 	else
       
   366 		Kern::Printf("HW test failed (%d)\n",errCnt) ;
       
   367 
       
   368 	Kern::Printf("Reset Astoria\n") ;
       
   369 	CyAsHalWriteRegister(dev_p, CY_AS_MEM_RST_CTRL_REG, CY_AS_MEM_RST_CTRL_REG_HARD) ;
       
   370 	return 0 ;
       
   371 }
       
   372 #endif
       
   373 
       
   374     /*
       
   375      * Now perform a hard reset of the device to have the new settings take
       
   376      * effect
       
   377      */
       
   378     Kern::Printf("<1>West Bridge Device Enters hard reset\n") ;
       
   379     CyAsHalWriteRegister(dev_p, CY_AS_MEM_RST_CTRL_REG, CY_AS_MEM_RST_CTRL_REG_HARD) ;
       
   380 
       
   381     /*
       
   382      * Sleep for 100 ms to be sure reset is complete.
       
   383      */
       
   384     Kern::Printf("<1>Sleep 100ms\n") ;
       
   385     CyAsHalCreateSleepChannel (&channel) ;
       
   386     CyAsHalSleepOn(&channel, 100) ;
       
   387     CyAsHalDestroySleepChannel(&channel) ;
       
   388 	Kern::Printf("<1>MyOmapStartIntr\n") ;
       
   389     MyOmapStartIntr(dev_p);
       
   390 
       
   391     dev_p->m_next_p = m_omap_list_p ;
       
   392     m_omap_list_p = dev_p ;
       
   393 
       
   394     *tag = dev_p ;
       
   395     gDevTag = dev_p ;
       
   396 
       
   397     return 1 ;
       
   398 }
       
   399 
       
   400 int StopOMAPKernel(const char *pgm, CyAsHalDeviceTag tag)
       
   401 {
       
   402     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)tag ;
       
   403 
       
   404     if (0 == dev_p)
       
   405 		return 1 ;
       
   406 
       
   407     Kern::Printf ("<1>StopOMAPKernel called\n");
       
   408     if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG)
       
   409     {
       
   410 		Kern::Printf("<1>%s: %s: bad TAG parameter passed to function\n", pgm, __FUNCTION__) ;
       
   411 		return 1 ;
       
   412     }
       
   413 
       
   414     Kern::Printf ("<1>West Bridge OMAP Kernel: Done cleaning thread\n") ;
       
   415 	/* TODO: */
       
   416 
       
   417     CyAsHalFree(dev_p) ;
       
   418 
       
   419     return 1 ;
       
   420 }
       
   421 
       
   422 
       
   423 /*************************************************************************************************
       
   424 *
       
   425 * Below are the functions that communicate with the West Bridge device.  These are system dependent
       
   426 * and must be defined by the HAL layer for a given system.
       
   427 *
       
   428 *************************************************************************************************/
       
   429 
       
   430 void
       
   431 CyAsHalWriteEP(CyAsHalDeviceTag tag, uint16_t addr, uint8_t* data, uint16_t size)
       
   432 {
       
   433     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)tag ;
       
   434 GPIO::DisableInterrupt(KGPIO_INT) ;
       
   435 
       
   436     /* Do additional error checks while in debug mode. */
       
   437     if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG)
       
   438     {
       
   439 		Kern::Printf("<1>%s: bad TAG parameter passed to function\n",  __FUNCTION__) ;
       
   440 		return ;
       
   441     }
       
   442 
       
   443     if (addr & 0x80)
       
   444     {
       
   445 		Kern::Printf ("<1>West Bridge write EP address 0x%x out of range\n", addr);
       
   446 		return ;
       
   447     }
       
   448 
       
   449 	CyAsHalBeagleBoardMcSPI4Ch0_WriteEP(addr, data, size) ;
       
   450 GPIO::EnableInterrupt(KGPIO_INT) ;
       
   451     return ;
       
   452 }
       
   453 
       
   454 void
       
   455 CyAsHalReadEP(CyAsHalDeviceTag tag, uint16_t addr, uint8_t* data, uint16_t size)
       
   456 {
       
   457     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)tag ;
       
   458 GPIO::DisableInterrupt(KGPIO_INT) ;
       
   459 
       
   460     /* Do additional error checks while in debug mode. */
       
   461     if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG)
       
   462     {
       
   463 		Kern::Printf("<1>%s: bad TAG parameter passed to function\n",  __FUNCTION__) ;
       
   464 		return ;
       
   465     }
       
   466 
       
   467     if (addr & 0x80)
       
   468     {
       
   469 		Kern::Printf ("<1>West Bridge write EP address 0x%x out of range\n", addr);
       
   470 		return ;
       
   471     }
       
   472 
       
   473 	CyAsHalBeagleBoardMcSPI4Ch0_ReadEP(addr, data, size) ;
       
   474 GPIO::EnableInterrupt(KGPIO_INT) ;
       
   475     return ;
       
   476 }
       
   477 
       
   478 /*
       
   479 * This function must be defined to write a register within the West Bridge
       
   480 * device.  The addr value is the address of the register to write with
       
   481 * respect to the base address of the West Bridge device.
       
   482 */
       
   483 void
       
   484 CyAsHalWriteRegister(CyAsHalDeviceTag tag, uint16_t addr, uint16_t data)
       
   485 {
       
   486     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)tag ;
       
   487 GPIO::DisableInterrupt(KGPIO_INT) ;
       
   488 
       
   489     /* Do additional error checks while in debug mode. */
       
   490     if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG)
       
   491     {
       
   492 		Kern::Printf("<1>%s: bad TAG parameter passed to function\n",  __FUNCTION__) ;
       
   493 		return ;
       
   494     }
       
   495 
       
   496     if (addr > CYAS_DEV_MAX_ADDR)
       
   497     {
       
   498 		Kern::Printf ("<1>West Bridge write address 0x%x out of range\n", addr);
       
   499 		return ;
       
   500     }
       
   501 
       
   502 	CyAsHalBeagleBoardMcSPI4Ch0_WriteReg((TUint32) addr, (TUint16) data) ;
       
   503 #ifdef SPI_DEBUG_LOG
       
   504 	Kern::Printf("CyAsHalWriteRegister(0x%02x,0x%04x)\n",addr,data) ;
       
   505 #endif
       
   506 GPIO::EnableInterrupt(KGPIO_INT) ;
       
   507     return ;
       
   508 
       
   509 }
       
   510 
       
   511 /*
       
   512 * This function must be defined to read a register from the West Bridge
       
   513 * device.  The addr value is the address of the register to read with
       
   514 * respect to the base address of the West Bridge device.
       
   515 */
       
   516 uint16_t
       
   517 CyAsHalReadRegister(CyAsHalDeviceTag tag, uint16_t addr)
       
   518 {
       
   519     uint16_t data  = 0 ;
       
   520     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)tag ;
       
   521 GPIO::DisableInterrupt(KGPIO_INT) ;
       
   522 
       
   523     if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG)
       
   524     {
       
   525 		Kern::Printf("<1>%s: bad TAG parameter passed to function\n",  __FUNCTION__) ;
       
   526 		return 0 ;
       
   527     }
       
   528 
       
   529     if (addr > CYAS_DEV_MAX_ADDR)
       
   530     {
       
   531 		Kern::Printf("<1>West Bridge read address 0x%x out of range\n", addr) ;
       
   532 		return 0 ;
       
   533     }
       
   534 
       
   535     CyAsHalBeagleBoardMcSPI4Ch0_ReadReg((TUint32) addr, (TUint16*) &data) ;
       
   536 #ifdef SPI_DEBUG_LOG
       
   537     Kern::Printf("CyAsHalReadRegister(0x%02x,0x%04x)\n",addr,data) ;
       
   538 #endif
       
   539 GPIO::EnableInterrupt(KGPIO_INT) ;
       
   540     return data ;
       
   541 }
       
   542 
       
   543 static void
       
   544 CyServiceEPDmaReadRequest(CyAsOmapDevKernel *dev_p, uint8_t ep)
       
   545 {
       
   546     CyAsHalDeviceTag tag = (CyAsHalDeviceTag)dev_p ;
       
   547     uint16_t  v ;
       
   548     uint32_t  size ;
       
   549     uint16_t  addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
       
   550     uint8_t *dptr = (uint8_t*)EndPoints[ep].data_p ;
       
   551 
       
   552 
       
   553 #ifdef SPI_DEBUG_LOG
       
   554 	Kern::Printf("CyServiceEPDmaReadRequest...");
       
   555 #endif
       
   556     /* Read the amount of data available */
       
   557     v = CyAsHalReadRegister(tag, addr) ;
       
   558     size =  v & CY_AS_MEM_P0_EPn_DMA_REG_COUNT_MASK ;
       
   559 
       
   560 	CyAsHalReadEP(tag, ep, dptr, size) ;
       
   561 
       
   562     /*
       
   563      * Now, reset the DMAVAL bit indicating that the data has been read
       
   564      */
       
   565 
       
   566     CyAsHalWriteRegister(tag, addr, 0) ;
       
   567 
       
   568     EndPoints[ep].pending      = CyFalse ;
       
   569     EndPoints[ep].type         = CyAsHalNone ;
       
   570     EndPoints[ep].buffer_valid = CyFalse ;
       
   571 
       
   572     if (callback)
       
   573 		callback(tag, ep, size, CY_AS_ERROR_SUCCESS) ;
       
   574 }
       
   575 
       
   576 static void
       
   577 CyServiceEPDmaWriteRequest(CyAsOmapDevKernel *dev_p, uint8_t ep)
       
   578 {
       
   579     CyAsHalDeviceTag tag = (CyAsHalDeviceTag)dev_p ;
       
   580     uint16_t  addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
       
   581     uint8_t *dptr = (uint8_t *)EndPoints[ep].data_p ;
       
   582     uint32_t  size ;
       
   583 
       
   584 
       
   585 #ifdef SPI_DEBUG_LOG
       
   586 	Kern::Printf("CyServiceEPDmaWriteRequest...");
       
   587 #endif
       
   588 
       
   589     if ( ep == CYASSTORAGE_WRITE_EP_NUM )
       
   590     {
       
   591 		if ( EndPoints[ep].size == 0x180 )
       
   592 		{
       
   593 			size = 0x180 ;
       
   594 		}
       
   595 		else
       
   596 			size = 0x200 ;
       
   597     }
       
   598     else
       
   599 		size = EndPoints[ep].size ;
       
   600 #ifdef SPI_DEBUG_LOG
       
   601     Kern::Printf("Service DMA write request EP%d, size=%d, ep.size=%d\n",ep,size,EndPoints[ep].size);
       
   602 #endif
       
   603 	#if 1
       
   604 	CyAsHalWriteEP(tag, ep, dptr, size) ;
       
   605 	#else
       
   606 	{
       
   607 		uint16_t v ;
       
   608 		int i ;
       
   609  		for(i = 0 ; i < size / 2 ; i++)
       
   610 		{
       
   611 			v = dptr[0] | (dptr[1] << 8) ;
       
   612 			CyAsHalWriteRegister(tag, ep, v) ;
       
   613 			dptr++ ;
       
   614 			dptr++ ;
       
   615 		}
       
   616 	}
       
   617 	#endif
       
   618 
       
   619     /*
       
   620      * Now, write the DMAVAL bit to indicate we are done transferring data and that the data
       
   621      * can now be sent via USB to the USB host, sent to storage, or used internally.
       
   622      */
       
   623     CyAsHalWriteRegister(tag, addr, size) ;
       
   624 
       
   625     /* We have sent the data, mark it as false */
       
   626     EndPoints[ep].pending = CyFalse ;
       
   627     EndPoints[ep].type     = CyAsHalNone ;
       
   628     EndPoints[ep].buffer_valid = CyFalse ;
       
   629 
       
   630     /*
       
   631      * Finally, tell the USB subsystem that the data is gone and we can accept the
       
   632      * next request if one exists.
       
   633      */
       
   634     if (callback)
       
   635 		callback(tag, ep, size, CY_AS_ERROR_SUCCESS) ;
       
   636 }
       
   637 
       
   638 static void
       
   639 CyHandleDRQInterrupt(CyAsOmapDevKernel *dev_p)
       
   640 {
       
   641     uint16_t v ;
       
   642     static uint8_t service_ep = 2 ;
       
   643     static CyBool indrq = CyFalse ;
       
   644 
       
   645     /*Kern::Printf("<1>DRQ interrupt detected\n") ;*/
       
   646     if (indrq)
       
   647     {
       
   648 #ifndef NDEBUG
       
   649 
       
   650 	Kern::Printf("<1>+++++++++  Nested DRQ interrupt detected\n") ;
       
   651         v = CyAsHalReadRegister((CyAsHalDeviceTag)dev_p, CY_AS_MEM_P0_INTR_REG) ;
       
   652 	Kern::Printf("<1>+++++++++ INTR_REG = %04x\n",v) ;
       
   653     	v = CyAsHalReadRegister((CyAsHalDeviceTag)dev_p, CY_AS_MEM_P0_DRQ) ;
       
   654 	Kern::Printf("<1>+++++++++ DRQ_REG = %04x\n",v) ;
       
   655 #endif
       
   656 	return ;
       
   657     }
       
   658 
       
   659     indrq = CyTrue ;
       
   660 
       
   661     /*
       
   662      * We have received a DMA interrupt
       
   663      */
       
   664     v = CyAsHalReadRegister((CyAsHalDeviceTag)dev_p, CY_AS_MEM_P0_DRQ) ;
       
   665     if (v == 0)
       
   666     {
       
   667 #ifndef NDEBUG
       
   668 	/*Stray DRQ is possible because we will check DRQ register before exit handler*/
       
   669 	Kern::Printf("<1>+++++++++  Stray DRQ interrupt detected\n") ;
       
   670 #endif
       
   671 	indrq = CyFalse;
       
   672 	return ;
       
   673     }
       
   674 
       
   675     /*
       
   676      * Now, pick a given DMA request to handle, for now, we just go round robin.  Each bit
       
   677      * position in the service_mask represents an endpoint from EP2 to EP15.  We rotate through
       
   678      * each of the endpoints to find one that needs to be serviced.
       
   679      */
       
   680     while ((v & (1 << service_ep)) == 0)
       
   681     {
       
   682 	if (service_ep == 15)
       
   683 	    service_ep = 2 ;
       
   684 	else
       
   685 	    service_ep++ ;
       
   686     }
       
   687 
       
   688     if ((v & (1 << service_ep)) == 0)
       
   689     {
       
   690 	Kern::Printf("<1>+++++++++  Internal error, this should not happen\n") ;
       
   691 	indrq = CyFalse;
       
   692 	return ;
       
   693     }
       
   694 
       
   695     if (EndPoints[service_ep].type == CyAsHalWrite)
       
   696 		CyServiceEPDmaWriteRequest(dev_p, service_ep) ;
       
   697     else if (EndPoints[service_ep].type == CyAsHalRead)
       
   698 		CyServiceEPDmaReadRequest(dev_p, service_ep) ;
       
   699 
       
   700 #ifndef NDEBUG
       
   701     else
       
   702     {
       
   703         Kern::Printf("+++++++ Interrupt occurred, but there is no DMA operation pending - check DRQ_MASK logic\n") ;
       
   704     }
       
   705 #endif
       
   706 
       
   707     /* Now bump the EP ahead, so other endpoints get a shot before the one we just serviced */
       
   708     if (EndPoints[service_ep].type == CyAsHalNone)
       
   709     {
       
   710 	if (service_ep == 15)
       
   711 	    service_ep = 2 ;
       
   712 	else
       
   713 	    service_ep++ ;
       
   714     }
       
   715 
       
   716     indrq = CyFalse ;
       
   717 }
       
   718 
       
   719 void
       
   720 CyAsHalDmaCancelRequest(CyAsHalDeviceTag tag, uint8_t ep)
       
   721 {
       
   722     if (EndPoints[ep].pending)
       
   723         CyAsHalWriteRegister(tag, CY_AS_MEM_P0_EP2_DMA_REG + ep - 2, 0) ;
       
   724 
       
   725     EndPoints[ep].buffer_valid = CyFalse ;
       
   726 }
       
   727 
       
   728 /*
       
   729 * This function must be defined to transfer a block of data to the West Bridge device.  This
       
   730 * function can use the burst write (DMA) capabilities of West Bridge to do this, or it can
       
   731 * just copy the data using writes.
       
   732 */
       
   733 void
       
   734 CyAsHalDmaSetupWrite(CyAsHalDeviceTag tag, uint8_t ep, void *buf, uint32_t size, uint16_t maxsize)
       
   735 {
       
   736     uint32_t addr ;
       
   737     uint16_t v ;
       
   738 #ifdef SPI_DEBUG_LOG
       
   739 	Kern::Printf("CyAsHalDmaSetupWrite (%d,%d)",size,maxsize);
       
   740 #endif
       
   741     /* No EP0 or EP1 traffic should get here */
       
   742     CyAsHalAssert(ep != 0 && ep != 1) ;
       
   743 
       
   744     /*
       
   745      * If this asserts, we have an ordering problem.  Another DMA request is coming down
       
   746      * before the previous one has completed.
       
   747      */
       
   748     CyAsHalAssert(EndPoints[ep].buffer_valid == CyFalse) ;
       
   749 
       
   750     /*
       
   751      * Store the data for the interrupt service routine
       
   752      */
       
   753     EndPoints[ep].buffer_valid = CyTrue ;
       
   754     EndPoints[ep].data_p = (uint16_t*)buf ;
       
   755     EndPoints[ep].size = size ;
       
   756     EndPoints[ep].type = CyAsHalWrite ;
       
   757 
       
   758     /*
       
   759      * Tell West Bridge we are ready to send data on the given endpoint
       
   760      */
       
   761     {
       
   762 		addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
       
   763 		v = (size & CY_AS_MEM_P0_EPn_DMA_REG_COUNT_MASK) | CY_AS_MEM_P0_EPn_DMA_REG_DMAVAL ;
       
   764     }
       
   765 
       
   766     CyAsHalWriteRegister(tag, addr, v) ;
       
   767 
       
   768 }
       
   769 
       
   770 /*
       
   771 * This function must be defined to transfer a block of data from the West Bridge device.  This
       
   772 * function can use the burst read (DMA) capabilities of West Bridge to do this, or it can just
       
   773 * copy the data using reads.
       
   774 */
       
   775 void
       
   776 CyAsHalDmaSetupRead(CyAsHalDeviceTag tag, uint8_t ep, void *buf, uint32_t size, uint16_t maxsize)
       
   777 {
       
   778     uint32_t addr ;
       
   779     uint16_t v ;
       
   780 #ifdef SPI_DEBUG_LOG
       
   781 	Kern::Printf("CyAsHalDmaSetupRead (%d,%d)",size,maxsize);
       
   782 #endif
       
   783     /* No EP0 or EP1 traffic should get here */
       
   784     CyAsHalAssert(ep != 0 && ep != 1) ;
       
   785     CyAsHalAssert(EndPoints[ep].buffer_valid == CyFalse) ;
       
   786 
       
   787     EndPoints[ep].buffer_valid = CyTrue ;
       
   788     EndPoints[ep].data_p = (uint16_t*)buf ;
       
   789     EndPoints[ep].size = size ;
       
   790     EndPoints[ep].type = CyAsHalRead ;
       
   791 
       
   792     /*
       
   793      * Program the EP DMA register for Storage endpoints only.
       
   794      */
       
   795     if (ep == 2)
       
   796     {
       
   797 		if (size == 1)
       
   798 		  size = 2 ;
       
   799 
       
   800 		addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
       
   801 		v = (size & CY_AS_MEM_P0_EPn_DMA_REG_COUNT_MASK) | CY_AS_MEM_P0_EPn_DMA_REG_DMAVAL;
       
   802 		CyAsHalWriteRegister(tag, addr, v );
       
   803     }
       
   804     else if (ep == CYASSTORAGE_READ_EP_NUM)
       
   805     {
       
   806         addr = CY_AS_MEM_P0_EP8_DMA_REG ;
       
   807 
       
   808 		/* This transfer is always done in 512 byte chunks. */
       
   809         v = 0x200 | CY_AS_MEM_P0_EPn_DMA_REG_DMAVAL ;
       
   810         CyAsHalWriteRegister(tag, addr, v) ;
       
   811 	}
       
   812 }
       
   813 
       
   814 /*
       
   815 * This function must be defined to allow the West Bridge API to register a callback function that is
       
   816 * called when a DMA transfer is complete.
       
   817 */
       
   818 void
       
   819 CyAsHalDmaRegisterCallback(CyAsHalDeviceTag tag, CyAsHalDmaCompleteCallback cb)
       
   820 {
       
   821     callback = cb ;
       
   822 }
       
   823 
       
   824 /*
       
   825 * This function must be defined to return the maximum size of DMA request that can be handled
       
   826 * on the given endpoint.  The return value should be the maximum size in bytes that the DMA
       
   827 * module can handle.
       
   828 */
       
   829 uint32_t
       
   830 CyAsHalDmaMaxRequestSize(CyAsHalDeviceTag tag, CyAsEndPointNumber_t ep)
       
   831 {
       
   832     /* Storage reads and writes are always done in 512 byte blocks. So, we do the count
       
   833        handling within the HAL, and save on some of the data transfer delay.
       
   834      */
       
   835     if ((ep == CYASSTORAGE_READ_EP_NUM) || (ep == CYASSTORAGE_WRITE_EP_NUM))
       
   836 	return CYASSTORAGE_MAX_XFER_SIZE;
       
   837     else
       
   838 	/*
       
   839 	 * For the USB - Processor endpoints, the maximum transfer size depends on
       
   840 	 * the speed of USB operation. So, we use the following constant to
       
   841 	 * indicate to the API that splitting of the data into chunks less than
       
   842 	 * or equal to the max transfer size should be handled internally.
       
   843 	 */
       
   844 	return CY_AS_DMA_MAX_SIZE_HW_SIZE;
       
   845 }
       
   846 
       
   847 /*
       
   848  * This function must be defined to set the state of the WAKEUP pin on the West Bridge device.  Generally
       
   849  * this is done via a GPIO of some type.
       
   850  */
       
   851 CyBool
       
   852 CyAsHalSetWakeupPin(CyAsHalDeviceTag tag, CyBool state)
       
   853 {
       
   854     /* Not supported as of now. */
       
   855     return CyFalse ;
       
   856 }
       
   857 
       
   858 void
       
   859 CyAsHalPllLockLossHandler(CyAsHalDeviceTag tag)
       
   860 {
       
   861     Kern::Printf("Error: West Bridge PLL has lost lock\n") ;
       
   862     Kern::Printf("Please check the input voltage levels and clock, and restart the system\n") ;
       
   863 }
       
   864 
       
   865 #define CYASHAL_REGISTERS_TO_SAVE_COUNT         (12)
       
   866 static uint16_t gAstoriaRegCache[CYASHAL_REGISTERS_TO_SAVE_COUNT][2] = {
       
   867     {CY_AS_MEM_P0_ENDIAN,        0x0000},
       
   868     {CY_AS_MEM_PMU_UPDATE,       0x0000},
       
   869     {CY_AS_MEM_P0_VM_SET,        0x0000},
       
   870     {CY_AS_MEM_P0_INT_MASK_REG,  0x0000},
       
   871     {CY_AS_MEM_P0_RSE_ALLOCATE,  0x0000},
       
   872     {CY_AS_MEM_P0_RSE_MASK,      0x0000},
       
   873     {CY_AS_MEM_P0_DRQ_MASK,      0x0000},
       
   874     {CY_AS_MEM_IROS_SLB_DATARET, 0x0000},
       
   875     {CY_AS_MEM_IROS_IO_CFG,      0x0000},
       
   876     {CY_AS_MEM_IROS_PLL_CFG,     0x0000},
       
   877     {CY_AS_MEM_IROS_PXB_DATARET, 0x0000},
       
   878     {CY_AS_MEM_IROS_SLEEP_CFG,   0x0000}
       
   879 };
       
   880 
       
   881 void
       
   882 CyAsHalReadRegsBeforeStandby (
       
   883         CyAsHalDeviceTag tag)
       
   884 {
       
   885     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)tag;
       
   886     int i, pos;
       
   887 
       
   888     if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG)
       
   889     {
       
   890         Kern::Printf("%s: bad TAG parameter passed to function\n", __FUNCTION__);
       
   891         return;
       
   892     }
       
   893 
       
   894     {
       
   895         for (i = 0; i < CYASHAL_REGISTERS_TO_SAVE_COUNT; i++)
       
   896         {
       
   897             gAstoriaRegCache[i][1] = CyAsHalReadRegister (tag, gAstoriaRegCache[i][0]);
       
   898 
       
   899             /* Special handling required for the RSE_ALLOCATE register, so as to
       
   900                ensure that the SD_IO pin ownership is set correctly.
       
   901              */
       
   902             if (gAstoriaRegCache[i][0] == CY_AS_MEM_P0_RSE_ALLOCATE)
       
   903             {
       
   904                 /* For each of the 4 two bits fields in the register, set it to 'b01 if the
       
   905                  * resource is currently allocated to the P port, and 'b10 if it is currently
       
   906                  * allocated to Astoria.
       
   907                  */
       
   908                 for (pos = 0; pos < 8; pos+= 2)
       
   909                 {
       
   910                     if (((gAstoriaRegCache[i][1] >> pos) & 0x03) == 0x03)
       
   911                         gAstoriaRegCache[i][1] = (gAstoriaRegCache[i][1] & (0xFF ^ (0x03 << pos))) | (0x01 << pos);
       
   912                     else
       
   913                         gAstoriaRegCache[i][1] = (gAstoriaRegCache[i][1] & (0xFF ^ (0x03 << pos))) | (0x02 << pos);
       
   914                 }
       
   915             }
       
   916         }
       
   917     }
       
   918 }
       
   919 
       
   920 void
       
   921 CyAsHalRestoreRegsAfterStandby (
       
   922         CyAsHalDeviceTag tag)
       
   923 {
       
   924     CyAsOmapDevKernel *dev_p = (CyAsOmapDevKernel *)tag;
       
   925     int i;
       
   926 
       
   927     if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG)
       
   928     {
       
   929         Kern::Printf("%s: bad TAG parameter passed to function\n", __FUNCTION__);
       
   930         return;
       
   931     }
       
   932 
       
   933     {
       
   934         /* Write 0xFF into the mask register so that all fields can be updated.
       
   935            The mask will get updated to its proper value later.
       
   936          */
       
   937         CyAsHalWriteRegister (tag, CY_AS_MEM_P0_RSE_MASK, 0xFF);
       
   938         for (i = 0; i < CYASHAL_REGISTERS_TO_SAVE_COUNT; i++)
       
   939         {
       
   940             CyAsHalWriteRegister (tag, gAstoriaRegCache[i][0], gAstoriaRegCache[i][1]);
       
   941         }
       
   942     }
       
   943 }
       
   944 
       
   945 void
       
   946 CyAsHalInitDevRegisters(
       
   947 	CyAsHalDeviceTag tag,
       
   948 	CyBool           is_standby_wakeup)
       
   949 {
       
   950 	(void)tag;
       
   951 	(void)is_standby_wakeup;
       
   952 	Kern::Printf("CyAsHalInitDevRegisters...");
       
   953 	return ;
       
   954 }
       
   955 
       
   956 
       
   957 void
       
   958 CyAsHalPrintMessage2(const char* msg)
       
   959 {
       
   960 	Kern::Printf("%s",msg);
       
   961 }
       
   962 
       
   963 /*************************************************************************************************
       
   964 *
       
   965 * Below are the functions that must be defined to provide the basic operating system services
       
   966 * required by the API.
       
   967 *
       
   968 *************************************************************************************************/
       
   969 
       
   970 /*
       
   971  * This function is required by the API to allocate memory.  This function is expected to work
       
   972  * exactly like malloc().
       
   973  */
       
   974 void *
       
   975 CyAsHalAlloc(uint32_t cnt)
       
   976 {
       
   977     void *ret_p ;
       
   978     /*ret_p = kmalloc(cnt, GFP_KERNEL) ;*/
       
   979     ret_p = (void*) new TUint8[cnt];
       
   980     return ret_p ;
       
   981 }
       
   982 
       
   983 /*
       
   984  * This function is required by the API to free memory allocated with CyAsHalAlloc().  This function is
       
   985  * expected to work exacly like free().
       
   986  */
       
   987 void
       
   988 CyAsHalFree(void *mem_p)
       
   989 {
       
   990     delete [] (mem_p) ;
       
   991 }
       
   992 
       
   993 /*
       
   994  * Allocator that can be used in interrupt context. We have to ensure that the kmalloc
       
   995  * call does not sleep in this case.
       
   996  */
       
   997 void *
       
   998 CyAsHalCBAlloc(uint32_t cnt)
       
   999 {
       
  1000     void *ret_p ;
       
  1001 
       
  1002 	/* TODO:
       
  1003     ret_p = kmalloc(cnt, GFP_ATOMIC) ;*/
       
  1004 	ret_p = (void*) new TUint8[cnt];
       
  1005     return ret_p ;
       
  1006 }
       
  1007 
       
  1008 /*
       
  1009  * This function is required to set a block of memory to a specific value.  This function is
       
  1010  * expected to work exactly like memset()
       
  1011  */
       
  1012 void
       
  1013 CyAsHalMemSet(void *ptr, uint8_t value, uint32_t cnt)
       
  1014 {
       
  1015 	/*uint32_t i ;
       
  1016 	uint8_t* b = (uint8_t*) ptr ;
       
  1017 	for ( i = 0 ; i < cnt ; i++ )
       
  1018 		*b = value ;
       
  1019 	 TODO: */
       
  1020     memset(ptr, value, cnt) ;
       
  1021 }
       
  1022 
       
  1023 
       
  1024 /*
       
  1025  * This function is expected to create a sleep channel.  The data structure that represents the
       
  1026  * sleep channel is given by the pointer in the argument.
       
  1027  */
       
  1028 CyBool
       
  1029 CyAsHalCreateSleepChannel(CyAsHalSleepChannel *channel)
       
  1030 {
       
  1031     /* TODO:
       
  1032     init_waitqueue_head(&channel->wq) ;
       
  1033     return CyTrue ;*/
       
  1034     if (channel)
       
  1035     	channel->wq = 0 ;
       
  1036     return CyTrue ;
       
  1037 }
       
  1038 
       
  1039 /*
       
  1040  * This function is expected to destroy a sleep channel.  The data structure that represents the
       
  1041  * sleep channel is given by the pointer in the argument.
       
  1042  */
       
  1043 CyBool
       
  1044 CyAsHalDestroySleepChannel(CyAsHalSleepChannel *channel)
       
  1045 {
       
  1046 	/* TODO:
       
  1047 	return CyTrue ;*/
       
  1048 	channel->wq =1 ;
       
  1049     return CyTrue ;
       
  1050 }
       
  1051 
       
  1052 CyBool
       
  1053 CyAsHalSleepOn(CyAsHalSleepChannel *channel, uint32_t ms)
       
  1054 {
       
  1055     /* TODO:
       
  1056     interruptible_sleep_on_timeout (&channel->wq, (ms * HZ/1000)) ;
       
  1057     return CyTrue ;*/
       
  1058 
       
  1059     NKern::Sleep(ms);
       
  1060     return CyTrue;
       
  1061 }
       
  1062 
       
  1063 CyBool
       
  1064 CyAsHalWake(CyAsHalSleepChannel *channel)
       
  1065 {
       
  1066 
       
  1067     /* TODO:
       
  1068     wake_up (&channel->wq) ;
       
  1069     return CyTrue ;*/
       
  1070     channel->wq = 1 ;
       
  1071     return CyTrue ;
       
  1072 
       
  1073 }
       
  1074 
       
  1075 uint32_t
       
  1076 CyAsHalDisableInterrupts()
       
  1077 {
       
  1078     uint16_t v = CyAsHalReadRegister(gDevTag,CY_AS_MEM_P0_INT_MASK_REG);
       
  1079     if ( !Intr_Disabled )
       
  1080     {
       
  1081         CyAsHalWriteRegister(gDevTag,CY_AS_MEM_P0_INT_MASK_REG,0);
       
  1082     }
       
  1083     Intr_Disabled++ ;
       
  1084 	return (uint32_t)v ;
       
  1085 }
       
  1086 
       
  1087 void
       
  1088 CyAsHalEnableInterrupts(uint32_t val)
       
  1089 {
       
  1090     Intr_Disabled-- ;
       
  1091     if ( !Intr_Disabled )
       
  1092     {
       
  1093         val = CYAS_INT_MASK | CYAS_DRQ_MASK ;
       
  1094         CyAsHalWriteRegister(gDevTag,CY_AS_MEM_P0_INT_MASK_REG,(uint16_t)val);
       
  1095         /*CyAsHalWriteRegister(gDevTag,CY_AS_MEM_P0_INT_MASK_REG,0x1800);*/
       
  1096     }
       
  1097 }
       
  1098 
       
  1099 void
       
  1100 CyAsHalSleep150 (void) /* Sleep atleast 150ns */
       
  1101 {
       
  1102     uint32_t i, j;
       
  1103 
       
  1104     j = 0;
       
  1105     for (i = 0; i < 100; i++)
       
  1106 	j += (~i);
       
  1107 }
       
  1108 
       
  1109 int j = 0;
       
  1110 void
       
  1111 CyAsHalSleep(uint32_t ms)
       
  1112 {
       
  1113     int i;
       
  1114 
       
  1115     while (ms--)
       
  1116     {
       
  1117 	i = 60000;
       
  1118 	while (i--)
       
  1119 	{
       
  1120 	    j += ((i * ~i) + 3 * i + 79);
       
  1121 	}
       
  1122     }
       
  1123 }
       
  1124 
       
  1125 /*****************************************************************************/
       
  1126 /*****************************************************************************/
       
  1127 /*****************************************************************************/
       
  1128 int gInitComplete = 0 ;
       
  1129 
       
  1130 /*
       
  1131  * This callback function is called for events from the MISC module.  The primary event
       
  1132  * processed by this function is the CyAsEventMiscInitialized which is sent once the
       
  1133  * West Bridge device is initialized and ready to accept requests.
       
  1134  */
       
  1135 static void
       
  1136 CyMiscCallback(CyAsDeviceHandle h, CyAsMiscEventType evtype, void *evdata)
       
  1137 {
       
  1138     (void)h ;
       
  1139     (void)evdata ;
       
  1140 
       
  1141     switch(evtype)
       
  1142     {
       
  1143     case CyAsEventMiscInitialized:
       
  1144     	Kern::Printf("Firmware initialized");
       
  1145         gInitComplete = CyTrue ;
       
  1146         break ;
       
  1147     default:
       
  1148         break ;
       
  1149     }
       
  1150 }
       
  1151 
       
  1152 int
       
  1153 CyAsHalAstoriaInit(void)
       
  1154 {
       
  1155  	uint32_t ret = 0 ;
       
  1156  	char* pgm = "Beagleboard HAL";
       
  1157     CyAsDeviceHandle dev_handle ;
       
  1158     CyAsDeviceConfig config ;
       
  1159     CyAsHalDeviceTag tag ;
       
  1160 
       
  1161     if (!StartOMAPKernel(pgm, &tag, CyFalse))
       
  1162     {
       
  1163 #ifndef HW_TEST
       
  1164 		Kern::Printf("ERROR: Cannot start OMAPKernel\n") ;
       
  1165 #endif
       
  1166 		return 1 ;
       
  1167 	}
       
  1168 
       
  1169     /*
       
  1170      * Create a handle to a West Bridge device.  It tag is used to identifiy the specific hardware
       
  1171      * we are talking to.
       
  1172      */
       
  1173     Kern::Printf("** Create API device\n") ;
       
  1174     ret = CyAsMiscCreateDevice(&dev_handle, tag) ;
       
  1175     if (ret != CY_AS_ERROR_SUCCESS)
       
  1176     {
       
  1177         Kern::Printf("%s: cannot initailize the West Bridge API - code %d\n", pgm, ret) ;
       
  1178         return 1 ;
       
  1179     }
       
  1180     Kern::Printf("** API device created\n") ;
       
  1181 
       
  1182     /*
       
  1183      * Configure the physical bus so we can talk to the West Bridge device.  This is the first required
       
  1184      * API call after creating a device.
       
  1185      */
       
  1186     Kern::Printf("** API device configuring...\n");
       
  1187     memset(&config, 0, sizeof(config)) ;
       
  1188     ret = CyAsMiscConfigureDevice(dev_handle, &config) ;
       
  1189     if (ret != CY_AS_ERROR_SUCCESS)
       
  1190     {
       
  1191         Kern::Printf("%s: cannot configure the West Bridge device - code %d\n", pgm, ret) ;
       
  1192         return 1 ;
       
  1193     }
       
  1194     Kern::Printf("** API device configured\n") ;
       
  1195 
       
  1196     /*
       
  1197      * Register a callback to process events from the MISC module.
       
  1198      */
       
  1199     Kern::Printf("** Register Callback...\n") ;
       
  1200     ret = CyAsMiscRegisterCallback(dev_handle, CyMiscCallback) ;
       
  1201     if (ret != CY_AS_ERROR_SUCCESS)
       
  1202     {
       
  1203         Kern::Printf("%s: cannot configure the West Bridge device - code %d\n", pgm, ret) ;
       
  1204         return 1 ;
       
  1205     }
       
  1206 	Kern::Printf("** Register Callback done\n") ;
       
  1207 	/*
       
  1208 	 * Download the firmware to the device.  Until the firmware has been downloaded, the West Bridge
       
  1209 	 * device cannot response to requests from the P port processor.
       
  1210 	 */
       
  1211 	Kern::Printf("** Download firmware...\n") ;
       
  1212 #ifdef FIRMWARE_NOPPORT
       
  1213 
       
  1214 #ifdef OVERCLOCK_SD
       
  1215 	ret = CyAsMiscDownloadFirmware(dev_handle, CyAnFirmware.fw_image,
       
  1216 			(uint16_t)CYANFW_SIZE, 0, 0) ;
       
  1217 #else
       
  1218 	ret = CyAsMiscDownloadFirmware(dev_handle, cyastfw_sd_mmc_rel_nopport_array.fw_image,
       
  1219 			(uint16_t)CYASTFW_SD_MMC_REL_NOPPORT_SIZE, 0, 0) ;
       
  1220 #endif
       
  1221 
       
  1222 #else
       
  1223 
       
  1224 #ifdef OVERCLOCK_SD
       
  1225 	ret = CyAsMiscDownloadFirmware(dev_handle, CyAnFirmware.fw_image,
       
  1226 			(uint16_t)CYANFW_SIZE, 0, 0) ;
       
  1227 #else
       
  1228 	ret = CyAsMiscDownloadFirmware(dev_handle, cyastfw_sd_mmc_rel_silicon_array.fw_image,
       
  1229 			(uint16_t)CYASTFW_SD_MMC_REL_SILICON_SIZE, 0, 0) ;
       
  1230 #endif
       
  1231 
       
  1232 #endif
       
  1233 	if (ret != CY_AS_ERROR_SUCCESS)
       
  1234 	{
       
  1235 		Kern::Printf("%s: cannot download the antioch firmware - code %d\n", pgm, ret) ;
       
  1236 		return 1 ;
       
  1237 	}
       
  1238 	Kern::Printf("** API device loaded firmware\n") ;
       
  1239 
       
  1240     /*
       
  1241      * Note, if a firmware image is not provided, the firmware can still be loaded if the West Bridge device
       
  1242      * is in DEBUG mode.  In debug mode, the firmware can be loaded via USB.  In general however, the firmware
       
  1243      * should be loaded via the P Port and therefore a firmware file name should be provided.
       
  1244      */
       
  1245 
       
  1246     /*
       
  1247      * Wait for the initialization event telling me that the firmware
       
  1248      * has completed initialization and is ready to go.  The sleep of 100 ms
       
  1249      * is used to insure that we do not burn too many CPU cycles while waiting on
       
  1250      * the firmware initialization to finish.
       
  1251      */
       
  1252 #ifndef FIRMWARE_NOPPORT
       
  1253     while (!gInitComplete)
       
  1254     {
       
  1255 		NKern::Sleep(1000);
       
  1256 	}
       
  1257 
       
  1258 	Kern::Printf("Firmware donwloaded successfully!!") ;
       
  1259 #if 0
       
  1260 #ifdef STORAGE_TEST
       
  1261 	ret = CyAsSymbianStorageTest("Symbian WB Test",dev_handle, tag);
       
  1262 	if ( !ret )
       
  1263 	{
       
  1264 		Kern::Printf("%s: CyAsSymbianStorageTest failed - code %d\n", pgm, ret) ;
       
  1265 		return 1 ;
       
  1266 	}
       
  1267 	Kern::Printf("** CyAsSymbianStorageTest done\n") ;
       
  1268 #else
       
  1269 	ret = CyAsAPIUsbInit("Symbian WB Test",dev_handle, tag);
       
  1270 	if ( !ret )
       
  1271 	{
       
  1272 		Kern::Printf("%s: CyAsAPIUsbInit failed - code %d\n", pgm, ret) ;
       
  1273 		return 1 ;
       
  1274 	}
       
  1275 	Kern::Printf("** CyAsAPIUsbInit done\n") ;
       
  1276 #endif
       
  1277 #endif
       
  1278 
       
  1279 #endif
       
  1280 
       
  1281 	ret = CyAsAPIGetHandle(dev_handle, tag);
       
  1282 	Kern::Printf("** CyAsAPIGetHandle done\n") ;
       
  1283 
       
  1284 	return 0 ;
       
  1285 }
       
  1286 
       
  1287 
       
  1288 /*****************************************************************************/
       
  1289 /*****************************************************************************/
       
  1290 /*****************************************************************************/
       
  1291 
       
  1292 #else
       
  1293 /*
       
  1294 * Some compilers do not like empty C files, so if the OMAP hal is not being
       
  1295 * compiled, we compile this single function.  We do this so that for a given target
       
  1296 * HAL there are not multiple sources for the HAL functions.
       
  1297 */
       
  1298 void MyOMAPKernelHalDummyFunction(
       
  1299 	void)
       
  1300 {
       
  1301 }
       
  1302 
       
  1303 #endif
       
  1304 
       
  1305 
       
  1306