1/*
2 * HwInit.c
3 *
4 * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 *  * Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in
15 *    the documentation and/or other materials provided with the
16 *    distribution.
17 *  * Neither the name Texas Instruments nor the names of its
18 *    contributors may be used to endorse or promote products derived
19 *    from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35
36/*******************************************************************************/
37/*                                                                             */
38/*  MODULE:  HwInit.c                                                          */
39/*  PURPOSE: HwInit module manages the init process of the TNETW, included     */
40/*           firmware download process. It shall perform Hard Reset the chip   */
41/*           if possible (this will require a Reset line to be connected to    */
42/*           the host); Start InterfaceCtrl; Download NVS and FW               */
43/*                                                                             */
44/*                                                                             */
45/*******************************************************************************/
46
47#define __FILE_ID__  FILE_ID_105
48#include "tidef.h"
49#include "osApi.h"
50#include "report.h"
51#include "timer.h"
52#include "HwInit_api.h"
53#include "FwEvent_api.h"
54#include "TwIf.h"
55#include "TWDriver.h"
56#include "TWDriverInternal.h"
57#include "eventMbox_api.h"
58#include "CmdBld.h"
59#include "CmdMBox_api.h"
60#ifdef TI_RANDOM_DEFAULT_MAC
61#include <linux/random.h>
62#include <linux/jiffies.h>
63#endif
64
65
66extern void TWD_FinalizeOnFailure   (TI_HANDLE hTWD);
67extern void cmdBld_FinalizeDownload (TI_HANDLE hCmdBld, TBootAttr *pBootAttr, FwStaticData_t *pFwInfo);
68
69
70/************************************************************************
71 * Defines
72 ************************************************************************/
73
74/* Download phase partition */
75#define PARTITION_DOWN_MEM_ADDR       0
76#define PARTITION_DOWN_MEM_SIZE       0x177C0
77#define PARTITION_DOWN_REG_ADDR       REGISTERS_BASE
78#define PARTITION_DOWN_REG_SIZE       0x8800
79
80/* Working phase partition */
81#define PARTITION_WORK_MEM_ADDR1       0x40000
82#define PARTITION_WORK_MEM_SIZE1       0x14FC0
83#define PARTITION_WORK_MEM_ADDR2       REGISTERS_BASE
84#define PARTITION_WORK_MEM_SIZE2       0xA000
85#define PARTITION_WORK_MEM_ADDR3       0x3004F8
86#define PARTITION_WORK_MEM_SIZE3       0x4
87#define PARTITION_WORK_MEM_ADDR4       0x40404
88
89/* DRPW setting partition */
90#define PARTITION_DRPW_MEM_ADDR       0x40000
91#define PARTITION_DRPW_MEM_SIZE       0x14FC0
92#define PARTITION_DRPW_REG_ADDR       DRPW_BASE
93#define PARTITION_DRPW_REG_SIZE       0x6000
94
95/* Total range of bus addresses range */
96#define PARTITION_TOTAL_ADDR_RANGE    0x1FFC0
97
98/* Maximal block size in a single SDIO transfer --> Firmware image load chunk size */
99#ifdef _VLCT_
100#define MAX_SDIO_BLOCK					(4000)
101#else
102#define MAX_SDIO_BLOCK					(500)
103#endif
104
105#define ACX_EEPROMLESS_IND_REG        (SCR_PAD4)
106#define USE_EEPROM                    (0)
107#define SOFT_RESET_MAX_TIME           (1000000)
108#define SOFT_RESET_STALL_TIME         (1000)
109#define NVS_DATA_BUNDARY_ALIGNMENT    (4)
110
111#define MAX_HW_INIT_CONSECUTIVE_TXN     15
112
113#define WORD_SIZE                       4
114#define WORD_ALIGNMENT_MASK             0x3
115#define DEF_NVS_SIZE                    ((NVS_PRE_PARAMETERS_LENGTH) + (NVS_TX_TYPE_INDEX) + 4)
116
117#define RADIO_SM_WAIT_LOOP  32
118
119#define FREF_CLK_FREQ_MASK      0x7
120#define FREF_CLK_TYPE_MASK      BIT_3
121#define FREF_CLK_POLARITY_MASK  BIT_4
122
123#define FREF_CLK_TYPE_BITS      0xfffffe7f
124#define CLK_REQ_PRCM            0x100
125
126#define FREF_CLK_POLARITY_BITS  0xfffff8ff
127#define CLK_REQ_OUTN_SEL        0x700
128
129#define DRPw_MASK_CHECK  0xc0
130#define DRPw_MASK_SET    0x2000000
131
132/* time to wait till we check if fw is running */
133#define STALL_TIMEOUT   7
134
135#ifdef DOWNLOAD_TIMER_REQUIERD
136#define FIN_LOOP 10
137#endif
138
139
140#ifdef _VLCT_
141#define FIN_LOOP 10
142#else
143#define FIN_LOOP 20000
144#endif
145
146
147/************************************************************************
148 * Macros
149 ************************************************************************/
150
151#define SET_DEF_NVS(aNVS)     aNVS[0]=0x01; aNVS[1]=0x6d; aNVS[2]=0x54; aNVS[3]=0x56; aNVS[4]=0x34; \
152                              aNVS[5]=0x12; aNVS[6]=0x28; aNVS[7]=0x01; aNVS[8]=0x71; aNVS[9]=0x54; \
153                              aNVS[10]=0x00; aNVS[11]=0x08; aNVS[12]=0x00; aNVS[13]=0x00; aNVS[14]=0x00; \
154                              aNVS[15]=0x00; aNVS[16]=0x00; aNVS[17]=0x00; aNVS[18]=0x00; aNVS[19]=0x00; \
155                              aNVS[20]=0x00; aNVS[21]=0x00; aNVS[22]=0x00; aNVS[23]=0x00; aNVS[24]=eNVS_NON_FILE;\
156							  aNVS[25]=0x00; aNVS[26]=0x00; aNVS[27]=0x00;
157
158
159#define SET_PARTITION(pPartition,uAddr1,uMemSize1,uAddr2,uMemSize2,uAddr3,uMemSize3,uAddr4) \
160                    ((TPartition*)pPartition)[0].uMemAdrr = uAddr1; \
161                    ((TPartition*)pPartition)[0].uMemSize = uMemSize1; \
162                    ((TPartition*)pPartition)[1].uMemAdrr = uAddr2; \
163                    ((TPartition*)pPartition)[1].uMemSize = uMemSize2; \
164                    ((TPartition*)pPartition)[2].uMemAdrr = uAddr3; \
165                    ((TPartition*)pPartition)[2].uMemSize = uMemSize3; \
166                    ((TPartition*)pPartition)[3].uMemAdrr = uAddr4;
167
168#define HW_INIT_PTXN_SET(pHwInit, pTxn)  pTxn = (TTxnStruct*)&(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].tTxnStruct);
169
170#define BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, uAddr, uVal, uSize, direction, fCB, hCB)     \
171                              HW_INIT_PTXN_SET(pHwInit, pTxn) \
172                              TXN_PARAM_SET_DIRECTION(pTxn, direction); \
173                              pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData = (TI_UINT32)uVal; \
174                              BUILD_TTxnStruct(pTxn, uAddr, &(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData), uSize, fCB, hCB)
175
176#define BUILD_HW_INIT_FW_STATIC_TXN(pHwInit, pTxn, uAddr, fCB, hCB)     \
177                              HW_INIT_PTXN_SET(pHwInit, pTxn) \
178                              TXN_PARAM_SET_DIRECTION(pTxn, TXN_DIRECTION_READ); \
179                              BUILD_TTxnStruct(pTxn, uAddr, &(pHwInit->tFwStaticTxn.tFwStaticInfo), sizeof(FwStaticData_t), fCB, hCB)
180
181#define BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, uAddr, uVal, uSize, direction, fCB, hCB)     \
182                              HW_INIT_PTXN_SET(pHwInit, pTxn) \
183                              TXN_PARAM_SET_DIRECTION(pTxn, direction); \
184                              BUILD_TTxnStruct(pTxn, uAddr, uVal, uSize, fCB, hCB)
185
186
187#define SET_DRP_PARTITION(pPartition)\
188                        SET_PARTITION(pPartition, PARTITION_DRPW_MEM_ADDR, PARTITION_DRPW_MEM_SIZE, PARTITION_DRPW_REG_ADDR, PARTITION_DRPW_REG_SIZE, 0, 0, 0)
189
190#define SET_FW_LOAD_PARTITION(pPartition,uFwAddress)\
191                            SET_PARTITION(pPartition,uFwAddress,PARTITION_DOWN_MEM_SIZE, PARTITION_DOWN_REG_ADDR, PARTITION_DOWN_REG_SIZE,0,0,0)
192
193#define SET_WORK_PARTITION(pPartition)\
194                        SET_PARTITION(pPartition,PARTITION_WORK_MEM_ADDR1, PARTITION_WORK_MEM_SIZE1, PARTITION_WORK_MEM_ADDR2, PARTITION_WORK_MEM_SIZE2, PARTITION_WORK_MEM_ADDR3, PARTITION_WORK_MEM_SIZE3, PARTITION_WORK_MEM_ADDR4)
195
196/* Handle return status inside a state machine */
197#define EXCEPT(phwinit,status)                                   \
198    switch (status) {                                           \
199        case TI_OK:                                             \
200        case TXN_STATUS_OK:                                     \
201        case TXN_STATUS_COMPLETE:                               \
202             break;                                             \
203        case TXN_STATUS_PENDING:                                \
204             return TXN_STATUS_PENDING;                         \
205        default:                                                \
206             TWD_FinalizeOnFailure (phwinit->hTWD);             \
207             return TXN_STATUS_ERROR;                           \
208    }
209
210
211/* Handle return status inside an init sequence state machine  */
212#define EXCEPT_I(phwinit,status)                                \
213    switch (status) {                                           \
214        case TI_OK:                                             \
215        case TXN_STATUS_COMPLETE:                               \
216             break;                                             \
217        case TXN_STATUS_PENDING:                                \
218             phwinit->uInitSeqStatus = status;                  \
219             return TXN_STATUS_PENDING;                         \
220        default:                                                \
221             TWD_FinalizeOnFailure (phwinit->hTWD);             \
222             return TXN_STATUS_ERROR;                           \
223    }
224
225
226/* Handle return status inside a load image state machine */
227#define EXCEPT_L(phwinit,status)                                \
228    switch (status) {                                           \
229        case TXN_STATUS_OK:                                     \
230        case TXN_STATUS_COMPLETE:                               \
231             break;                                             \
232        case TXN_STATUS_PENDING:                                \
233             phwinit->DownloadStatus = status;                  \
234             return TXN_STATUS_PENDING;                         \
235        default:                                                \
236             phwinit->DownloadStatus = status;                  \
237             TWD_FinalizeOnFailure (phwinit->hTWD);             \
238             return TXN_STATUS_ERROR;                           \
239    }
240
241
242/************************************************************************
243 * Types
244 ************************************************************************/
245
246enum
247{
248    REF_FREQ_19_2                   = 0,
249    REF_FREQ_26_0                   = 1,
250    REF_FREQ_38_4                   = 2,
251    REF_FREQ_40_0                   = 3,
252    REF_FREQ_33_6                   = 4,
253    REF_FREQ_NUM                    = 5
254};
255
256enum
257{
258    LUT_PARAM_INTEGER_DIVIDER       = 0,
259    LUT_PARAM_FRACTIONAL_DIVIDER    = 1,
260    LUT_PARAM_ATTN_BB               = 2,
261    LUT_PARAM_ALPHA_BB              = 3,
262    LUT_PARAM_STOP_TIME_BB          = 4,
263    LUT_PARAM_BB_PLL_LOOP_FILTER    = 5,
264    LUT_PARAM_NUM                   = 6
265};
266
267typedef struct
268{
269    TTxnStruct              tTxnStruct;
270    TI_UINT32               uData;
271
272} THwInitTxn;
273
274typedef struct
275{
276    TTxnStruct              tTxnStruct;
277    FwStaticData_t          tFwStaticInfo;
278
279} TFwStaticTxn;
280
281
282/* The HW Init module object */
283typedef struct
284{
285    /* Handles */
286    TI_HANDLE               hOs;
287    TI_HANDLE               hReport;
288    TI_HANDLE               hTWD;
289    TI_HANDLE               hBusTxn;
290    TI_HANDLE               hTwIf;
291
292    TI_HANDLE 		    hFileInfo;	/* holds parameters of FW Image Portion - for DW Download */
293    TEndOfHwInitCb          fInitHwCb;
294
295    /* Firmware image ptr */
296    TI_UINT8               *pFwBuf;
297    /* Firmware image length */
298    TI_UINT32               uFwLength;
299    TI_UINT32               uFwAddress;
300    TI_UINT32               bFwBufLast;
301    TI_UINT32               uFwLastAddr;
302    /* EEPROM image ptr */
303    TI_UINT8               *pEEPROMBuf;
304    /* EEPROM image length */
305    TI_UINT32               uEEPROMLen;
306
307    TI_UINT8               *pEEPROMCurPtr;
308    TI_UINT32               uEEPROMCurLen;
309    TBootAttr               tBootAttr;
310    TI_HANDLE               hHwCtrl;
311    ETxnStatus              DownloadStatus;
312    /* Upper module callback for the init stage */
313    fnotify_t               fCb;
314    /* Upper module handle for the init stage */
315    TI_HANDLE               hCb;
316    /* Init stage */
317    TI_UINT32               uInitStage;
318    /* Reset statge */
319    TI_UINT32               uResetStage;
320    /* EEPROM burst stage */
321    TI_UINT32               uEEPROMStage;
322    /* Init state machine temporary data */
323    TI_UINT32               uInitData;
324    /* ELP command image */
325    TI_UINT32               uElpCmd;
326    /* Chip ID */
327    TI_UINT32               uChipId;
328    /* Boot state machine temporary data */
329    TI_UINT32               uBootData;
330    TI_UINT32               uSelfClearTime;
331    TI_UINT8                uEEPROMBurstLen;
332    TI_UINT8                uEEPROMBurstLoop;
333    TI_UINT32               uEEPROMRegAddr;
334    TI_STATUS               uEEPROMStatus;
335    TI_UINT32               uNVSStartAddr;
336    TI_UINT32               uNVSNumChar;
337    TI_UINT32               uNVSNumByte;
338    TI_STATUS               uNVSStatus;
339    TI_UINT32               uScrPad6;
340    TI_UINT32               uRefFreq;
341    TI_UINT32               uInitSeqStage;
342    TI_STATUS               uInitSeqStatus;
343    TI_UINT32               uLoadStage;
344    TI_UINT32               uBlockReadNum;
345    TI_UINT32               uBlockWriteNum;
346    TI_UINT32               uPartitionLimit;
347    TI_UINT32               uFinStage;
348    TI_UINT32               uFinData;
349    TI_UINT32               uFinLoop;
350     TI_UINT32               uRegStage;
351    TI_UINT32               uRegLoop;
352    TI_UINT32               uRegSeqStage;
353    TI_UINT32               uRegData;
354	TI_HANDLE               hStallTimer;
355
356    /* Top register Read/Write SM temporary data*/
357    TI_UINT32               uTopRegAddr;
358    TI_UINT32               uTopRegValue;
359    TI_UINT32               uTopRegMask;
360    TI_UINT32               uTopRegUpdateValue;
361    TI_UINT32               uTopStage;
362    TI_STATUS               uTopStatus;
363
364    TI_UINT8                auFwTmpBuf [WSPI_PAD_LEN_WRITE + MAX_SDIO_BLOCK];
365
366    TFinalizeCb             fFinalizeDownload;
367    TI_HANDLE               hFinalizeDownload;
368    /* Size of the Fw image, retrieved from the image itself */
369    TI_UINT32               uFwDataLen;
370    TI_UINT8                aDefaultNVS[DEF_NVS_SIZE];
371    TI_UINT8                uTxnIndex;
372    THwInitTxn              aHwInitTxn[MAX_HW_INIT_CONSECUTIVE_TXN];
373    TFwStaticTxn            tFwStaticTxn;
374
375    TI_UINT32               uSavedDataForWspiHdr;  /* For saving the 4 bytes before the NVS data for WSPI case
376                                                        where they are overrun by the WSPI BusDrv */
377    TPartition              aPartition[NUM_OF_PARTITION];
378} THwInit;
379
380
381/************************************************************************
382 * Local Functions Prototypes
383 ************************************************************************/
384static void      hwInit_SetPartition                (THwInit   *pHwInit,
385                                                     TPartition *pPartition);
386static TI_STATUS hwInit_BootSm                      (TI_HANDLE hHwInit);
387static TI_STATUS hwInit_ResetSm                     (TI_HANDLE hHwInit);
388static TI_STATUS hwInit_EepromlessStartBurstSm      (TI_HANDLE hHwInit);
389static TI_STATUS hwInit_LoadFwImageSm               (TI_HANDLE hHwInit);
390static TI_STATUS hwInit_FinalizeDownloadSm          (TI_HANDLE hHwInit);
391static TI_STATUS hwInit_TopRegisterRead(TI_HANDLE hHwInit);
392static TI_STATUS hwInit_InitTopRegisterRead(TI_HANDLE hHwInit, TI_UINT32 uAddress);
393static TI_STATUS hwInit_TopRegisterWrite(TI_HANDLE hHwInit);
394static TI_STATUS hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit, TI_UINT32 uAddress, TI_UINT32 uValue);
395#ifdef DOWNLOAD_TIMER_REQUIERD
396static void      hwInit_StallTimerCb                (TI_HANDLE hHwInit, TI_BOOL bTwdInitOccured);
397#endif
398
399
400/*******************************************************************************
401*                       PUBLIC  FUNCTIONS  IMPLEMENTATION                      *
402********************************************************************************/
403
404
405/*************************************************************************
406*                        hwInit_Create                                   *
407**************************************************************************
408* DESCRIPTION:  This function initializes the HwInit module.
409*
410* INPUT:        hOs - handle to Os Abstraction Layer
411*
412* RETURN:       Handle to the allocated HwInit module
413*************************************************************************/
414TI_HANDLE hwInit_Create (TI_HANDLE hOs)
415{
416    THwInit *pHwInit;
417
418    /* Allocate HwInit module */
419    pHwInit = os_memoryAlloc (hOs, sizeof(THwInit));
420
421    if (pHwInit == NULL)
422    {
423        WLAN_OS_REPORT(("Error allocating the HwInit Module\n"));
424        return NULL;
425    }
426
427    /* Reset HwInit module */
428    os_memoryZero (hOs, pHwInit, sizeof(THwInit));
429
430    pHwInit->hOs = hOs;
431
432    return (TI_HANDLE)pHwInit;
433}
434
435
436/***************************************************************************
437*                           hwInit_Destroy                                 *
438****************************************************************************
439* DESCRIPTION:  This function unload the HwInit module.
440*
441* INPUTS:       hHwInit - the object
442*
443* OUTPUT:
444*
445* RETURNS:      TI_OK - Unload succesfull
446*               TI_NOK - Unload unsuccesfull
447***************************************************************************/
448TI_STATUS hwInit_Destroy (TI_HANDLE hHwInit)
449{
450    THwInit *pHwInit = (THwInit *)hHwInit;
451
452    if (pHwInit->hStallTimer)
453    {
454#ifdef DOWNLOAD_TIMER_REQUIERD
455		tmr_DestroyTimer (pHwInit->hStallTimer);
456#endif
457    }
458
459    /* Free HwInit Module */
460    os_memoryFree (pHwInit->hOs, pHwInit, sizeof(THwInit));
461
462    return TI_OK;
463}
464
465
466/***************************************************************************
467*                           hwInit_Init                                    *
468****************************************************************************
469* DESCRIPTION:  This function configures the hwInit module
470*
471* RETURNS:      TI_OK - Configuration successful
472*               TI_NOK - Configuration unsuccessful
473***************************************************************************/
474TI_STATUS hwInit_Init (TI_HANDLE      hHwInit,
475                       TI_HANDLE      hReport,
476                       TI_HANDLE      hTimer,
477                       TI_HANDLE      hTWD,
478                       TI_HANDLE 	  hFinalizeDownload,
479                       TFinalizeCb    fFinalizeDownload,
480                       TEndOfHwInitCb fInitHwCb)
481{
482    THwInit   *pHwInit = (THwInit *)hHwInit;
483    TTxnStruct* pTxn;
484#ifdef TI_RANDOM_DEFAULT_MAC
485    u32 rand_mac;
486#endif
487
488    /* Configure modules handles */
489    pHwInit->hReport    = hReport;
490    pHwInit->hTWD       = hTWD;
491    pHwInit->hTwIf      = ((TTwd *)hTWD)->hTwIf;
492    pHwInit->hOs        = ((TTwd *)hTWD)->hOs;
493    pHwInit->fInitHwCb  = fInitHwCb;
494    pHwInit->fFinalizeDownload 	= fFinalizeDownload;
495    pHwInit->hFinalizeDownload 	= hFinalizeDownload;
496
497    SET_DEF_NVS(pHwInit->aDefaultNVS)
498#ifdef TI_RANDOM_DEFAULT_MAC
499    /* Create random MAC address: offset 3, 4 and 5 */
500    srandom32((u32)jiffies);
501    rand_mac = random32();
502    pHwInit->aDefaultNVS[3] = (u8)rand_mac;
503    pHwInit->aDefaultNVS[4] = (u8)(rand_mac >> 8);
504    pHwInit->aDefaultNVS[5] = (u8)(rand_mac >> 16);
505#endif
506
507    for (pHwInit->uTxnIndex=0;pHwInit->uTxnIndex<MAX_HW_INIT_CONSECUTIVE_TXN;pHwInit->uTxnIndex++)
508    {
509        HW_INIT_PTXN_SET(pHwInit, pTxn)
510        /* Setting write as default transaction */
511        TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
512    }
513
514#ifdef DOWNLOAD_TIMER_REQUIERD
515	pHwInit->hStallTimer = tmr_CreateTimer (hTimer);
516	if (pHwInit->hStallTimer == NULL)
517	{
518		return TI_NOK;
519	}
520#endif
521
522    TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT, ".....HwInit configured successfully\n");
523
524    return TI_OK;
525}
526
527
528TI_STATUS hwInit_SetNvsImage (TI_HANDLE hHwInit, TI_UINT8 *pbuf, TI_UINT32 length)
529{
530    THwInit   *pHwInit = (THwInit *)hHwInit;
531
532    pHwInit->pEEPROMBuf = pbuf;
533    pHwInit->uEEPROMLen = length;
534
535    return TI_OK;
536}
537
538
539TI_STATUS hwInit_SetFwImage (TI_HANDLE hHwInit, TFileInfo *pFileInfo)
540{
541    THwInit   *pHwInit = (THwInit *)hHwInit;
542
543    if ((hHwInit == NULL) || (pFileInfo == NULL))
544    {
545	return TI_NOK;
546    }
547
548    pHwInit->pFwBuf 	= pFileInfo->pBuffer;
549    pHwInit->uFwLength  = pFileInfo->uLength;
550    pHwInit->uFwAddress = pFileInfo->uAddress;
551    pHwInit->bFwBufLast = pFileInfo->bLast;
552
553    return TI_OK;
554}
555
556
557/**
558 * \fn     hwInit_SetPartition
559 * \brief  Set HW addresses partition
560 *
561 * Set the HW address ranges for download or working memory and registers access.
562 * Generate and configure the bus access address mapping table.
563 * The partition is split between register (fixed partition of 24KB size, exists in all modes),
564 *     and memory (dynamically changed during init and gets constant value in run-time, 104KB size).
565 * The TwIf configures the memory mapping table on the device by issuing write transaction to
566 *     table address (note that the TxnQ and bus driver see this as a regular transaction).
567 *
568 * \note In future versions, a specific bus may not support partitioning (as in wUART),
569 *       In this case the HwInit module shall not call this function (will learn the bus
570 *       configuration from the INI file).
571 *
572 * \param  pHwInit   - The module's object
573 * \param  pPartition  - all partition base address
574 * \return void
575 * \sa
576 */
577static void hwInit_SetPartition (THwInit   *pHwInit,
578                                 TPartition *pPartition)
579{
580   TRACE7(pHwInit->hReport, REPORT_SEVERITY_INFORMATION, "hwInit_SetPartition: uMemAddr1=0x%x, MemSize1=0x%x uMemAddr2=0x%x, MemSize2=0x%x, uMemAddr3=0x%x, MemSize3=0x%x, uMemAddr4=0x%x, MemSize4=0x%x\n",pPartition[0].uMemAdrr, pPartition[0].uMemSize,pPartition[1].uMemAdrr, pPartition[1].uMemSize,pPartition[2].uMemAdrr, pPartition[2].uMemSize,pPartition[3].uMemAdrr );
581
582    /* Prepare partition Txn data and send to HW */
583    twIf_SetPartition (pHwInit->hTwIf,pPartition);
584}
585
586
587/****************************************************************************
588 *                      hwInit_Boot()
589 ****************************************************************************
590 * DESCRIPTION: Start HW init sequence which writes and reads some HW registers
591 *                  that are needed prior to FW download.
592 *
593 * INPUTS:  None
594 *
595 * OUTPUT:  None
596 *
597 * RETURNS: TI_OK or TI_NOK
598 ****************************************************************************/
599TI_STATUS hwInit_Boot (TI_HANDLE hHwInit)
600{
601    THwInit      *pHwInit = (THwInit *)hHwInit;
602    TTwd         *pTWD = (TTwd *)pHwInit->hTWD;
603    TWlanParams  *pWlanParams = &DB_WLAN(pTWD->hCmdBld);
604    TBootAttr     tBootAttr;
605
606    tBootAttr.MacClock = pWlanParams->MacClock;
607    tBootAttr.ArmClock = pWlanParams->ArmClock;
608
609    /*
610     * Initialize the status of download to  pending
611     * It will be set to TXN_STATUS_COMPLETE at the FinalizeDownload function
612     */
613    pHwInit->DownloadStatus = TXN_STATUS_PENDING;
614
615    /* Call the boot sequence state machine */
616    pHwInit->uInitStage = 0;
617
618    os_memoryCopy (pHwInit->hOs, &pHwInit->tBootAttr, &tBootAttr, sizeof(TBootAttr));
619
620    hwInit_BootSm (hHwInit);
621
622    /*
623     * If it returns the status of the StartInstance only then we can here query for the download status
624     * and then return the status up to the TNETW_Driver.
625     * This return value will go back up to the TNETW Driver layer so that the init from OS will know
626     * if to wait for the InitComplte or not in case of TXN_STATUS_ERROR.
627     * This value will always be pending since the SPI is ASYNC
628     * and in SDIOa timer is set so it will be ASync also in anyway.
629     */
630    return pHwInit->DownloadStatus;
631}
632
633
634 /****************************************************************************
635 * DESCRIPTION: Firmware boot state machine
636 *
637 * INPUTS:
638 *
639 * OUTPUT:  None
640 *
641 * RETURNS: TI_OK
642 ****************************************************************************/
643static TI_STATUS hwInit_BootSm (TI_HANDLE hHwInit)
644{
645    THwInit    *pHwInit = (THwInit *)hHwInit;
646    TI_STATUS   status = 0;
647    TTxnStruct  *pTxn;
648    TI_UINT32   uData;
649    TTwd        *pTWD        = (TTwd *) pHwInit->hTWD;
650    IniFileGeneralParam  *pGenParams = &DB_GEN(pTWD->hCmdBld);
651    TI_UINT32   clkVal = 0x3;
652
653    switch (pHwInit->uInitStage)
654    {
655    case 0:
656        pHwInit->uInitStage++;
657        pHwInit->uTxnIndex = 0;
658
659        /* Set the bus addresses partition to its "running" mode */
660        SET_WORK_PARTITION(pHwInit->aPartition)
661        hwInit_SetPartition (pHwInit,pHwInit->aPartition);
662
663#ifdef _VLCT_
664         /* Set FW to test mode */
665         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, SCR_PAD8, 0xBABABABE,
666                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
667         twIf_Transact(pHwInit->hTwIf, pTxn);
668         pHwInit->uTxnIndex++;
669#endif
670
671        if (( 0 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)) || (2 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK))
672             || (4 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)))
673        {/* ref clk: 19.2/38.4/38.4-XTAL */
674            clkVal = 0x3;
675        }
676        if ((1 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)) || (3 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)))
677        {/* ref clk: 26/52 */
678            clkVal = 0x5;
679        }
680
681        WLAN_OS_REPORT(("CHIP VERSION... set 1273 chip top registers\n"));
682
683        /* set the reference clock freq' to be used (pll_selinpfref field) */
684        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, PLL_PARAMETERS, clkVal,
685                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
686        twIf_Transact(pHwInit->hTwIf, pTxn);
687
688        pHwInit->uTxnIndex++;
689
690        /* read the PAUSE value to highest threshold */
691        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, PLL_PARAMETERS, 0,
692                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_BootSm, hHwInit)
693        status = twIf_Transact(pHwInit->hTwIf, pTxn);
694
695        EXCEPT (pHwInit, status)
696
697    case 1:
698        pHwInit->uInitStage ++;
699        /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
700        uData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
701        uData &= ~(0x3ff);
702
703        /* Now we can zero the index */
704        pHwInit->uTxnIndex = 0;
705
706        /* set the the PAUSE value to highest threshold */
707        uData |= WU_COUNTER_PAUSE_VAL;
708        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, WU_COUNTER_PAUSE, uData,
709                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
710        twIf_Transact(pHwInit->hTwIf, pTxn);
711
712        pHwInit->uTxnIndex++;
713
714        /* Continue the ELP wake up sequence */
715        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL,
716                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
717        twIf_Transact(pHwInit->hTwIf, pTxn);
718
719        /* Wait 500uS */
720        os_StalluSec (pHwInit->hOs, 500);
721
722        /* Set the bus addresses partition to DRPw registers region */
723        SET_DRP_PARTITION(pHwInit->aPartition)
724        hwInit_SetPartition (pHwInit,pHwInit->aPartition);
725
726        pHwInit->uTxnIndex++;
727
728        /* Read-modify-write DRPW_SCRATCH_START register (see next state) to be used by DRPw FW.
729           The RTRIM value will be added  by the FW before taking DRPw out of reset */
730        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, DRPW_SCRATCH_START, 0,
731                               REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
732        status = twIf_Transact(pHwInit->hTwIf, pTxn);
733
734        EXCEPT (pHwInit, status)
735
736    case 2:
737        pHwInit->uInitStage ++;
738
739        /* multiply fref value by 2, so that {0,1,2,3} values will become {0,2,4,6} */
740        /* Then, move it 4 places to the right, to alter Fref relevant bits in register 0x2c */
741        clkVal = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
742        pHwInit->uTxnIndex = 0; /* Reset index only after getting the last read value! */
743        clkVal |= ((pGenParams->RefClk & 0x3)<< 1) << 4;
744        if ((pGenParams->GeneralSettings & DRPw_MASK_CHECK) > 0)
745        {
746            clkVal |= DRPw_MASK_SET;
747        }
748        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, DRPW_SCRATCH_START, clkVal,
749                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
750        twIf_Transact(pHwInit->hTwIf, pTxn);
751
752        pHwInit->uTxnIndex++;
753
754
755        /* Set the bus addresses partition back to its "running" mode */
756        SET_WORK_PARTITION(pHwInit->aPartition)
757        hwInit_SetPartition (pHwInit,pHwInit->aPartition);
758
759        /*
760         * end of CHIP init seq.
761         */
762
763        /* Disable interrupts */
764        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_MASK, ACX_INTR_ALL,
765                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
766        twIf_Transact(pHwInit->hTwIf, pTxn);
767
768        pHwInit->uTxnIndex++;
769
770        /* Read the CHIP ID to get an indication that the bus is TI_OK */
771        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, CHIP_ID, 0,
772                               REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
773        status = twIf_Transact(pHwInit->hTwIf, pTxn);
774
775        EXCEPT (pHwInit, status)
776
777    case 3:
778        pHwInit->uInitStage ++;
779
780        /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
781         pHwInit->uChipId = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
782
783        /* This is only sanity check that the HW exists, we can continue and fail on FwLoad */
784		if (pHwInit->uChipId == CHIP_ID_1273_PG10)
785        {
786            WLAN_OS_REPORT(("Error!!  1273 PG 1.0 is not supported anymore!!.\n"));
787        }
788		else if (pHwInit->uChipId == CHIP_ID_1273_PG20)
789        {
790            WLAN_OS_REPORT(("Working on a 1273 PG 2.0 board.\n"));
791        }
792        else
793        {
794            WLAN_OS_REPORT (("Error!! Found unknown Chip Id = 0x%x\n", pHwInit->uChipId));
795
796            /*
797             * NOTE: no exception because of forward compatibility
798             */
799        }
800
801        /*
802         * Soft reset
803         */
804        pHwInit->uResetStage = 0;
805        pHwInit->uSelfClearTime = 0;
806        pHwInit->uBootData = 0;
807        status = hwInit_ResetSm (pHwInit);
808
809        EXCEPT (pHwInit, status)
810
811    case 4:
812        pHwInit->uInitStage ++;
813
814        TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "TNET SOFT-RESET\n");
815
816        WLAN_OS_REPORT(("Starting to process NVS...\n"));
817
818        /*
819         * Start EEPROM/NVS burst
820         */
821
822        if (pHwInit->pEEPROMBuf)
823        {
824            /* NVS file exists (EEPROM-less support) */
825            pHwInit->uEEPROMCurLen = pHwInit->uEEPROMLen;
826
827            TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "EEPROM Image addr=0x%x, EEPROM Len=0x0x%x\n", pHwInit->pEEPROMBuf, pHwInit->uEEPROMLen);
828            WLAN_OS_REPORT (("NVS found, EEPROM Image addr=0x%x, EEPROM Len=0x0x%x\n",
829            pHwInit->pEEPROMBuf, pHwInit->uEEPROMLen));
830        }
831        else
832        {
833            WLAN_OS_REPORT (("No Nvs, Setting default MAC address\n"));
834            pHwInit->uEEPROMCurLen = DEF_NVS_SIZE;
835            pHwInit->pEEPROMBuf = (TI_UINT8*)(&pHwInit->aDefaultNVS[0]);
836            WLAN_OS_REPORT (("pHwInit->uEEPROMCurLen: %x\n", pHwInit->uEEPROMCurLen));
837            WLAN_OS_REPORT (("ERROR: If you are not calibating the device, you will soon get errors !!!\n"));
838
839        }
840
841        pHwInit->pEEPROMCurPtr = pHwInit->pEEPROMBuf;
842        pHwInit->uEEPROMStage = 0;
843        status = hwInit_EepromlessStartBurstSm (hHwInit);
844
845        EXCEPT (pHwInit, status)
846
847    case 5:
848        pHwInit->uInitStage ++;
849        pHwInit->uTxnIndex = 0;
850
851        if (pHwInit->pEEPROMBuf)
852        {
853            /* Signal FW that we are eeprom less */
854            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG,
855                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
856            twIf_Transact(pHwInit->hTwIf, pTxn);
857
858            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "DRIVER NVS BURST-READ\n");
859        }
860        else
861        {
862	    /* 1273 - EEPROM is not support by FPGA yet */
863            /*
864             * Start ACX EEPROM
865             */
866            /*pHwInit->uRegister = START_EEPROM_MGR;
867            TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
868            BUILD_TTxnStruct(pTxn, ACX_REG_EE_START, &pHwInit->uRegister, REGISTER_SIZE, 0, NULL, NULL)
869            twIf_Transact(pHwInit->hTwIf, pTxn);*/
870
871            /*
872             * The stall is needed so the EEPROM NVS burst read will complete
873             */
874            os_StalluSec (pHwInit->hOs, 40000);
875
876            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_EEPROMLESS_IND_REG, USE_EEPROM,
877                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
878            twIf_Transact(pHwInit->hTwIf, pTxn);
879
880            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "STARTING EEPROM NVS BURST-READ\n");
881        }
882
883        pHwInit->uTxnIndex++;
884
885        /* Read Chip ID */
886        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn,  CHIP_ID, 0,
887                               REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
888        status = twIf_Transact(pHwInit->hTwIf, pTxn);
889
890        EXCEPT (pHwInit, status)
891
892    case 6:
893        pHwInit->uInitStage ++;
894        /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
895        pHwInit->uBootData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
896        /* Now we can zero the index */
897        pHwInit->uTxnIndex = 0;
898
899        WLAN_OS_REPORT(("Chip ID is 0x%X.\n", pHwInit->uBootData));
900        /* if the WLAN_EN is ON but MainClock is problamtic the chip-id will be zero*/
901        if (pHwInit->uBootData == 0)
902        {
903         WLAN_OS_REPORT(("Cannot read ChipID stopping\n", pHwInit->uBootData));
904         TWD_FinalizeOnFailure (pHwInit->hTWD);
905         return TXN_STATUS_ERROR;
906        }
907
908
909
910        /* Read Scr2 to verify that the HW is ready */
911        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, SCR_PAD2, 0,
912                               REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
913        status = twIf_Transact(pHwInit->hTwIf, pTxn);
914        EXCEPT (pHwInit, status)
915
916    case 7:
917        pHwInit->uInitStage ++;
918        /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
919        pHwInit->uBootData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
920
921        if (pHwInit->uBootData == 0xffffffff)
922        {
923            TRACE0(pHwInit->hReport, REPORT_SEVERITY_FATAL_ERROR , "Error in SCR_PAD2 register\n");
924            EXCEPT (pHwInit, TXN_STATUS_ERROR)
925        }
926
927        /* Call the restart sequence */
928        pHwInit->uInitSeqStage = 0;
929        pHwInit->uInitSeqStatus = TXN_STATUS_COMPLETE;
930
931        EXCEPT (pHwInit, status)
932
933    case 8:
934        pHwInit->uInitStage++;
935        if ((pGenParams->RefClk & FREF_CLK_TYPE_MASK) != 0x0)
936        {
937            status = hwInit_InitTopRegisterRead(hHwInit, 0x448);
938            EXCEPT (pHwInit, status)
939        }
940
941    case 9:
942        pHwInit->uInitStage++;
943
944        if ((pGenParams->RefClk & FREF_CLK_TYPE_MASK) != 0x0)
945        {
946			pHwInit->uTopRegValue &= FREF_CLK_TYPE_BITS;
947            pHwInit->uTopRegValue |= CLK_REQ_PRCM;
948			status =  hwInit_InitTopRegisterWrite( hHwInit, 0x448, pHwInit->uTopRegValue);
949            EXCEPT (pHwInit, status)
950        }
951
952    case 10:
953        pHwInit->uInitStage++;
954		if ((pGenParams->RefClk & FREF_CLK_POLARITY_MASK) == 0x0)
955        {
956            status = hwInit_InitTopRegisterRead(hHwInit, 0xCB2);
957            EXCEPT (pHwInit, status)
958        }
959
960    case 11:
961        pHwInit->uInitStage++;
962        if ((pGenParams->RefClk & FREF_CLK_POLARITY_MASK) == 0x0)
963        {
964            pHwInit->uTopRegValue &= FREF_CLK_POLARITY_BITS;
965            pHwInit->uTopRegValue |= CLK_REQ_OUTN_SEL;
966            status =  hwInit_InitTopRegisterWrite( hHwInit, 0xCB2, pHwInit->uTopRegValue);
967            EXCEPT (pHwInit, status)
968        }
969
970    case 12:
971        pHwInit->uInitStage = 0;
972
973        /* Set the Download Status to COMPLETE */
974        pHwInit->DownloadStatus = TXN_STATUS_COMPLETE;
975
976        /* Call upper layer callback */
977        if (pHwInit->fInitHwCb)
978        {
979            (*pHwInit->fInitHwCb) (pHwInit->hTWD);
980        }
981
982        return TI_OK;
983    }
984
985    return TI_OK;
986}
987
988
989TI_STATUS hwInit_LoadFw (TI_HANDLE hHwInit)
990{
991    THwInit   *pHwInit = (THwInit *)hHwInit;
992    TI_STATUS  status;
993
994    /* check parameters */
995    if (hHwInit == NULL)
996    {
997        EXCEPT (pHwInit, TXN_STATUS_ERROR)
998    }
999
1000    if (pHwInit->pFwBuf)
1001    {
1002        TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "CPU halt -> download code\n");
1003
1004        /* Load firmware image */
1005        pHwInit->uLoadStage = 0;
1006        status = hwInit_LoadFwImageSm (pHwInit);
1007
1008        switch (status)
1009        {
1010        case TI_OK:
1011        case TXN_STATUS_OK:
1012        case TXN_STATUS_COMPLETE:
1013            WLAN_OS_REPORT (("Firmware successfully downloaded.\n"));
1014            break;
1015        case TXN_STATUS_PENDING:
1016            WLAN_OS_REPORT (("Starting to download firmware...\n"));
1017            break;
1018        default:
1019            TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Firmware download failed!\n");
1020            break;
1021        }
1022
1023        EXCEPT (pHwInit, status);
1024    }
1025    else
1026    {
1027        TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Firmware not downloaded...\n");
1028
1029        EXCEPT (pHwInit, TXN_STATUS_ERROR)
1030    }
1031
1032    WLAN_OS_REPORT (("FW download OK...\n"));
1033    return TI_OK;
1034}
1035
1036
1037/****************************************************************************
1038 *                      hwInit_FinalizeDownloadSm()
1039 ****************************************************************************
1040 * DESCRIPTION: Run the Hardware firmware
1041 *              Wait for Init Complete
1042 *              Configure the Bus Access with Addresses available on the scratch pad register
1043 *              Change the SDIO/SPI partitions to be able to see all the memory addresses
1044 *
1045 * INPUTS:  None
1046 *
1047 * OUTPUT:  None
1048 *
1049 * RETURNS: None
1050 ****************************************************************************/
1051static TI_STATUS hwInit_FinalizeDownloadSm (TI_HANDLE hHwInit)
1052{
1053    THwInit  *pHwInit = (THwInit *)hHwInit;
1054    TTwd     *pTWD = (TTwd *)pHwInit->hTWD;
1055    TI_STATUS status = TI_OK;
1056    TTxnStruct* pTxn;
1057
1058
1059    while (TI_TRUE)
1060    {
1061        switch (pHwInit->uFinStage)
1062        {
1063        case 0:
1064            pHwInit->uFinStage = 1;
1065            pHwInit->uTxnIndex = 0;
1066            /*
1067             * Run the firmware (I) - Read current value from ECPU Control Reg.
1068             */
1069            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_ECPU_CONTROL, 0,
1070                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
1071            status = twIf_Transact(pHwInit->hTwIf, pTxn);
1072
1073            EXCEPT (pHwInit, status)
1074
1075        case 1:
1076            pHwInit->uFinStage ++;
1077            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
1078            pHwInit->uFinData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
1079            /* Now we can zero the index */
1080            pHwInit->uTxnIndex = 0;
1081
1082            /*
1083             * Run the firmware (II) - Take HW out of reset (write ECPU_CONTROL_HALT to ECPU Control Reg.)
1084             */
1085            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_ECPU_CONTROL, (pHwInit->uFinData | ECPU_CONTROL_HALT),
1086                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1087            twIf_Transact(pHwInit->hTwIf, pTxn);
1088
1089            WLAN_OS_REPORT (("Firmware running.\n"));
1090
1091            /*
1092             * CHIP ID Debug
1093             */
1094
1095            pHwInit->uTxnIndex++;
1096
1097            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, CHIP_ID, 0,
1098                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
1099            status = twIf_Transact(pHwInit->hTwIf, pTxn);
1100
1101            EXCEPT (pHwInit, status)
1102
1103        case 2:
1104            pHwInit->uFinStage ++;
1105            pHwInit->uFinLoop = 0;
1106
1107            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
1108            pHwInit->uFinData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
1109
1110            TRACE1(pHwInit->hReport, REPORT_SEVERITY_INIT , "CHIP ID IS %x\n", pHwInit->uFinData);
1111
1112            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Wait init complete\n");
1113
1114        case 3:
1115            pHwInit->uTxnIndex = 0;
1116
1117            /*
1118             * Wait for init complete
1119             */
1120            if (pHwInit->uFinLoop < FIN_LOOP)
1121            {
1122                pHwInit->uFinStage = 4;
1123
1124#ifndef DOWNLOAD_TIMER_REQUIERD
1125				os_StalluSec (pHwInit->hOs, 50);
1126#endif
1127
1128                /* Read interrupt status register */
1129                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_NO_CLEAR, 0,
1130                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
1131                status = twIf_Transact(pHwInit->hTwIf, pTxn);
1132
1133                EXCEPT (pHwInit, status)
1134            }
1135            else
1136			{
1137				pHwInit->uFinStage = 5;
1138			}
1139            continue;
1140
1141        case 4:
1142            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
1143            pHwInit->uFinData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
1144            /* Now we can zero the index */
1145            pHwInit->uTxnIndex = 0;
1146
1147            if (pHwInit->uFinData == 0xffffffff) /* error */
1148            {
1149                TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Error reading hardware complete init indication\n");
1150
1151                pHwInit->DownloadStatus = TXN_STATUS_ERROR;
1152                EXCEPT (pHwInit, TXN_STATUS_ERROR)
1153            }
1154
1155            if (IS_MASK_ON (pHwInit->uFinData, ACX_INTR_INIT_COMPLETE))
1156            {
1157                pHwInit->uFinStage = 5;
1158
1159                /* Interrupt ACK */
1160                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_ACK, ACX_INTR_INIT_COMPLETE,
1161                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1162                twIf_Transact(pHwInit->hTwIf, pTxn);
1163
1164                break;
1165            }
1166            else
1167            {
1168                pHwInit->uFinStage = 3;
1169                pHwInit->uFinLoop ++;
1170
1171#ifdef DOWNLOAD_TIMER_REQUIERD
1172                tmr_StartTimer (pHwInit->hStallTimer, hwInit_StallTimerCb, hHwInit, STALL_TIMEOUT, TI_FALSE);
1173                return TXN_STATUS_PENDING;
1174#endif
1175            }
1176#ifndef DOWNLOAD_TIMER_REQUIERD
1177            continue;
1178#endif
1179
1180        case 5:
1181            pHwInit->uFinStage++;
1182
1183            if (pHwInit->uFinLoop >= FIN_LOOP)
1184            {
1185                TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for the hardware to complete initialization\n");
1186
1187                pHwInit->DownloadStatus = TXN_STATUS_ERROR;
1188                EXCEPT (pHwInit, TXN_STATUS_ERROR);
1189            }
1190
1191            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Firmware init complete...\n");
1192
1193            /*
1194             * There are valid addresses of the command and event mailbox
1195             * on the scratch pad registers
1196             */
1197            /* Hardware config command mail box */
1198            status = cmdMbox_ConfigHw (pTWD->hCmdMbox,
1199                                       (fnotify_t)hwInit_FinalizeDownloadSm,
1200                                       hHwInit);
1201            EXCEPT (pHwInit, status)
1202
1203        case 6:
1204            pHwInit->uFinStage++;
1205
1206            /* Hardware config event mail box */
1207            status = eventMbox_InitMboxAddr (pTWD->hEventMbox,
1208                                         (fnotify_t)hwInit_FinalizeDownloadSm,
1209                                         hHwInit);
1210            EXCEPT (pHwInit, status);
1211
1212        case 7:
1213            pHwInit->uFinStage++;
1214            pHwInit->uTxnIndex = 0;
1215
1216            SET_WORK_PARTITION(pHwInit->aPartition)
1217            /* Set the bus addresses partition to its "running" mode */
1218            SET_WORK_PARTITION(pHwInit->aPartition)
1219            hwInit_SetPartition (pHwInit,pHwInit->aPartition);
1220
1221            /* Unmask interrupts needed in the FW configuration phase */
1222            fwEvent_SetInitMask (pTWD->hFwEvent);
1223
1224            /* Get FW static information from mailbox area */
1225            BUILD_HW_INIT_FW_STATIC_TXN(pHwInit, pTxn, cmdMbox_GetMboxAddress (pTWD->hCmdMbox),
1226                                        (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
1227            status = twIf_Transact(pHwInit->hTwIf, pTxn);
1228
1229            EXCEPT (pHwInit, status);
1230            continue;
1231
1232        case 8:
1233
1234            pHwInit->uFinStage = 0;
1235
1236            cmdBld_FinalizeDownload (pTWD->hCmdBld, &pHwInit->tBootAttr, &(pHwInit->tFwStaticTxn.tFwStaticInfo));
1237
1238            /* Set the Download Status to COMPLETE */
1239            pHwInit->DownloadStatus = TXN_STATUS_COMPLETE;
1240
1241            return TXN_STATUS_COMPLETE;
1242
1243        } /* End switch */
1244
1245    } /* End while */
1246
1247}
1248
1249
1250/****************************************************************************
1251 *                      hwInit_ResetSm()
1252 ****************************************************************************
1253 * DESCRIPTION: Reset hardware state machine
1254 *
1255 * INPUTS:  None
1256 *
1257 * OUTPUT:  None
1258 *
1259 * RETURNS: TI_OK or TI_NOK
1260 ****************************************************************************/
1261static TI_STATUS hwInit_ResetSm (TI_HANDLE hHwInit)
1262{
1263    THwInit *pHwInit = (THwInit *)hHwInit;
1264    TI_STATUS status = TI_OK;
1265    TTxnStruct* pTxn;
1266
1267    pHwInit->uTxnIndex = 0;
1268
1269        /* Disable Rx/Tx */
1270    BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, REG_ENABLE_TX_RX, 0x0,
1271                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1272    status = twIf_Transact(pHwInit->hTwIf, pTxn);
1273	pHwInit->uTxnIndex++;
1274	return status;
1275}
1276
1277
1278/****************************************************************************
1279 *                      hwInit_EepromlessStartBurstSm()
1280 ****************************************************************************
1281 * DESCRIPTION: prepare eepromless configuration before boot
1282 *
1283 * INPUTS:
1284 *
1285 * OUTPUT:
1286 *
1287 * RETURNS:
1288 ****************************************************************************/
1289static TI_STATUS hwInit_EepromlessStartBurstSm (TI_HANDLE hHwInit)
1290{
1291    THwInit   *pHwInit = (THwInit *)hHwInit;
1292    TI_STATUS  status = TI_OK;
1293    TI_UINT8   *uAddr;
1294    TI_UINT32  uDeltaLength;
1295    TTxnStruct* pTxn;
1296
1297    pHwInit->uTxnIndex = 0;
1298
1299    while (TI_TRUE)
1300    {
1301        switch (pHwInit->uEEPROMStage)
1302        {
1303        /*
1304         * Stages 0, 1 handles the eeprom format parameters:
1305         * ------------------------------------------------
1306         * Length  - 8bit       --> The length is counted in 32bit words
1307         * Address - 16bit
1308         * Data    - (Length * 4) bytes
1309         *
1310         * Note: The nvs is in big endian format and we need to change it to little endian
1311         */
1312        case 0:
1313            /* Check if address LSB = 1 --> Register address */
1314            if ((pHwInit->uEEPROMRegAddr = pHwInit->pEEPROMCurPtr[1]) & 1)
1315            {
1316                /* Mask the register's address LSB before writing to it */
1317                pHwInit->uEEPROMRegAddr &= 0xfe;
1318                /* Change the address's endian */
1319                pHwInit->uEEPROMRegAddr |= (TI_UINT32)pHwInit->pEEPROMCurPtr[2] << 8;
1320                /* Length of burst data */
1321                pHwInit->uEEPROMBurstLen = pHwInit->pEEPROMCurPtr[0];
1322                pHwInit->pEEPROMCurPtr += 3;
1323                pHwInit->uEEPROMBurstLoop = 0;
1324                /*
1325                 * We've finished reading the burst information.
1326                 * Go to stage 1 in order to write it
1327                 */
1328                pHwInit->uEEPROMStage = 1;
1329            }
1330            /* If address LSB = 0 --> We're not in the burst section */
1331            else
1332            {
1333                /* End of Burst transaction: we should see 7 zeroed bytes */
1334                if (pHwInit->pEEPROMCurPtr[0] == 0)
1335                {
1336                    pHwInit->pEEPROMCurPtr += 7;
1337                }
1338                pHwInit->uEEPROMCurLen -= (pHwInit->pEEPROMCurPtr - pHwInit->pEEPROMBuf + 1);
1339                pHwInit->uEEPROMCurLen = (pHwInit->uEEPROMCurLen + NVS_DATA_BUNDARY_ALIGNMENT - 1) & 0xfffffffc;
1340                /* End of Burst transaction, go to TLV section */
1341                pHwInit->uEEPROMStage = 2;
1342            }
1343            continue;
1344
1345        case 1:
1346            if (pHwInit->uEEPROMBurstLoop < pHwInit->uEEPROMBurstLen)
1347            {
1348                /* Change the data's endian */
1349                TI_UINT32 val = (pHwInit->pEEPROMCurPtr[0] |
1350                                (pHwInit->pEEPROMCurPtr[1] << 8) |
1351                                (pHwInit->pEEPROMCurPtr[2] << 16) |
1352                                (pHwInit->pEEPROMCurPtr[3] << 24));
1353
1354                TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "NVS::BurstRead: *(%08x) = %x\n", pHwInit->uEEPROMRegAddr, val);
1355
1356                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, (REGISTERS_BASE+pHwInit->uEEPROMRegAddr), val,
1357                               REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_EepromlessStartBurstSm, hHwInit)
1358                status = twIf_Transact(pHwInit->hTwIf, pTxn);
1359
1360                pHwInit->uEEPROMStatus = status;
1361                pHwInit->uEEPROMRegAddr += WORD_SIZE;
1362                pHwInit->pEEPROMCurPtr +=  WORD_SIZE;
1363                /* While not end of burst, we stay in stage 1 */
1364                pHwInit->uEEPROMStage = 1;
1365                pHwInit->uEEPROMBurstLoop ++;
1366
1367                EXCEPT (pHwInit, status);
1368            }
1369            else
1370            {
1371                /* If end of burst return to stage 0 to read the next one */
1372                pHwInit->uEEPROMStage = 0;
1373            }
1374
1375            continue;
1376
1377        case 2:
1378
1379
1380            pHwInit->uEEPROMStage = 3;
1381
1382            /* Set the bus addresses partition to its "running" mode */
1383            SET_WORK_PARTITION(pHwInit->aPartition)
1384            hwInit_SetPartition (pHwInit,pHwInit->aPartition);
1385            continue;
1386
1387        case 3:
1388            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Reached TLV section\n");
1389
1390            /* Align the host address */
1391            if (((TI_UINT32)pHwInit->pEEPROMCurPtr & WORD_ALIGNMENT_MASK) && (pHwInit->uEEPROMCurLen > 0) )
1392            {
1393                uAddr = (TI_UINT8*)(((TI_UINT32)pHwInit->pEEPROMCurPtr & 0xFFFFFFFC)+WORD_SIZE);
1394                uDeltaLength = uAddr - pHwInit->pEEPROMCurPtr + 1;
1395
1396                pHwInit->pEEPROMCurPtr = uAddr;
1397                pHwInit->uEEPROMCurLen-= uDeltaLength;
1398            }
1399
1400            TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "NVS::WriteTLV: pEEPROMCurPtr= %x, Length=%d\n", pHwInit->pEEPROMCurPtr, pHwInit->uEEPROMCurLen);
1401
1402            if (pHwInit->uEEPROMCurLen)
1403            {
1404                /* Save the 4 bytes before the NVS data for WSPI case where they are overrun by the WSPI BusDrv */
1405                pHwInit->uSavedDataForWspiHdr = *(TI_UINT32 *)(pHwInit->pEEPROMCurPtr - WSPI_PAD_LEN_WRITE);
1406
1407                /* Prepare the Txn structure for the NVS transaction to the CMD_MBOX */
1408                HW_INIT_PTXN_SET(pHwInit, pTxn)
1409                TXN_PARAM_SET_DIRECTION(pTxn, TXN_DIRECTION_WRITE);
1410                BUILD_TTxnStruct(pTxn, CMD_MBOX_ADDRESS, pHwInit->pEEPROMCurPtr, pHwInit->uEEPROMCurLen,
1411                                 (TTxnDoneCb)hwInit_EepromlessStartBurstSm, hHwInit)
1412
1413                /* Transact the NVS data to the CMD_MBOX */
1414                status = twIf_Transact(pHwInit->hTwIf, pTxn);
1415
1416                pHwInit->uEEPROMCurLen = 0;
1417                pHwInit->uNVSStatus = status;
1418
1419                EXCEPT (pHwInit, status);
1420            }
1421            else
1422            {
1423                /* Restore the 4 bytes before the NVS data for WSPI case were they are overrun by the WSPI BusDrv */
1424                *(TI_UINT32 *)(pHwInit->pEEPROMCurPtr - WSPI_PAD_LEN_WRITE) = pHwInit->uSavedDataForWspiHdr;
1425
1426                /* Call the upper level state machine */
1427                if (pHwInit->uEEPROMStatus == TXN_STATUS_PENDING ||
1428                    pHwInit->uNVSStatus == TXN_STATUS_PENDING)
1429                {
1430                    hwInit_BootSm (hHwInit);
1431                }
1432
1433                return TXN_STATUS_COMPLETE;
1434            }
1435        } /* End switch */
1436
1437    } /* End while */
1438}
1439
1440/****************************************************************************
1441 *                      hwInit_LoadFwImageSm()
1442 ****************************************************************************
1443 * DESCRIPTION: Load image from the host and download into the hardware
1444 *
1445 * INPUTS:  None
1446 *
1447 * OUTPUT:  None
1448 *
1449 * RETURNS: TI_OK or TI_NOK
1450 ****************************************************************************/
1451
1452
1453#define ADDRESS_SIZE		(sizeof(TI_INT32))
1454
1455static TI_STATUS hwInit_LoadFwImageSm (TI_HANDLE hHwInit)
1456{
1457    THwInit *pHwInit 			= (THwInit *)hHwInit;
1458    TI_STATUS status 			= TI_OK;
1459	ETxnStatus	TxnStatus;
1460	TI_UINT32 uMaxPartitionSize	= PARTITION_DOWN_MEM_SIZE;
1461    TTxnStruct* pTxn;
1462
1463    pHwInit->uTxnIndex = 0;
1464
1465    while (TI_TRUE)
1466    {
1467        switch (pHwInit->uLoadStage)
1468        {
1469		case 0:
1470            pHwInit->uLoadStage = 1;
1471
1472			/* Check the Downloaded FW alignment */
1473			if ((pHwInit->uFwLength % ADDRESS_SIZE) != 0)
1474			{
1475				TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Length of downloaded Portion (%d) is not aligned\n",pHwInit->uFwLength);
1476				EXCEPT_L (pHwInit, TXN_STATUS_ERROR);
1477			}
1478
1479			TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "Image addr=0x%x, Len=0x%x\n", pHwInit->pFwBuf, pHwInit->uFwLength);
1480
1481			/* Set bus memory partition to current download area */
1482           SET_FW_LOAD_PARTITION(pHwInit->aPartition,pHwInit->uFwAddress)
1483           hwInit_SetPartition (pHwInit,pHwInit->aPartition);
1484            status = TI_OK;
1485			break;
1486
1487        case 1:
1488
1489			pHwInit->uLoadStage = 2;
1490			/* if initial size is smaller than MAX_SDIO_BLOCK - go strait to stage 4 to write partial block */
1491			if (pHwInit->uFwLength < MAX_SDIO_BLOCK)
1492			{
1493				pHwInit->uLoadStage = 4;
1494			}
1495
1496			pHwInit->uBlockReadNum 		= 0;
1497			pHwInit->uBlockWriteNum 	= 0;
1498			pHwInit->uPartitionLimit 	= pHwInit->uFwAddress + uMaxPartitionSize;
1499
1500            continue;
1501
1502        case 2:
1503
1504            /* Load firmware by blocks */
1505 			if (pHwInit->uBlockReadNum < (pHwInit->uFwLength / MAX_SDIO_BLOCK))
1506            {
1507                pHwInit->uLoadStage = 3;
1508
1509                /* Change partition */
1510				/* The +2 is for the last block and the block remainder */
1511				if ( ((pHwInit->uBlockWriteNum + 2) * MAX_SDIO_BLOCK + pHwInit->uFwAddress) > pHwInit->uPartitionLimit)
1512                {
1513					pHwInit->uFwAddress += pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK;
1514					/* update uPartitionLimit */
1515					pHwInit->uPartitionLimit = pHwInit->uFwAddress + uMaxPartitionSize;
1516                    /* Set bus memory partition to current download area */
1517                    SET_FW_LOAD_PARTITION(pHwInit->aPartition,pHwInit->uFwAddress)
1518                    hwInit_SetPartition (pHwInit,pHwInit->aPartition);
1519                    TxnStatus = TXN_STATUS_OK;
1520					pHwInit->uBlockWriteNum = 0;
1521                    TRACE1(pHwInit->hReport, REPORT_SEVERITY_INIT , "Change partition to address offset = 0x%x\n", 									   pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK);
1522                    EXCEPT_L (pHwInit, TxnStatus);
1523                }
1524            }
1525            else
1526            {
1527                pHwInit->uLoadStage = 4;
1528                TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Load firmware with Portions\n");
1529            }
1530            continue;
1531
1532        case 3:
1533            pHwInit->uLoadStage = 2;
1534
1535            pHwInit->uTxnIndex = 0;
1536
1537            /* Copy image block to temporary buffer */
1538            os_memoryCopy (pHwInit->hOs,
1539                           (void *)&pHwInit->auFwTmpBuf[WSPI_PAD_LEN_WRITE],
1540						   (void *)(pHwInit->pFwBuf + pHwInit->uBlockReadNum * MAX_SDIO_BLOCK),
1541						   MAX_SDIO_BLOCK);
1542
1543            /* Load the block. Save WSPI_PAD_LEN_WRITE space for WSPI bus command */
1544             BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, (pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK),
1545                                     (pHwInit->auFwTmpBuf + WSPI_PAD_LEN_WRITE), MAX_SDIO_BLOCK, TXN_DIRECTION_WRITE,
1546                                     (TTxnDoneCb)hwInit_LoadFwImageSm, hHwInit)
1547            TxnStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
1548
1549            /* Log ERROR if the transaction returned ERROR */
1550            if (TxnStatus == TXN_STATUS_ERROR)
1551            {
1552                TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "hwInit_LoadFwImageSm: twIf_Transact retruned status=0x%x\n", TxnStatus);
1553            }
1554
1555			pHwInit->uBlockWriteNum ++;
1556			pHwInit->uBlockReadNum ++;
1557            EXCEPT_L (pHwInit, TxnStatus);
1558            continue;
1559
1560        case 4:
1561			pHwInit->uLoadStage 	= 5;
1562
1563            pHwInit->uTxnIndex = 0;
1564
1565			/* If No Last block to write */
1566			if ( pHwInit->uFwLength % MAX_SDIO_BLOCK == 0 )
1567			{
1568				continue;
1569			}
1570
1571
1572            /* Copy the last image block */
1573             os_memoryCopy (pHwInit->hOs,
1574                           (void *)&pHwInit->auFwTmpBuf[WSPI_PAD_LEN_WRITE],
1575						   (void *)(pHwInit->pFwBuf + pHwInit->uBlockReadNum * MAX_SDIO_BLOCK),
1576						   pHwInit->uFwLength % MAX_SDIO_BLOCK);
1577
1578            /* Load the last block */
1579             BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, (pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK),
1580                                     (pHwInit->auFwTmpBuf + WSPI_PAD_LEN_WRITE), (pHwInit->uFwLength % MAX_SDIO_BLOCK), TXN_DIRECTION_WRITE,
1581                                     (TTxnDoneCb)hwInit_LoadFwImageSm, hHwInit)
1582            TxnStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
1583
1584            if (TxnStatus == TXN_STATUS_ERROR)
1585			{
1586                TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "hwInit_LoadFwImageSm: last block retruned status=0x%x\n", TxnStatus);
1587			}
1588
1589            EXCEPT_L (pHwInit, TxnStatus);
1590            continue;
1591
1592        case 5:
1593            pHwInit->uLoadStage = 0;
1594
1595			/*If end of overall FW Download Process: Finalize download (run firmware)*/
1596			if ( pHwInit->bFwBufLast == TI_TRUE )
1597			{
1598				/* The download has completed */
1599				WLAN_OS_REPORT (("Finished downloading firmware.\n"));
1600				status = hwInit_FinalizeDownloadSm (hHwInit);
1601			}
1602			/* Have to wait to more FW Portions */
1603			else
1604			{
1605				/* Call the upper layer callback */
1606				if ( pHwInit->fFinalizeDownload != NULL )
1607				{
1608					(pHwInit->fFinalizeDownload) (pHwInit->hFinalizeDownload);
1609				}
1610
1611				status = TI_OK;
1612			}
1613            return status;
1614
1615        } /* End switch */
1616
1617    } /* End while */
1618
1619} /* hwInit_LoadFwImageSm() */
1620
1621#define READ_TOP_REG_LOOP  32
1622
1623/****************************************************************************
1624 *                      hwInit_ReadRadioParamsSm ()
1625 ****************************************************************************
1626 * DESCRIPTION: hwInit_ReadRadioParamsSm
1627 * INPUTS:  None
1628 *
1629 * OUTPUT:  None
1630 *
1631 * RETURNS: TI_OK or TI_NOK
1632 ****************************************************************************/
1633TI_STATUS hwInit_ReadRadioParamsSm (TI_HANDLE hHwInit)
1634{
1635    THwInit      *pHwInit = (THwInit *)hHwInit;
1636    TTwd         *pTWD = (TTwd *)pHwInit->hTWD;
1637   IniFileGeneralParam *pGenParams = &DB_GEN(pTWD->hCmdBld);
1638    TI_UINT32  val= 0, value;
1639    TI_UINT32  add = FUNC7_SEL;
1640	TI_UINT32  retAddress;
1641    TTxnStruct  *pTxn;
1642    TI_STATUS   status = 0;
1643
1644
1645    while (TI_TRUE)
1646    {
1647       switch (pHwInit->uRegStage)
1648        {
1649        case 0:
1650            pHwInit->uRegStage = 1;
1651            pHwInit->uTxnIndex++;
1652
1653            /*
1654             * Select GPIO over Debug for BT_FUNC7 clear bit 17
1655             */
1656            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_SELECT, 0,
1657                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
1658            status = twIf_Transact(pHwInit->hTwIf, pTxn);
1659
1660            EXCEPT (pHwInit, status)
1661
1662        case 1:
1663            pHwInit->uRegStage ++;
1664            pHwInit->uRegLoop = 0;
1665
1666            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
1667            val = (pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData);
1668            val &= 0xFFFDFFFF; /*clear bit 17*/
1669            /* Now we can zero the index */
1670            pHwInit->uTxnIndex = 0;
1671
1672            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_SELECT, val,
1673                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1674
1675            twIf_Transact(pHwInit->hTwIf, pTxn);
1676
1677            pHwInit->uTxnIndex++;
1678
1679            pHwInit->uRegData = FUNC7_SEL;
1680
1681            continue;
1682
1683        case 2:
1684
1685            pHwInit->uRegStage ++;
1686            add = pHwInit->uRegData;
1687
1688
1689            /* Select GPIO over Debug for BT_FUNC7*/
1690            retAddress = (TI_UINT32)(add / 2);
1691	        val = (retAddress & 0x7FF);
1692        	val |= BIT_16 | BIT_17;
1693
1694            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, val,
1695                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1696            twIf_Transact(pHwInit->hTwIf, pTxn);
1697
1698            pHwInit->uTxnIndex++;
1699
1700            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2,
1701                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1702            twIf_Transact(pHwInit->hTwIf, pTxn);
1703
1704            continue;
1705
1706        case 3:
1707
1708            pHwInit->uRegStage ++;
1709            pHwInit->uTxnIndex++;
1710
1711            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0,
1712                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
1713            status = twIf_Transact(pHwInit->hTwIf, pTxn);
1714
1715            EXCEPT (pHwInit, status)
1716
1717
1718        case 4:
1719
1720            val = (pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData);
1721
1722            pHwInit->uTxnIndex = 0;
1723            if (val & BIT_18)
1724            {
1725              if ((val & BIT_16) && (!(val & BIT_17)))
1726              {
1727                  pHwInit->uRegStage ++;
1728                  pHwInit->uRegLoop = 0;
1729
1730              }
1731              else
1732              {
1733                TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "can't writing bt_func7_sel\n");
1734
1735                TWD_FinalizeFEMRead(pHwInit->hTWD);
1736
1737                return TI_NOK;
1738              }
1739            }
1740            else
1741            {
1742              if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
1743              {
1744                 pHwInit->uRegStage = 3;
1745                 pHwInit->uRegLoop++;
1746              }
1747              else
1748              {
1749
1750                TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");
1751
1752                TWD_FinalizeFEMRead(pHwInit->hTWD);
1753
1754                return TI_NOK;
1755
1756              }
1757            }
1758
1759            continue;
1760
1761        case 5:
1762               pHwInit->uRegStage ++;
1763               add = pHwInit->uRegData;
1764               retAddress = (TI_UINT32)(add / 2);
1765	           value = (retAddress & 0x7FF);
1766               value |= BIT_16 | BIT_17;
1767
1768               BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, value,
1769                                  REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1770               twIf_Transact(pHwInit->hTwIf, pTxn);
1771
1772               pHwInit->uTxnIndex++;
1773
1774              if (pHwInit->uRegSeqStage == 0)
1775              {
1776                  if (pHwInit->uRegData == FUNC7_SEL)
1777                    value = (val | 0x600);
1778                  else
1779                    value = (val | 0x1000);
1780              }
1781              else
1782              {
1783                  if (pHwInit->uRegData == FUNC7_SEL)
1784                    value = (val & 0xF8FF);
1785                  else
1786                    value = (val & 0xCFFF);
1787
1788              }
1789
1790	      value &= 0xFFFF;
1791
1792               BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, value,
1793                                  REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1794               twIf_Transact(pHwInit->hTwIf, pTxn);
1795
1796               pHwInit->uTxnIndex++;
1797
1798               BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1,
1799                                  REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
1800
1801               /*BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, INDIRECT_REG5, 0x1,
1802                                  REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL) */
1803
1804               status = twIf_Transact(pHwInit->hTwIf, pTxn);
1805
1806               pHwInit->uTxnIndex++;
1807
1808               if ((pHwInit->uRegData == FUNC7_SEL)&& (pHwInit->uRegSeqStage == 0))
1809               {
1810                 pHwInit->uRegData = FUNC7_PULL;
1811                 pHwInit->uRegStage = 2;
1812               }
1813               else
1814               {
1815                  if ((pHwInit->uRegData == FUNC7_PULL)&& (pHwInit->uRegSeqStage == 1))
1816                   {
1817                     pHwInit->uRegData = FUNC7_SEL;
1818                     pHwInit->uRegStage = 2;
1819                   }
1820               }
1821
1822               EXCEPT (pHwInit, status)
1823               continue;
1824
1825        case 6:
1826
1827              if (pHwInit->uRegSeqStage == 1)
1828              {
1829                  pHwInit->uRegStage = 8;
1830              }
1831              else
1832              {
1833                pHwInit->uRegStage ++;
1834                pHwInit->uTxnIndex++;
1835
1836                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_OE_RADIO, 0,
1837                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
1838                status = twIf_Transact(pHwInit->hTwIf, pTxn);
1839                EXCEPT (pHwInit, status)
1840              }
1841              continue;
1842
1843        case 7:
1844            pHwInit->uRegStage ++;
1845
1846            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
1847            val = (pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData);
1848            val |= 0x00020000;
1849
1850            pHwInit->uTxnIndex = 0;
1851            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_OE_RADIO, val,
1852                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1853            twIf_Transact(pHwInit->hTwIf, pTxn);
1854
1855            pHwInit->uTxnIndex++;
1856
1857            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_IN, 0,
1858                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
1859            status = twIf_Transact(pHwInit->hTwIf, pTxn);
1860
1861            EXCEPT (pHwInit, status)
1862
1863
1864        case 8:
1865            if (pHwInit->uRegSeqStage == 0)
1866             {
1867	       val = (pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData);
1868	       val &= 0x20000;
1869	       if(val)
1870	      {
1871		   pGenParams->TXBiPFEMManufacturer = FEM_TRIQUINT_TYPE_E;
1872	      }
1873	      else
1874	      {
1875	  	   pGenParams->TXBiPFEMManufacturer = FEM_RFMD_TYPE_E;
1876	      }
1877               WLAN_OS_REPORT (("FEM Type %d \n",pGenParams->TXBiPFEMManufacturer));
1878			   pHwInit->uTxnIndex = 0;
1879               pHwInit->uRegSeqStage = 1;
1880               pHwInit->uRegStage = 2;
1881               pHwInit->uRegData = FUNC7_PULL;
1882               continue;
1883             }
1884             else
1885             {
1886              TRACE0(pHwInit->hReport, REPORT_SEVERITY_INFORMATION, "hwInit_ReadRadioParamsSm Ended Successfully\n");
1887
1888              TWD_FinalizeFEMRead(pHwInit->hTWD);
1889
1890              return TI_OK;
1891
1892             }
1893
1894        } /* End switch */
1895
1896    } /* End while */
1897
1898}
1899
1900
1901/****************************************************************************
1902 *                      hwInit_ReadRadioParams()
1903 ****************************************************************************
1904 * DESCRIPTION: hwInit_ReadRadioParamsSm
1905 * initalizie hwInit_ReadRadioParamsSm parmaeters
1906  ****************************************************************************/
1907
1908TI_STATUS hwInit_ReadRadioParams (TI_HANDLE hHwInit)
1909{
1910  THwInit      *pHwInit = (THwInit *)hHwInit;
1911
1912  pHwInit->uRegStage = 0;
1913  pHwInit->uRegSeqStage = 0;
1914
1915  return hwInit_ReadRadioParamsSm (hHwInit);
1916}
1917
1918/****************************************************************************
1919 *                      hwInit_InitPoalrity()
1920 ****************************************************************************
1921 * DESCRIPTION: hwInit_ReadRadioParamsSm
1922 * initalizie hwInit_ReadRadioParamsSm parmaeters
1923  ****************************************************************************/
1924
1925TI_STATUS hwInit_InitPolarity(TI_HANDLE hHwInit)
1926{
1927  THwInit      *pHwInit = (THwInit *)hHwInit;
1928
1929  pHwInit->uRegStage = 0;
1930  pHwInit->uRegSeqStage = 0;
1931
1932  return hwInit_WriteIRQPolarity (hHwInit);
1933}
1934
1935
1936
1937/****************************************************************************
1938 *                      hwInit_WriteIRQPolarity ()
1939 ****************************************************************************
1940 * DESCRIPTION: hwInit_WriteIRQPolarity
1941  * INPUTS:  None
1942 *
1943 * OUTPUT:  None
1944 *
1945 * RETURNS: TI_OK or TI_NOK
1946 ****************************************************************************/
1947 TI_STATUS hwInit_WriteIRQPolarity(TI_HANDLE hHwInit)
1948 {
1949     THwInit     *pHwInit = (THwInit *)hHwInit;
1950     TI_UINT32   Address,value;
1951     TI_UINT32   val=0;
1952     TTxnStruct  *pTxn;
1953     TI_STATUS   status = 0;
1954
1955   /*  To write to a top level address from the WLAN IP:
1956       Write the top level address to the OCP_POR_CTR register.
1957       Divide the top address by 2, and add 0x30000 to the result  for example for top address 0xC00, write to the OCP_POR_CTR 0x30600
1958       Write the data to the OCP_POR_WDATA register
1959       Write 0x1 to the OCP_CMD register.
1960
1961      To read from a top level address:
1962      Write the top level address to the OCP_POR_CTR register.
1963      Divide the top address by 2, and add 0x30000 to the result  for example for top address 0xC00, write to the OCP_POR_CTR 0x30600
1964      Write 0x2 to the OCP_CMD register.
1965      Poll bit [18] of OCP_DATA_RD for data valid indication
1966      Check bits 17:16 of OCP_DATA_RD:
1967      00  no response
1968      01  data valid / accept
1969      10  request failed
1970      11  response error
1971      Read the data from the OCP_DATA_RD register
1972   */
1973
1974     while (TI_TRUE)
1975     {
1976         switch (pHwInit->uRegStage)
1977         {
1978         case 0:
1979
1980             pHwInit->uRegStage = 1;
1981             pHwInit->uTxnIndex++;
1982             pHwInit->uRegLoop = 0;
1983
1984             /* first read the IRQ Polarity register*/
1985             Address = (TI_UINT32)(FN0_CCCR_REG_32 / 2);
1986             val = (Address & 0x7FF);
1987             val |= BIT_16 | BIT_17;
1988
1989             /* Write IRQ Polarity address register to OCP_POR_CTR*/
1990             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, val,
1991                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
1992
1993             twIf_Transact(pHwInit->hTwIf, pTxn);
1994
1995             pHwInit->uTxnIndex++;
1996
1997             /* Write read (2)command to the OCP_CMD register. */
1998
1999             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2,
2000                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
2001             twIf_Transact(pHwInit->hTwIf, pTxn);
2002
2003             continue;
2004
2005         case 1:
2006
2007             pHwInit->uRegStage ++;
2008             pHwInit->uTxnIndex++;
2009
2010             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0,
2011                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_WriteIRQPolarity, hHwInit)
2012             status = twIf_Transact(pHwInit->hTwIf, pTxn);
2013
2014             EXCEPT (pHwInit, status)
2015
2016
2017         case 2:
2018             /* get the value from  IRQ Polarity register*/
2019             val = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
2020
2021             pHwInit->uTxnIndex = 0;
2022
2023             /*Poll bit 18 of OCP_DATA_RD for data valid indication*/
2024             if (val & BIT_18)
2025             {
2026               if ((val & BIT_16) && (!(val & BIT_17)))
2027               {
2028                   pHwInit->uRegStage ++;
2029                   pHwInit->uRegLoop = 0;
2030
2031               }
2032               else
2033               {
2034                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "can't writing bt_func7_sel\n");
2035                 TWD_FinalizePolarityRead(pHwInit->hTWD);
2036
2037                return TI_NOK;
2038               }
2039             }
2040             else
2041             {
2042               if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
2043               {
2044                  pHwInit->uRegStage = 1;
2045                  pHwInit->uRegLoop++;
2046               }
2047               else
2048               {
2049
2050                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");
2051                 TWD_FinalizePolarityRead(pHwInit->hTWD);
2052
2053                return TI_NOK;
2054
2055               }
2056             }
2057
2058             continue;
2059
2060
2061         case 3:
2062               /* second, write new value of IRQ polarity due to complation flag 1 - active low, 0 - active high*/
2063                pHwInit->uRegStage ++;
2064                Address = (TI_UINT32)(FN0_CCCR_REG_32 / 2);
2065                value = (Address & 0x7FF);
2066                value |= BIT_16 | BIT_17;
2067
2068                /* Write IRQ Polarity address register to OCP_POR_CTR*/
2069
2070                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, value,
2071                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
2072
2073                twIf_Transact(pHwInit->hTwIf, pTxn);
2074
2075                pHwInit->uTxnIndex++;
2076
2077#ifdef USE_IRQ_ACTIVE_HIGH
2078                TRACE0(pHwInit->hReport, REPORT_SEVERITY_INFORMATION , "Hwinit IRQ polarity active high\n");
2079                val |= 0x0<<1;
2080
2081#else
2082                TRACE0(pHwInit->hReport, REPORT_SEVERITY_INFORMATION , "Hwinit IRQ polarity active low\n");
2083                val |= 0x01<<1;
2084#endif
2085
2086              /* Write the new IRQ polarity value to the OCP_POR_WDATA register */
2087                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, val,
2088                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
2089                twIf_Transact(pHwInit->hTwIf, pTxn);
2090
2091                pHwInit->uTxnIndex++;
2092
2093               /* Write write (1)command to the OCP_CMD register. */
2094                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1,
2095                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_WriteIRQPolarity, hHwInit)
2096                status = twIf_Transact(pHwInit->hTwIf, pTxn);
2097
2098                pHwInit->uTxnIndex++;
2099
2100                EXCEPT (pHwInit, status)
2101                continue;
2102
2103         case 4:
2104
2105               TWD_FinalizePolarityRead(pHwInit->hTWD);
2106
2107              return TI_OK;
2108
2109
2110         } /* End switch */
2111
2112     } /* End while */
2113
2114 }
2115
2116
2117/****************************************************************************
2118 *                      hwInit_InitTopRegisterWrite()
2119 ****************************************************************************
2120 * DESCRIPTION: hwInit_InitTopRegisterWrite
2121 * initalizie hwInit_TopRegisterWrite SM parmaeters
2122  ****************************************************************************/
2123
2124TI_STATUS hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit, TI_UINT32 uAddress, TI_UINT32 uValue)
2125{
2126  THwInit      *pHwInit = (THwInit *)hHwInit;
2127
2128  pHwInit->uTopStage = 0;
2129  uAddress = (TI_UINT32)(uAddress / 2);
2130  uAddress = (uAddress & 0x7FF);
2131  uAddress|= BIT_16 | BIT_17;
2132  pHwInit->uTopRegAddr = uAddress;
2133  pHwInit->uTopRegValue = uValue & 0xffff;
2134  return hwInit_TopRegisterWrite (hHwInit);
2135}
2136
2137
2138/****************************************************************************
2139 *                      hwInit_TopRegisterWrite ()
2140 ****************************************************************************
2141 * DESCRIPTION: Generic function that writes to the top registers area
2142  * INPUTS:  None
2143 *
2144 * OUTPUT:  None
2145 *
2146 * RETURNS: TI_OK or TI_NOK
2147 ****************************************************************************/
2148 TI_STATUS hwInit_TopRegisterWrite(TI_HANDLE hHwInit)
2149 {
2150     /*  To write to a top level address from the WLAN IP:
2151         Write the top level address to the OCP_POR_CTR register.
2152         Divide the top address by 2, and add 0x30000 to the result  for example for top address 0xC00, write to the OCP_POR_CTR 0x30600
2153         Write the data to the OCP_POR_WDATA register
2154         Write 0x1 to the OCP_CMD register.
2155     */
2156     THwInit *pHwInit = (THwInit *)hHwInit;
2157     TTxnStruct *pTxn;
2158
2159     while (TI_TRUE)
2160     {
2161         switch (pHwInit->uTopStage)
2162         {
2163         case 0:
2164             pHwInit->uTopStage = 1;
2165
2166             pHwInit->uTxnIndex++;
2167             /* Write the address to OCP_POR_CTR*/
2168             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, pHwInit->uTopRegAddr,
2169                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
2170             twIf_Transact(pHwInit->hTwIf, pTxn);
2171
2172             pHwInit->uTxnIndex++;
2173             /* Write the new value to the OCP_POR_WDATA register */
2174             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, pHwInit->uTopRegValue,
2175                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
2176             twIf_Transact(pHwInit->hTwIf, pTxn);
2177
2178             pHwInit->uTxnIndex++;
2179             /* Write write (1)command to the OCP_CMD register. */
2180             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1,
2181                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_TopRegisterWrite, hHwInit)
2182             pHwInit->uTopStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
2183
2184             pHwInit->uTxnIndex++;
2185
2186             EXCEPT (pHwInit, pHwInit->uTopStatus)
2187             continue;
2188
2189         case 1:
2190
2191             pHwInit->uTxnIndex = 0;
2192
2193             if (pHwInit->uTopStatus == TXN_STATUS_PENDING)
2194             {
2195                 hwInit_BootSm (hHwInit);
2196             }
2197
2198             return TI_OK;
2199
2200         } /* End switch */
2201
2202     } /* End while */
2203
2204 }
2205
2206
2207 /****************************************************************************
2208 *                      hwInit_InitTopRegisterRead()
2209 ****************************************************************************
2210 * DESCRIPTION: hwInit_InitTopRegisterRead
2211 * initalizie hwInit_InitTopRegisterRead SM parmaeters
2212  ****************************************************************************/
2213
2214TI_STATUS hwInit_InitTopRegisterRead(TI_HANDLE hHwInit, TI_UINT32 uAddress)
2215{
2216  THwInit      *pHwInit = (THwInit *)hHwInit;
2217
2218  pHwInit->uTopStage = 0;
2219  uAddress = (TI_UINT32)(uAddress / 2);
2220  uAddress = (uAddress & 0x7FF);
2221  uAddress|= BIT_16 | BIT_17;
2222  pHwInit->uTopRegAddr = uAddress;
2223
2224  return hwInit_TopRegisterRead (hHwInit);
2225}
2226
2227
2228/****************************************************************************
2229 *                      hwInit_TopRegisterRead ()
2230 ****************************************************************************
2231 * DESCRIPTION: Generic function that reads the top registers area
2232  * INPUTS:  None
2233 *
2234 * OUTPUT:  None
2235 *
2236 * RETURNS: TI_OK or TI_NOK
2237 ****************************************************************************/
2238 TI_STATUS hwInit_TopRegisterRead(TI_HANDLE hHwInit)
2239 {
2240     /*
2241        To read from a top level address:
2242        Write the top level address to the OCP_POR_CTR register.
2243        Divide the top address by 2, and add 0x30000 to the result  for example for top address 0xC00, write to the OCP_POR_CTR 0x30600
2244        Write 0x2 to the OCP_CMD register.
2245        Poll bit [18] of OCP_DATA_RD for data valid indication
2246        Check bits 17:16 of OCP_DATA_RD:
2247        00  no response
2248        01  data valid / accept
2249        10  request failed
2250        11  response error
2251        Read the data from the OCP_DATA_RD register
2252     */
2253
2254     THwInit *pHwInit = (THwInit *)hHwInit;
2255     TTxnStruct *pTxn;
2256
2257     while (TI_TRUE)
2258     {
2259         switch (pHwInit->uTopStage)
2260         {
2261         case 0:
2262             pHwInit->uTopStage = 1;
2263             pHwInit->uTxnIndex++;
2264             pHwInit->uRegLoop = 0;
2265
2266             /* Write the address to OCP_POR_CTR*/
2267             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, pHwInit->uTopRegAddr,
2268                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
2269             twIf_Transact(pHwInit->hTwIf, pTxn);
2270
2271             pHwInit->uTxnIndex++;
2272             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2,
2273                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
2274             twIf_Transact(pHwInit->hTwIf, pTxn);
2275
2276             continue;
2277
2278         case 1:
2279             pHwInit->uTopStage ++;
2280             pHwInit->uTxnIndex++;
2281
2282             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0,
2283                                    REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_TopRegisterRead, hHwInit)
2284             pHwInit->uTopStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
2285
2286             EXCEPT (pHwInit, pHwInit->uTopStatus)
2287
2288         case 2:
2289             /* get the value from  IRQ Polarity register*/
2290             pHwInit->uTopRegValue = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
2291
2292             pHwInit->uTxnIndex = 0;
2293
2294             /*Poll bit 18 of OCP_DATA_RD for data valid indication*/
2295             if (pHwInit->uTopRegValue & BIT_18)
2296             {
2297               if ((pHwInit->uTopRegValue & BIT_16) && (!(pHwInit->uTopRegValue & BIT_17)))
2298               {
2299                   pHwInit->uTopRegValue &= 0xffff;
2300                   pHwInit->uTxnIndex = 0;
2301                   pHwInit->uRegLoop = 0;
2302                   if (pHwInit->uTopStatus == TXN_STATUS_PENDING)
2303                   {
2304                       hwInit_BootSm (hHwInit);
2305                   }
2306                   return TI_OK;
2307               }
2308               else
2309               {
2310                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "can't write bt_func7_sel\n");
2311                 if (pHwInit->uTopStatus == TXN_STATUS_PENDING)
2312                 {
2313                       hwInit_BootSm (hHwInit);
2314                 }
2315                 return TI_NOK;
2316               }
2317             }
2318             else
2319             {
2320               if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
2321               {
2322                  pHwInit->uTopStage = 1;
2323                  pHwInit->uRegLoop++;
2324               }
2325               else
2326               {
2327                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");
2328                 if (pHwInit->uTopStatus == TXN_STATUS_PENDING)
2329                 {
2330                       hwInit_BootSm (hHwInit);
2331                 }
2332                 return TI_NOK;
2333               }
2334              }
2335
2336             continue;
2337
2338         } /* End switch */
2339
2340     } /* End while */
2341
2342 }
2343
2344
2345/****************************************************************************
2346*                      hwInit_StallTimerCb ()
2347****************************************************************************
2348* DESCRIPTION: CB timer function in fTimerFunction format that calls hwInit_StallTimerCb
2349* INPUTS:  TI_HANDLE hHwInit
2350*
2351* OUTPUT:  None
2352*
2353* RETURNS: None
2354****************************************************************************/
2355#ifdef DOWNLOAD_TIMER_REQUIERD
2356 static void hwInit_StallTimerCb (TI_HANDLE hHwInit, TI_BOOL bTwdInitOccured)
2357{
2358	hwInit_FinalizeDownloadSm (hHwInit);
2359}
2360#endif
2361