atmel_lcd: Allow contrast polarity to be either positive or negative
[platform/kernel/u-boot.git] / arch / arm / cpu / ixp / npe / IxNpeDlNpeMgr.c
1 /**
2  * @file IxNpeDlNpeMgr.c
3  *
4  * @author Intel Corporation
5  * @date 09 January 2002
6  *
7  * @brief This file contains the implementation of the private API for the
8  *        IXP425 NPE Downloader NpeMgr module
9  *
10  * 
11  * @par
12  * IXP400 SW Release version 2.0
13  * 
14  * -- Copyright Notice --
15  * 
16  * @par
17  * Copyright 2001-2005, Intel Corporation.
18  * All rights reserved.
19  * 
20  * @par
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions
23  * are met:
24  * 1. Redistributions of source code must retain the above copyright
25  *    notice, this list of conditions and the following disclaimer.
26  * 2. Redistributions in binary form must reproduce the above copyright
27  *    notice, this list of conditions and the following disclaimer in the
28  *    documentation and/or other materials provided with the distribution.
29  * 3. Neither the name of the Intel Corporation nor the names of its contributors
30  *    may be used to endorse or promote products derived from this software
31  *    without specific prior written permission.
32  * 
33  * @par
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
35  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44  * SUCH DAMAGE.
45  * 
46  * @par
47  * -- End of Copyright Notice --
48 */
49
50
51 /*
52  * Put the user defined include files required.
53  */
54
55
56 /*
57  * Put the user defined include files required.
58  */
59 #include "IxOsal.h"
60 #include "IxNpeDl.h"
61 #include "IxNpeDlNpeMgr_p.h"
62 #include "IxNpeDlNpeMgrUtils_p.h"
63 #include "IxNpeDlNpeMgrEcRegisters_p.h"
64 #include "IxNpeDlMacros_p.h"
65 #include "IxFeatureCtrl.h"
66
67 /*
68  * #defines and macros used in this file.
69  */
70 #define IX_NPEDL_BYTES_PER_WORD                   4
71
72 /* used to read download map from version in microcode image */
73 #define IX_NPEDL_BLOCK_TYPE_INSTRUCTION           0x00000000
74 #define IX_NPEDL_BLOCK_TYPE_DATA                  0x00000001
75 #define IX_NPEDL_BLOCK_TYPE_STATE                 0x00000002
76 #define IX_NPEDL_END_OF_DOWNLOAD_MAP              0x0000000F
77
78 /*
79  * masks used to extract address info from State information context
80  * register addresses as read from microcode image 
81  */
82 #define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG         0x0000000F
83 #define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM         0x000000F0
84
85 /* LSB offset of Context Number field in State-Info Context Address */
86 #define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM       4
87
88 /* size (in words) of single State Information entry (ctxt reg address|data) */
89 #define IX_NPEDL_STATE_INFO_ENTRY_SIZE            2
90
91
92  #define IX_NPEDL_RESET_NPE_PARITY  0x0800
93  #define IX_NPEDL_PARITY_BIT_MASK   0x3F00FFFF
94  #define IX_NPEDL_CONFIG_CTRL_REG_MASK  0x3F3FFFFF
95
96
97 /*
98  * Typedefs whose scope is limited to this file.
99  */
100
101 typedef struct
102 {
103     UINT32 type;
104     UINT32 offset;
105 } IxNpeDlNpeMgrDownloadMapBlockEntry;
106
107 typedef union
108 {
109     IxNpeDlNpeMgrDownloadMapBlockEntry block;
110     UINT32 eodmMarker;
111 } IxNpeDlNpeMgrDownloadMapEntry;
112
113 typedef struct
114 {
115     /* 1st entry in the download map (there may be more than one) */
116     IxNpeDlNpeMgrDownloadMapEntry entry[1];
117 } IxNpeDlNpeMgrDownloadMap;
118
119
120 /* used to access an instruction or data block in a microcode image */
121 typedef struct
122 {
123     UINT32 npeMemAddress;
124     UINT32 size;
125     UINT32 data[1];
126 } IxNpeDlNpeMgrCodeBlock;
127
128 /* used to access each Context Reg entry state-information block */
129 typedef struct
130 {
131     UINT32 addressInfo;
132     UINT32 value;
133 } IxNpeDlNpeMgrStateInfoCtxtRegEntry;
134
135 /* used to access a state-information block in a microcode image */
136 typedef struct
137 {
138     UINT32 size;
139     IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];
140 } IxNpeDlNpeMgrStateInfoBlock;
141  
142 /* used to store some useful NPE information for easy access */
143 typedef struct
144 {
145     UINT32 baseAddress;
146     UINT32 insMemSize;
147     UINT32 dataMemSize;
148 } IxNpeDlNpeInfo;
149
150 /* used to distinguish instruction and data memory operations */
151 typedef enum 
152 {
153   IX_NPEDL_MEM_TYPE_INSTRUCTION = 0,
154   IX_NPEDL_MEM_TYPE_DATA
155 } IxNpeDlNpeMemType;
156
157 /* used to hold a reset value for a particular ECS register */
158 typedef struct
159 {
160     UINT32 regAddr;
161     UINT32 regResetVal;
162 } IxNpeDlEcsRegResetValue;
163
164 /* prototype of function to write either Instruction or Data memory */
165 typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress,
166                                             UINT32 npeMemAddress,
167                                             UINT32 npeMemData,
168                                             BOOL verify);
169
170 /* module statistics counters */
171 typedef struct
172 {
173     UINT32 instructionBlocksLoaded;
174     UINT32 dataBlocksLoaded;
175     UINT32 stateInfoBlocksLoaded;
176     UINT32 criticalNpeErrors;
177     UINT32 criticalMicrocodeErrors;
178     UINT32 npeStarts;
179     UINT32 npeStops;
180     UINT32 npeResets;
181 } IxNpeDlNpeMgrStats;
182
183
184 /*
185  * Variable declarations global to this file only.  Externs are followed by
186  * static variables.
187  */
188 static IxNpeDlNpeInfo ixNpeDlNpeInfo[] =
189 {
190     {
191         0,
192         IX_NPEDL_INS_MEMSIZE_WORDS_NPEA,
193         IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
194     },
195     {
196         0,
197         IX_NPEDL_INS_MEMSIZE_WORDS_NPEB,
198         IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
199     },
200     {
201         0,
202         IX_NPEDL_INS_MEMSIZE_WORDS_NPEC,
203         IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
204     }
205 };
206
207 /* contains Reset values for Context Store Registers  */
208 static UINT32 ixNpeDlCtxtRegResetValues[] =
209 {
210     IX_NPEDL_CTXT_REG_RESET_STEVT,
211     IX_NPEDL_CTXT_REG_RESET_STARTPC,
212     IX_NPEDL_CTXT_REG_RESET_REGMAP,
213     IX_NPEDL_CTXT_REG_RESET_CINDEX,
214 };
215
216 /* contains Reset values for Context Store Registers  */
217 static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] =
218 {
219     {IX_NPEDL_ECS_BG_CTXT_REG_0,    IX_NPEDL_ECS_BG_CTXT_REG_0_RESET},
220     {IX_NPEDL_ECS_BG_CTXT_REG_1,    IX_NPEDL_ECS_BG_CTXT_REG_1_RESET},
221     {IX_NPEDL_ECS_BG_CTXT_REG_2,    IX_NPEDL_ECS_BG_CTXT_REG_2_RESET},
222     {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET},
223     {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET},
224     {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET},
225     {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET},
226     {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET},
227     {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET},
228     {IX_NPEDL_ECS_DBG_CTXT_REG_0,   IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET},
229     {IX_NPEDL_ECS_DBG_CTXT_REG_1,   IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET},
230     {IX_NPEDL_ECS_DBG_CTXT_REG_2,   IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET},
231     {IX_NPEDL_ECS_INSTRUCT_REG,     IX_NPEDL_ECS_INSTRUCT_REG_RESET}
232 };
233
234 static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats;
235
236 /* Set when NPE register memory has been mapped */
237 static BOOL ixNpeDlMemInitialised = FALSE;
238
239
240 /*
241  * static function prototypes.
242  */
243 PRIVATE IX_STATUS
244 ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress,
245                       IxNpeDlNpeMgrCodeBlock *codeBlockPtr,
246                       BOOL verify, IxNpeDlNpeMemType npeMemType);
247 PRIVATE IX_STATUS
248 ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress,
249                             IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr,
250                             BOOL verify);
251 PRIVATE BOOL
252 ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset,
253                            UINT32 expectedBitsSet);
254
255 PRIVATE UINT32
256 ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId);
257
258 /*
259  * Function definition: ixNpeDlNpeMgrBaseAddressGet
260  */
261 PRIVATE UINT32
262 ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId)
263 {
264     IX_OSAL_ASSERT (ixNpeDlMemInitialised);
265     return ixNpeDlNpeInfo[npeId].baseAddress;
266 }
267
268
269 /*
270  * Function definition: ixNpeDlNpeMgrInit
271  */
272 void
273 ixNpeDlNpeMgrInit (void)
274 {
275     /* Only map the memory once */
276     if (!ixNpeDlMemInitialised)
277     {
278         UINT32 virtAddr;
279
280         /* map the register memory for NPE-A */
281         virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA,
282                                             IX_OSAL_IXP400_NPEA_MAP_SIZE); 
283         IX_OSAL_ASSERT(virtAddr);
284         ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr;
285
286         /* map the register memory for NPE-B */
287         virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB,
288                                             IX_OSAL_IXP400_NPEB_MAP_SIZE); 
289         IX_OSAL_ASSERT(virtAddr);
290         ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr;
291
292         /* map the register memory for NPE-C */
293         virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC,
294                                             IX_OSAL_IXP400_NPEC_MAP_SIZE); 
295         IX_OSAL_ASSERT(virtAddr);
296         ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr;
297
298         ixNpeDlMemInitialised = TRUE;
299     }
300 }
301
302
303 /*
304  * Function definition: ixNpeDlNpeMgrUninit
305  */
306 IX_STATUS
307 ixNpeDlNpeMgrUninit (void)
308 {
309     if (!ixNpeDlMemInitialised)
310     {
311         return IX_FAIL;
312     }
313
314     IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress);
315     IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress);
316     IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress);
317
318     ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0;
319     ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0;
320     ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0;
321
322     ixNpeDlMemInitialised = FALSE;
323
324     return IX_SUCCESS;
325 }
326
327 /*
328  * Function definition: ixNpeDlNpeMgrImageLoad
329  */
330 IX_STATUS
331 ixNpeDlNpeMgrImageLoad (
332     IxNpeDlNpeId npeId,
333     UINT32 *imageCodePtr,
334     BOOL verify)
335 {
336     UINT32 npeBaseAddress;
337     IxNpeDlNpeMgrDownloadMap *downloadMap;
338     UINT32 *blockPtr;
339     UINT32 mapIndex = 0;
340     IX_STATUS status = IX_SUCCESS;
341     
342     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
343                      "Entering ixNpeDlNpeMgrImageLoad\n");
344
345     /* get base memory address of NPE from npeId */
346     npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
347
348     /* check execution status of NPE to verify NPE Stop was successful */
349     if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
350                                     IX_NPEDL_EXCTL_STATUS_STOP))
351     {
352         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - "
353                                "NPE was not stopped before download\n");
354         status = IX_FAIL;
355     }
356     else
357     {
358         /*
359          * Read Download Map, checking each block type and calling
360          * appropriate function to perform download 
361          */
362         downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr;
363         while ((downloadMap->entry[mapIndex].eodmMarker != 
364                 IX_NPEDL_END_OF_DOWNLOAD_MAP)
365                && (status == IX_SUCCESS))
366         {
367             /* calculate pointer to block to be downloaded */
368             blockPtr = imageCodePtr +
369                 downloadMap->entry[mapIndex].block.offset;
370
371             switch (downloadMap->entry[mapIndex].block.type)
372             {
373             case IX_NPEDL_BLOCK_TYPE_INSTRUCTION:
374                 status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, 
375                                              (IxNpeDlNpeMgrCodeBlock *)blockPtr,
376                                                verify,
377                                                IX_NPEDL_MEM_TYPE_INSTRUCTION);
378                 break;
379             case IX_NPEDL_BLOCK_TYPE_DATA:
380                 status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
381                                              (IxNpeDlNpeMgrCodeBlock *)blockPtr,
382                                                verify, IX_NPEDL_MEM_TYPE_DATA);
383                 break;
384             case IX_NPEDL_BLOCK_TYPE_STATE:
385                 status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress,
386                                        (IxNpeDlNpeMgrStateInfoBlock *) blockPtr,
387                                                      verify);
388                 break;
389             default:
390                 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: "
391                                        "unknown block type in download map\n");
392                 status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
393                 ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
394                 break;
395             }
396             mapIndex++;
397         }/* loop: for each entry in download map, while status == SUCCESS */
398     }/* condition: NPE stopped before attempting download */
399     
400     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
401                      "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n",
402                      status);
403     return status;
404 }
405
406
407 /*
408  * Function definition: ixNpeDlNpeMgrMemLoad
409  */
410 PRIVATE IX_STATUS
411 ixNpeDlNpeMgrMemLoad (
412     IxNpeDlNpeId npeId,
413     UINT32 npeBaseAddress,
414     IxNpeDlNpeMgrCodeBlock *blockPtr,
415     BOOL verify,
416     IxNpeDlNpeMemType npeMemType)
417 {
418     UINT32 npeMemAddress;
419     UINT32 blockSize;
420     UINT32 memSize = 0;
421     IxNpeDlNpeMgrMemWrite memWriteFunc = NULL;
422     UINT32 localIndex = 0;
423     IX_STATUS status = IX_SUCCESS;
424
425     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
426                      "Entering ixNpeDlNpeMgrMemLoad\n");
427     
428     /*
429      * select NPE EXCTL reg read/write commands depending on memory
430      * type (instruction/data) to be accessed
431      */
432     if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
433     {
434         memSize = ixNpeDlNpeInfo[npeId].insMemSize;
435         memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite;
436     }
437     else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
438     {
439         memSize = ixNpeDlNpeInfo[npeId].dataMemSize;
440         memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite;
441     }
442
443     /*
444      * NPE memory is loaded contiguously from each block, so only address
445      * of 1st word in block is needed
446      */
447     npeMemAddress = blockPtr->npeMemAddress;
448     /* number of words of instruction/data microcode in block to download */
449     blockSize = blockPtr->size;
450     if ((npeMemAddress + blockSize) > memSize)
451     {
452         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
453                                "Block size too big for NPE memory\n");
454         status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
455         ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
456     }
457     else
458     {
459         for (localIndex = 0; localIndex < blockSize; localIndex++)
460         {
461             status = memWriteFunc (npeBaseAddress, npeMemAddress,
462                                    blockPtr->data[localIndex], verify);
463
464             if (status != IX_SUCCESS)
465             {
466                 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
467                                        "write to NPE memory failed\n");
468                 status = IX_NPEDL_CRITICAL_NPE_ERR;
469                 ixNpeDlNpeMgrStats.criticalNpeErrors++;
470                 break;   /* abort download */
471             }
472             /* increment target (word)address in NPE memory */
473             npeMemAddress++;   
474         }
475     }/* condition: block size will fit in NPE memory */
476
477     if (status == IX_SUCCESS)
478     {
479         if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
480         {
481             ixNpeDlNpeMgrStats.instructionBlocksLoaded++;
482         }
483         else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
484         {
485             ixNpeDlNpeMgrStats.dataBlocksLoaded++;
486         }
487     }
488
489     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
490                      "Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status);
491     return status;
492 }
493
494
495 /*
496  * Function definition: ixNpeDlNpeMgrStateInfoLoad
497  */
498 PRIVATE IX_STATUS
499 ixNpeDlNpeMgrStateInfoLoad (
500     UINT32 npeBaseAddress,
501     IxNpeDlNpeMgrStateInfoBlock *blockPtr,
502     BOOL verify)
503 {
504     UINT32 blockSize;
505     UINT32 ctxtRegAddrInfo; 
506     UINT32 ctxtRegVal;
507     IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
508     UINT32 ctxtNum;            /* identifies Context number (0-16)   */
509     UINT32 i;
510     IX_STATUS status = IX_SUCCESS;
511
512     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
513                      "Entering ixNpeDlNpeMgrStateInfoLoad\n");
514
515     /* block size contains number of words of state-info in block */
516     blockSize = blockPtr->size;
517     
518     ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
519
520     /* for each state-info context register entry in block */
521     for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++)
522     {
523         /* each state-info entry is 2 words (address, value) in length */
524         ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo;
525         ctxtRegVal      = (blockPtr->ctxtRegEntry[i]).value;
526         
527         ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG);
528         ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >> 
529             IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM;
530         
531         /* error-check Context Register No. and Context Number values  */
532         /* NOTE that there is no STEVT register for Context 0 */
533         if ((ctxtReg < 0) ||
534             (ctxtReg >= IX_NPEDL_CTXT_REG_MAX) ||
535             (ctxtNum > IX_NPEDL_CTXT_NUM_MAX) ||
536             ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
537         {
538             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
539                                    "invalid Context Register Address\n");
540             status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
541             ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
542             break;   /* abort download */
543         }    
544         
545         status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg,
546                                             ctxtRegVal, verify);
547         if (status != IX_SUCCESS)
548         {
549             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
550                                    "write of state-info to NPE failed\n");
551             status = IX_NPEDL_CRITICAL_NPE_ERR;
552             ixNpeDlNpeMgrStats.criticalNpeErrors++;
553             break;   /* abort download */
554         }
555     }/* loop: for each context reg entry in State Info block */
556     
557     ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
558
559     if (status == IX_SUCCESS)
560     {
561         ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++;
562     }
563
564     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
565                      "Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n",
566                      status);
567     return status;
568 }
569
570
571 /*
572  * Function definition: ixNpeDlNpeMgrNpeReset
573  */
574 IX_STATUS
575 ixNpeDlNpeMgrNpeReset (
576     IxNpeDlNpeId npeId)
577 {
578     UINT32 npeBaseAddress;
579     IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
580     UINT32 ctxtNum;            /* identifies Context number (0-16)   */
581     UINT32 regAddr;
582     UINT32 regVal;
583     UINT32 localIndex;
584     UINT32 indexMax;
585     IX_STATUS status = IX_SUCCESS;
586     IxFeatureCtrlReg unitFuseReg;
587     UINT32 ixNpeConfigCtrlRegVal;
588     
589     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
590                      "Entering ixNpeDlNpeMgrNpeReset\n");
591     
592     /* get base memory address of NPE from npeId */
593     npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
594
595     /* pre-store the NPE Config Control Register Value */
596     IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal);
597     
598     ixNpeConfigCtrlRegVal |= 0x3F000000;
599     
600     /* disable the parity interrupt */
601     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
602     
603     ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
604
605     /*
606      * clear the FIFOs
607      */
608     while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
609                                       IX_NPEDL_REG_OFFSET_WFIFO,
610                                       IX_NPEDL_MASK_WFIFO_VALID))
611     {
612         /* read from the Watch-point FIFO until empty */
613         IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO,
614                            &regVal);
615     }
616     
617     while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
618                                           IX_NPEDL_REG_OFFSET_STAT,
619                                       IX_NPEDL_MASK_STAT_OFNE))
620     {
621         /* read from the outFIFO until empty */
622         IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO,
623                            &regVal);
624     }
625     
626     while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
627                                       IX_NPEDL_REG_OFFSET_STAT,
628                                       IX_NPEDL_MASK_STAT_IFNE))
629     {
630         /*
631          * step execution of the NPE intruction to read inFIFO using
632          * the Debug Executing Context stack
633          */
634         status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
635                                            IX_NPEDL_INSTR_RD_FIFO, 0, 0);
636
637     if (IX_SUCCESS != status)
638     {
639         return status;   
640     }
641     
642     }
643     
644     /*
645      * Reset the mailbox reg
646      */
647     /* ...from XScale side */
648     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST,
649                         IX_NPEDL_REG_RESET_MBST);
650     /* ...from NPE side */
651     status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
652                                        IX_NPEDL_INSTR_RESET_MBOX, 0, 0);
653
654     if (IX_SUCCESS != status)
655     {
656         return status;   
657     }
658
659     /* 
660      *   Reset the physical registers in the NPE register file:
661      *   Note: no need to save/restore REGMAP for Context 0 here
662      *   since all Context Store regs are reset in subsequent code
663      */
664     for (regAddr = 0;
665          (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL);
666          regAddr++)
667     {
668         /* for each physical register in the NPE reg file, write 0 : */
669         status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr,
670                                                 0, TRUE);
671         if (status != IX_SUCCESS)
672         {
673             return status;  /* abort reset */
674         }
675     }
676     
677
678     /*
679      * Reset the context store:
680      */
681     for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN;
682          ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++)
683     {   
684         /* set each context's Context Store registers to reset values: */
685         for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++)
686         {
687             /* NOTE that there is no STEVT register for Context 0 */
688             if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
689             { 
690                 regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
691                 status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum,
692                                                     ctxtReg, regVal, TRUE);
693                 if (status != IX_SUCCESS)
694                 {
695                     return status;  /* abort reset */
696                 }
697             }
698         }
699     }
700
701     ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
702
703     /* write Reset values to Execution Context Stack registers */
704     indexMax = sizeof (ixNpeDlEcsRegResetValues) /
705         sizeof (IxNpeDlEcsRegResetValue);
706     for (localIndex = 0; localIndex < indexMax; localIndex++)
707     {
708         regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr;
709         regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal;
710         ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal);
711     }
712     
713     /* clear the profile counter */
714     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, 
715                                IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
716     
717     /* clear registers EXCT, AP0, AP1, AP2 and AP3 */
718     for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
719              regAddr <= IX_NPEDL_REG_OFFSET_AP3;
720          regAddr += IX_NPEDL_BYTES_PER_WORD)
721     {
722         IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0);
723     }
724     
725     /* Reset the Watch-count register */
726     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0);
727     
728     /*
729      * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
730      */
731
732     /*
733      * Call the feature control API to fused out and reset the NPE and its
734      * coprocessor - to reset internal states and remove parity error
735      */
736     unitFuseReg = ixFeatureCtrlRead ();
737     unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId);
738     ixFeatureCtrlWrite (unitFuseReg);
739
740     /* call the feature control API to un-fused and un-reset the NPE & COP */
741     unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId));
742     ixFeatureCtrlWrite (unitFuseReg);
743
744     /*
745      * Call NpeMgr function to stop the NPE again after the Feature Control
746      * has unfused and Un-Reset the NPE and its associated Coprocessors
747      */
748     status = ixNpeDlNpeMgrNpeStop (npeId);
749
750     /* restore NPE configuration bus Control Register - Parity Settings  */
751     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, 
752         (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));
753
754     ixNpeDlNpeMgrStats.npeResets++;
755
756     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
757                      "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status);
758     return status;
759 }
760
761
762 /*
763  * Function definition: ixNpeDlNpeMgrNpeStart
764  */
765 IX_STATUS
766 ixNpeDlNpeMgrNpeStart (
767     IxNpeDlNpeId npeId)
768 {
769     UINT32    npeBaseAddress;
770     UINT32    ecsRegVal;
771     BOOL      npeRunning;
772     IX_STATUS status = IX_SUCCESS;
773
774     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
775                      "Entering ixNpeDlNpeMgrNpeStart\n");
776
777     /* get base memory address of NPE from npeId */
778     npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
779
780     /*
781      * ensure only Background Context Stack Level is Active by turning off
782      * the Active bit in each of the other Executing Context Stack levels
783      */
784     ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
785                                              IX_NPEDL_ECS_PRI_1_CTXT_REG_0);
786     ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
787     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0,
788                                   ecsRegVal);
789
790     ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
791                                              IX_NPEDL_ECS_PRI_2_CTXT_REG_0);
792     ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
793     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0,
794                                   ecsRegVal);
795
796     ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
797                                              IX_NPEDL_ECS_DBG_CTXT_REG_0);
798     ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
799     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
800                                   ecsRegVal);
801     
802     /* clear the pipeline */
803     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
804     
805     /* start NPE execution by issuing command through EXCTL register on NPE */
806     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START);
807
808     /*
809      * check execution status of NPE to verify NPE Start operation was
810      * successful
811      */
812     npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
813                                             IX_NPEDL_REG_OFFSET_EXCTL,
814                                             IX_NPEDL_EXCTL_STATUS_RUN);
815     if (npeRunning)
816     {
817         ixNpeDlNpeMgrStats.npeStarts++;
818     }
819     else
820     {
821         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: "
822                                "failed to start NPE execution\n");
823         status = IX_FAIL;
824     }
825
826     
827     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
828                      "Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status);
829     return status;
830 }
831
832
833 /*
834  * Function definition: ixNpeDlNpeMgrNpeStop
835  */
836 IX_STATUS
837 ixNpeDlNpeMgrNpeStop (
838     IxNpeDlNpeId npeId)
839 {
840     UINT32    npeBaseAddress;
841     IX_STATUS status = IX_SUCCESS;
842     
843     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
844                      "Entering ixNpeDlNpeMgrNpeStop\n");
845     
846     /* get base memory address of NPE from npeId */
847     npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
848
849     /* stop NPE execution by issuing command through EXCTL register on NPE */
850     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP);
851
852     /* verify that NPE Stop was successful */
853     if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
854                                      IX_NPEDL_EXCTL_STATUS_STOP))
855     {
856         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: "
857                                "failed to stop NPE execution\n");
858         status = IX_FAIL;
859     }
860
861     ixNpeDlNpeMgrStats.npeStops++;
862     
863     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
864                      "Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status);
865     return status;
866 }
867
868
869 /*
870  * Function definition: ixNpeDlNpeMgrBitsSetCheck
871  */
872 PRIVATE BOOL
873 ixNpeDlNpeMgrBitsSetCheck (
874     UINT32 npeBaseAddress,
875     UINT32 regOffset,
876     UINT32 expectedBitsSet)
877 {
878     UINT32 regVal;
879     IX_NPEDL_REG_READ (npeBaseAddress, regOffset, &regVal);
880
881     return expectedBitsSet == (expectedBitsSet & regVal);
882 }
883
884
885 /*
886  * Function definition: ixNpeDlNpeMgrStatsShow
887  */
888 void
889 ixNpeDlNpeMgrStatsShow (void)
890 {
891     ixOsalLog (IX_OSAL_LOG_LVL_USER,
892                IX_OSAL_LOG_DEV_STDOUT,
893                "\nixNpeDlNpeMgrStatsShow:\n"
894                "\tInstruction Blocks loaded: %u\n"
895                "\tData Blocks loaded: %u\n"
896                "\tState Information Blocks loaded: %u\n"
897                "\tCritical NPE errors: %u\n"
898                "\tCritical Microcode errors: %u\n",
899                ixNpeDlNpeMgrStats.instructionBlocksLoaded,
900                ixNpeDlNpeMgrStats.dataBlocksLoaded,
901                ixNpeDlNpeMgrStats.stateInfoBlocksLoaded,
902                ixNpeDlNpeMgrStats.criticalNpeErrors,
903                ixNpeDlNpeMgrStats.criticalMicrocodeErrors,
904                0);
905
906     ixOsalLog (IX_OSAL_LOG_LVL_USER,
907                IX_OSAL_LOG_DEV_STDOUT,
908                "\tSuccessful NPE Starts: %u\n"
909                "\tSuccessful NPE Stops: %u\n"
910                "\tSuccessful NPE Resets: %u\n\n",
911                ixNpeDlNpeMgrStats.npeStarts,
912                ixNpeDlNpeMgrStats.npeStops,
913                ixNpeDlNpeMgrStats.npeResets,
914                0,0,0);
915
916     ixNpeDlNpeMgrUtilsStatsShow ();
917 }
918
919
920 /*
921  * Function definition: ixNpeDlNpeMgrStatsReset
922  */
923 void
924 ixNpeDlNpeMgrStatsReset (void)
925 {
926     ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0;
927     ixNpeDlNpeMgrStats.dataBlocksLoaded = 0;
928     ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0;
929     ixNpeDlNpeMgrStats.criticalNpeErrors = 0;
930     ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0;
931     ixNpeDlNpeMgrStats.npeStarts = 0;
932     ixNpeDlNpeMgrStats.npeStops = 0;
933     ixNpeDlNpeMgrStats.npeResets = 0;
934
935     ixNpeDlNpeMgrUtilsStatsReset ();
936 }