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
66 extern void TWD_FinalizeOnFailure (TI_HANDLE hTWD);
67 extern 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
246 enum
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
256 enum
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
267 typedef struct
268 {
269 TTxnStruct tTxnStruct;
270 TI_UINT32 uData;
271
272 } THwInitTxn;
273
274 typedef struct
275 {
276 TTxnStruct tTxnStruct;
277 FwStaticData_t tFwStaticInfo;
278
279 } TFwStaticTxn;
280
281
282 /* The HW Init module object */
283 typedef 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 ************************************************************************/
384 static void hwInit_SetPartition (THwInit *pHwInit,
385 TPartition *pPartition);
386 static TI_STATUS hwInit_BootSm (TI_HANDLE hHwInit);
387 static TI_STATUS hwInit_ResetSm (TI_HANDLE hHwInit);
388 static TI_STATUS hwInit_EepromlessStartBurstSm (TI_HANDLE hHwInit);
389 static TI_STATUS hwInit_LoadFwImageSm (TI_HANDLE hHwInit);
390 static TI_STATUS hwInit_FinalizeDownloadSm (TI_HANDLE hHwInit);
391 static TI_STATUS hwInit_TopRegisterRead(TI_HANDLE hHwInit);
392 static TI_STATUS hwInit_InitTopRegisterRead(TI_HANDLE hHwInit, TI_UINT32 uAddress);
393 static TI_STATUS hwInit_TopRegisterWrite(TI_HANDLE hHwInit);
394 static TI_STATUS hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit, TI_UINT32 uAddress, TI_UINT32 uValue);
395 #ifdef DOWNLOAD_TIMER_REQUIERD
396 static 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 *************************************************************************/
hwInit_Create(TI_HANDLE hOs)414 TI_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 ***************************************************************************/
hwInit_Destroy(TI_HANDLE hHwInit)448 TI_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 ***************************************************************************/
hwInit_Init(TI_HANDLE hHwInit,TI_HANDLE hReport,TI_HANDLE hTimer,TI_HANDLE hTWD,TI_HANDLE hFinalizeDownload,TFinalizeCb fFinalizeDownload,TEndOfHwInitCb fInitHwCb)474 TI_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
hwInit_SetNvsImage(TI_HANDLE hHwInit,TI_UINT8 * pbuf,TI_UINT32 length)528 TI_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
hwInit_SetFwImage(TI_HANDLE hHwInit,TFileInfo * pFileInfo)539 TI_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 */
hwInit_SetPartition(THwInit * pHwInit,TPartition * pPartition)577 static 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 ****************************************************************************/
hwInit_Boot(TI_HANDLE hHwInit)599 TI_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 ****************************************************************************/
hwInit_BootSm(TI_HANDLE hHwInit)643 static 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 << 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
hwInit_LoadFw(TI_HANDLE hHwInit)989 TI_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 ****************************************************************************/
hwInit_FinalizeDownloadSm(TI_HANDLE hHwInit)1051 static 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 ****************************************************************************/
hwInit_ResetSm(TI_HANDLE hHwInit)1261 static 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 ****************************************************************************/
hwInit_EepromlessStartBurstSm(TI_HANDLE hHwInit)1289 static 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
hwInit_LoadFwImageSm(TI_HANDLE hHwInit)1455 static 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 ****************************************************************************/
hwInit_ReadRadioParamsSm(TI_HANDLE hHwInit)1633 TI_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
hwInit_ReadRadioParams(TI_HANDLE hHwInit)1908 TI_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
hwInit_InitPolarity(TI_HANDLE hHwInit)1925 TI_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 ****************************************************************************/
hwInit_WriteIRQPolarity(TI_HANDLE hHwInit)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
hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit,TI_UINT32 uAddress,TI_UINT32 uValue)2124 TI_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 ****************************************************************************/
hwInit_TopRegisterWrite(TI_HANDLE hHwInit)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
hwInit_InitTopRegisterRead(TI_HANDLE hHwInit,TI_UINT32 uAddress)2214 TI_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 ****************************************************************************/
hwInit_TopRegisterRead(TI_HANDLE hHwInit)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
hwInit_StallTimerCb(TI_HANDLE hHwInit,TI_BOOL bTwdInitOccured)2356 static void hwInit_StallTimerCb (TI_HANDLE hHwInit, TI_BOOL bTwdInitOccured)
2357 {
2358 hwInit_FinalizeDownloadSm (hHwInit);
2359 }
2360 #endif
2361