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