Annotation of qemu/roms/SLOF/board-js2x/llfw/u4mem.c, revision 1.1

1.1     ! root        1: /******************************************************************************
        !             2:  * Copyright (c) 2004, 2008 IBM Corporation
        !             3:  * All rights reserved.
        !             4:  * This program and the accompanying materials
        !             5:  * are made available under the terms of the BSD License
        !             6:  * which accompanies this distribution, and is available at
        !             7:  * http://www.opensource.org/licenses/bsd-license.php
        !             8:  *
        !             9:  * Contributors:
        !            10:  *     IBM Corporation - initial implementation
        !            11:  *****************************************************************************/
        !            12: #include <stdint.h>
        !            13: #include <hw.h>
        !            14: #include <stdio.h>
        !            15: #include "stage2.h"
        !            16: #include <cpu.h>
        !            17: #include <string.h>
        !            18: 
        !            19: /*
        !            20:  * compiler switches
        !            21:  *******************************************************************************
        !            22:  */
        !            23: #define U4_DEBUG
        !            24: #define U4_INFO
        !            25: //#define U4_SHOW_REGS
        !            26: 
        !            27: int io_getchar(char *);
        !            28: 
        !            29: /*
        !            30:  * version info
        !            31:  */
        !            32: static const uint32_t VER    = 2;
        !            33: static const uint32_t SUBVER = 1;
        !            34: 
        !            35: /*
        !            36:  * local macros
        !            37:  *******************************************************************************
        !            38:  */
        !            39: // bit shifting in Motorola/IBM bit enumeration format (yaks...)
        !            40: #define IBIT( nr )             ( (uint32_t) 0x80000000 >> (nr) )
        !            41: #define BIT( nr )              ( (uint32_t) 0x1 << (nr) )
        !            42: 
        !            43: /*
        !            44:  * macros to detect the current board layout
        !            45:  */
        !            46: #define IS_MAUI                ( ( load8_ci( 0xf4000682 ) >> 4 ) == 0 )
        !            47: #define IS_BIMINI              ( ( load8_ci( 0xf4000682 ) >> 4 ) == 1 )
        !            48: #define IS_KAUAI               ( ( load8_ci( 0xf4000682 ) >> 4 ) == 2 )
        !            49: 
        !            50: /*
        !            51:  * local constants
        !            52:  *******************************************************************************
        !            53:  */
        !            54: 
        !            55: /*
        !            56:  * u4 base address
        !            57:  */
        !            58: #define U4_BASE_ADDR           ((uint64_t) 0xf8000000 )
        !            59: #define u4reg( reg )           (U4_BASE_ADDR + (uint64_t) (reg))
        !            60: 
        !            61: /*
        !            62:  * I2C registers
        !            63:  */
        !            64: #define I2C_MODE_R             u4reg(0x1000)
        !            65: #define I2C_CTRL_R             u4reg(0x1010)
        !            66: #define I2C_STAT_R             u4reg(0x1020)
        !            67: #define I2C_ISR_R              u4reg(0x1030)
        !            68: #define I2C_ADDR_R             u4reg(0x1050)
        !            69: #define I2C_SUBA_R             u4reg(0x1060)
        !            70: #define I2C_DATA_R             u4reg(0x1070)
        !            71: 
        !            72: /*
        !            73:  * clock control registers & needed bits/masks
        !            74:  */
        !            75: #define ClkCntl_R              u4reg(0x0800)
        !            76: #define PLL2Cntl_R             u4reg(0x0860)
        !            77: 
        !            78: /*
        !            79:  * clock control bits & masks
        !            80:  */
        !            81: #define CLK_DDR_CLK_MSK                (IBIT(11) | IBIT(12) | IBIT(13))
        !            82: 
        !            83: /*
        !            84:  * memory controler registers
        !            85:  */
        !            86: #define RASTimer0_R            u4reg(0x2030)
        !            87: #define RASTimer1_R            u4reg(0x2040)
        !            88: #define CASTimer0_R            u4reg(0x2050)
        !            89: #define CASTimer1_R            u4reg(0x2060)
        !            90: #define MemRfshCntl_R          u4reg(0x2070)
        !            91: #define MemProgCntl_R          u4reg(0x20b0)
        !            92: #define Dm0Cnfg_R              u4reg(0x2200)
        !            93: #define Dm1Cnfg_R              u4reg(0x2210)
        !            94: #define Dm2Cnfg_R              u4reg(0x2220)
        !            95: #define Dm3Cnfg_R              u4reg(0x2230)
        !            96: #define MemWrQCnfg_R           u4reg(0x2270)
        !            97: #define MemArbWt_R             u4reg(0x2280)
        !            98: #define UsrCnfg_R              u4reg(0x2290)
        !            99: #define MemRdQCnfg_R           u4reg(0x22a0)
        !           100: #define MemQArb_R              u4reg(0x22b0)
        !           101: #define MemRWArb_R             u4reg(0x22c0)
        !           102: #define MemBusCnfg_R           u4reg(0x22d0)
        !           103: #define MemBusCnfg2_R          u4reg(0x22e0)
        !           104: #define ODTCntl_R              u4reg(0x23a0)
        !           105: #define MemModeCntl_R          u4reg(0x2500)
        !           106: #define MemPhyModeCntl_R       u4reg(0x2880)
        !           107: #define CKDelayL_R             u4reg(0x2890)
        !           108: #define CKDelayU_R             u4reg(0x28a0)
        !           109: #define IOPadCntl_R            u4reg(0x29a0)
        !           110: #define ByteWrClkDelC0B00_R    u4reg(0x2800)
        !           111: #define ByteWrClkDelC0B01_R    u4reg(0x2810)
        !           112: #define ByteWrClkDelC0B02_R    u4reg(0x2820)
        !           113: #define ByteWrClkDelC0B03_R    u4reg(0x2830)
        !           114: #define ByteWrClkDelC0B04_R    u4reg(0x2900)
        !           115: #define ByteWrClkDelC0B05_R    u4reg(0x2910)
        !           116: #define ByteWrClkDelC0B06_R    u4reg(0x2920)
        !           117: #define ByteWrClkDelC0B07_R    u4reg(0x2930)
        !           118: #define ByteWrClkDelC0B16_R    u4reg(0x2980)
        !           119: #define ByteWrClkDelC0B08_R    u4reg(0x2a00)
        !           120: #define ByteWrClkDelC0B09_R    u4reg(0x2a10)
        !           121: #define ByteWrClkDelC0B10_R    u4reg(0x2a20)
        !           122: #define ByteWrClkDelC0B11_R    u4reg(0x2a30)
        !           123: #define ByteWrClkDelC0B12_R    u4reg(0x2b00)
        !           124: #define ByteWrClkDelC0B13_R    u4reg(0x2b10)
        !           125: #define ByteWrClkDelC0B14_R    u4reg(0x2b20)
        !           126: #define ByteWrClkDelC0B15_R    u4reg(0x2b30)
        !           127: #define ByteWrClkDelC0B17_R    u4reg(0x2b80)
        !           128: #define ReadStrobeDelC0B00_R   u4reg(0x2840)
        !           129: #define ReadStrobeDelC0B01_R   u4reg(0x2850)
        !           130: #define ReadStrobeDelC0B02_R   u4reg(0x2860)
        !           131: #define ReadStrobeDelC0B03_R   u4reg(0x2870)
        !           132: #define ReadStrobeDelC0B04_R   u4reg(0x2940)
        !           133: #define ReadStrobeDelC0B05_R   u4reg(0x2950)
        !           134: #define ReadStrobeDelC0B06_R   u4reg(0x2960)
        !           135: #define ReadStrobeDelC0B07_R   u4reg(0x2970)
        !           136: #define ReadStrobeDelC0B16_R   u4reg(0x2990)
        !           137: #define ReadStrobeDelC0B08_R   u4reg(0x2a40)
        !           138: #define ReadStrobeDelC0B09_R   u4reg(0x2a50)
        !           139: #define ReadStrobeDelC0B10_R   u4reg(0x2a60)
        !           140: #define ReadStrobeDelC0B11_R   u4reg(0x2a70)
        !           141: #define ReadStrobeDelC0B12_R   u4reg(0x2b40)
        !           142: #define ReadStrobeDelC0B13_R   u4reg(0x2b50)
        !           143: #define ReadStrobeDelC0B14_R   u4reg(0x2b60)
        !           144: #define ReadStrobeDelC0B15_R   u4reg(0x2b70)
        !           145: #define ReadStrobeDelC0B17_R   u4reg(0x2b90)
        !           146: #define MemInit00_R            u4reg(0x2100)
        !           147: #define MemInit01_R            u4reg(0x2110)
        !           148: #define MemInit02_R            u4reg(0x2120)
        !           149: #define MemInit03_R            u4reg(0x2130)
        !           150: #define MemInit04_R            u4reg(0x2140)
        !           151: #define MemInit05_R            u4reg(0x2150)
        !           152: #define MemInit06_R            u4reg(0x2160)
        !           153: #define MemInit07_R            u4reg(0x2170)
        !           154: #define MemInit08_R            u4reg(0x2180)
        !           155: #define MemInit09_R            u4reg(0x2190)
        !           156: #define MemInit10_R            u4reg(0x21a0)
        !           157: #define MemInit11_R            u4reg(0x21b0)
        !           158: #define MemInit12_R            u4reg(0x21c0)
        !           159: #define MemInit13_R            u4reg(0x21d0)
        !           160: #define MemInit14_R            u4reg(0x21e0)
        !           161: #define MemInit15_R            u4reg(0x21f0)
        !           162: #define CalConf0_R             u4reg(0x29b0)
        !           163: #define CalConf1_R             u4reg(0x29c0)
        !           164: #define MeasStatusC0_R         u4reg(0x28f0)
        !           165: #define MeasStatusC1_R         u4reg(0x29f0)
        !           166: #define MeasStatusC2_R         u4reg(0x2af0)
        !           167: #define MeasStatusC3_R         u4reg(0x2bf0)
        !           168: #define CalC0_R                        u4reg(0x28e0)
        !           169: #define CalC1_R                        u4reg(0x29e0)
        !           170: #define CalC2_R                        u4reg(0x2ae0)
        !           171: #define CalC3_R                        u4reg(0x2be0)
        !           172: #define RstLdEnVerniersC0_R    u4reg(0x28d0)
        !           173: #define RstLdEnVerniersC1_R    u4reg(0x29d0)
        !           174: #define RstLdEnVerniersC2_R    u4reg(0x2ad0)
        !           175: #define RstLdEnVerniersC3_R    u4reg(0x2bd0)
        !           176: #define ExtMuxVernier0_R       u4reg(0x28b0)
        !           177: #define ExtMuxVernier1_R       u4reg(0x28c0)
        !           178: #define OCDCalCmd_R            u4reg(0x2300)
        !           179: #define OCDCalCntl_R           u4reg(0x2310)
        !           180: #define MCCR_R                 u4reg(0x2440)
        !           181: #define MSRSR_R                u4reg(0x2410)
        !           182: #define MSRER_R                u4reg(0x2420)
        !           183: #define MSPR_R                 u4reg(0x2430)
        !           184: #define MSCR_R                 u4reg(0x2400)
        !           185: #define MEAR0_R                        u4reg(0x2460)
        !           186: #define MEAR1_R                        u4reg(0x2470)
        !           187: #define MESR_R                 u4reg(0x2480)
        !           188: #define MRSRegCntl_R           u4reg(0x20c0)
        !           189: #define EMRSRegCntl_R          u4reg(0x20d0)
        !           190: #define APIMemRdCfg_R          u4reg(0x30090)
        !           191: #define APIExcp_R              u4reg(0x300a0)
        !           192: 
        !           193: /*
        !           194:  * common return values
        !           195:  */
        !           196: #define RET_OK                  0
        !           197: #define RET_ERR                        -1
        !           198: #define RET_ACERR_CE           -1
        !           199: #define RET_ACERR_UEWT         -2
        !           200: #define RET_ACERR_UE           -3
        !           201: 
        !           202: /*
        !           203:  * 'DIMM slot populated' indicator
        !           204:  */
        !           205: #define SL_POP                 1
        !           206: 
        !           207: /*
        !           208:  * spd buffer size
        !           209:  */
        !           210: #define SPD_BUF_SIZE           0x40
        !           211: 
        !           212: /*
        !           213:  * maximum number of DIMM banks & DIMM groups
        !           214:  */
        !           215: #define NUM_SLOTS              8
        !           216: #define NUM_BANKS              ( NUM_SLOTS / 2 )
        !           217: #define MAX_DGROUPS            ( NUM_SLOTS / 2 )
        !           218: #define SLOT_ADJ()             ( ( IS_MAUI ) ? NUM_SLOTS / 4 : NUM_SLOTS / 2 )
        !           219: 
        !           220: /*
        !           221:  * values needed for auto calibration
        !           222:  */
        !           223: #define MAX_DRANKS             NUM_SLOTS
        !           224: #define MAX_BLANE              18
        !           225: #define MAX_RMD                        0xf
        !           226: 
        !           227: /*
        !           228:  * maximum number of supported CAS latencies
        !           229:  */
        !           230: #define NUM_CL                 3
        !           231: 
        !           232: /*
        !           233:  * min/max supported CL values by U4
        !           234:  */
        !           235: #define U4_MIN_CL              3
        !           236: #define U4_MAX_CL              5
        !           237: 
        !           238: /*
        !           239:  * DIMM constants
        !           240:  */
        !           241: #define DIMM_TYPE_MSK          BIT(0)
        !           242: #define DIMM_ORG_x4            BIT(0)
        !           243: #define DIMM_ORG_x8            BIT(1)
        !           244: #define DIMM_ORG_x16           BIT(2)
        !           245: #define DIMM_ORG_MIXx8x16      BIT(30)
        !           246: #define DIMM_ORG_UNKNOWN       0
        !           247: #define DIMM_WIDTH             72
        !           248: #define DIMM_BURSTLEN_4                BIT(2)
        !           249: 
        !           250: /*
        !           251:  * L2 cache size
        !           252:  */
        !           253: #define L2_CACHE_SIZE          (uint32_t) 0x100000
        !           254: 
        !           255: /*
        !           256:  * scrub types
        !           257:  */
        !           258: #define        IMMEDIATE_SCRUB                 IBIT(0)
        !           259: #define        IMMEDIATE_SCRUB_WITH_FILL       ( IBIT(0) | IBIT(1) )
        !           260: #define        BACKGROUND_SCRUB                ( IBIT(1) | ( 0x29 << 16 ) )
        !           261: 
        !           262: /*
        !           263:  * I2C starting slave addresses of the DIMM banks
        !           264:  */
        !           265: #define I2C_START              0x50
        !           266: 
        !           267: /*
        !           268:  * Index to the speed dependend DIMM settings
        !           269:  */
        !           270: enum
        !           271: {
        !           272:        SPEED_IDX_400 = 0,
        !           273:        SPEED_IDX_533,
        !           274:        SPEED_IDX_667,
        !           275:        NUM_SPEED_IDX
        !           276: };
        !           277: 
        !           278: /*
        !           279:  * number of read/write strobes of the U4
        !           280:  */
        !           281: #define NUM_STROBES            18
        !           282: 
        !           283: /*
        !           284:  * 2GB hole definition
        !           285:  */
        !           286: static const uint64_t _2GB = (uint64_t) 0x80000000;
        !           287: 
        !           288: /*
        !           289:  * local types
        !           290:  *******************************************************************************
        !           291:  */
        !           292: /*
        !           293:  * DIMM definition
        !           294:  */
        !           295: typedef struct
        !           296: {
        !           297:        uint32_t m_pop_u32;             // set if bank is populated
        !           298:        uint32_t m_bank_u32;            // bank number
        !           299:        uint32_t m_clmsk_u32;           // mask of supported CAS latencies
        !           300:        uint32_t m_clcnt_u32;           // number of supporetd CAS latencies
        !           301:        uint32_t m_clval_pu32[NUM_CL];  // values of supporeted CAS latencies
        !           302:        uint32_t m_speed_pu32[NUM_CL];  // speed (Mhz) at CAS latency of same index
        !           303:        uint32_t m_size_u32;            // chip size in Mb
        !           304:        uint32_t m_rank_u32;            // # of ranks, total size = chip size*rank
        !           305:        uint32_t m_orgmsk_u32;          // data organisation (x4, x8, x16) (mask)
        !           306:        uint32_t m_orgval_u32;          // data organisation (value)
        !           307:        uint32_t m_width_u32;           // data width
        !           308:        uint32_t m_ecc_u32;             // set if ecc
        !           309:        uint32_t m_type_u32;            // rdimm or udimm
        !           310:        uint32_t m_burst_u32;           // supported burst lengths
        !           311:        uint32_t m_bankcnt_u32;         // number of banks
        !           312: 
        !           313:        /*
        !           314:         * the following timing values are all in 1/100ns
        !           315:         */
        !           316:        uint32_t m_tCK_pu32[NUM_CL];
        !           317:        uint32_t m_tRAS_u32;
        !           318:        uint32_t m_tRTP_u32;
        !           319:        uint32_t m_tRP_u32;
        !           320:        uint32_t m_tWR_u32;
        !           321:        uint32_t m_tRRD_u32;
        !           322:        uint32_t m_tRC_u32;
        !           323:        uint32_t m_tRCD_u32;
        !           324:        uint32_t m_tWTR_u32;
        !           325:        uint32_t m_tREF_u32;
        !           326:        uint32_t m_tRFC_u32;
        !           327: }      dimm_t;
        !           328: 
        !           329: /*
        !           330:  * DIMM group definition
        !           331:  */
        !           332: typedef struct
        !           333: {
        !           334:        uint32_t  m_size_u32;           // group size in MB
        !           335:        uint32_t  m_start_u32;          // in 128Mb granularity
        !           336:        uint32_t  m_end_u32;            // in 128Mb granularity
        !           337:        uint32_t  m_ss_u32;             // single sided/double sided
        !           338:        uint32_t  m_csmode_u32;         // selected CS mode for this group
        !           339:        uint32_t  m_add2g_u32;
        !           340:        uint32_t  m_sub2g_u32;
        !           341:        uint32_t  m_memmd_u32;          // selected mem mode for this group
        !           342:        uint32_t  m_dcnt_u32;           // number of DIMMs in group
        !           343:        dimm_t   *m_dptr[NUM_SLOTS];
        !           344: }      dgroup_t;
        !           345: 
        !           346: /*
        !           347:  * auto calibration result structure
        !           348:  */
        !           349: typedef struct
        !           350: {
        !           351:        uint32_t m_MemBusCnfg_u32;
        !           352:        uint32_t m_MemBusCnfg2_u32;
        !           353:        uint32_t m_RstLdEnVerniers_pu32[4];
        !           354: }      auto_calib_t;
        !           355: 
        !           356: /*
        !           357:  * ECC error structure
        !           358:  */
        !           359: typedef struct
        !           360: {
        !           361:        int32_t  m_err_i32;
        !           362:        uint32_t m_uecnt_u32;           // number of uncorrectable errors
        !           363:        uint32_t m_cecnt_u32;           // number of correctable errors
        !           364:        uint32_t m_rank_u32;            // erroneous rank
        !           365:        uint32_t m_col_u32;             // erroneous column
        !           366:        uint32_t m_row_u32;             // erroneous row
        !           367:        uint32_t m_bank_u32;            // erroneous bank
        !           368: }      eccerror_t;
        !           369: 
        !           370: /*
        !           371:  * U4 register setup structure
        !           372:  */
        !           373: typedef struct
        !           374: {
        !           375:        /*
        !           376:         * external MUX delays
        !           377:         */
        !           378:        uint32_t RRMux;
        !           379:        uint32_t WRMux;
        !           380:        uint32_t WWMux;
        !           381:        uint32_t RWMux;
        !           382: 
        !           383:        /*
        !           384:         * default Wr/Rd Queue & Arbiter register settings
        !           385:         */
        !           386:        uint32_t MemRdQCnfg;
        !           387:        uint32_t MemWrQCnfg;
        !           388:        uint32_t MemQArb;
        !           389:        uint32_t MemRWArb;
        !           390: 
        !           391:        /*
        !           392:         * misc fixed register values
        !           393:         */
        !           394:        uint32_t ODTCntl;
        !           395:        uint32_t IOPadCntl;
        !           396:        uint32_t MemPhyModeCntl;
        !           397:        uint32_t OCDCalCntl;
        !           398:        uint32_t OCDCalCmd;
        !           399:        uint32_t CKDelayL;
        !           400:        uint32_t CKDelayU;
        !           401:        uint32_t MemBusCnfg;
        !           402:        uint32_t CAS1Dly0;
        !           403:        uint32_t CAS1Dly1;
        !           404:        uint32_t ByteWrClkDel[NUM_STROBES];
        !           405:        uint32_t ReadStrobeDel[NUM_STROBES];
        !           406: } reg_statics_t;
        !           407: 
        !           408: /*
        !           409:  * local variables
        !           410:  *******************************************************************************
        !           411:  */
        !           412: static dimm_t   m_dimm[NUM_SLOTS];
        !           413: static dimm_t   m_gendimm;
        !           414: static uint32_t  m_dcnt_u32;
        !           415: static dimm_t   *m_dptr[NUM_SLOTS];
        !           416: static uint32_t  m_bankoff_u32;
        !           417: static uint32_t         m_bankpop_u32[NUM_BANKS];
        !           418: static uint32_t  m_dclidx_u32;
        !           419: static uint32_t  m_dgrcnt_u32;
        !           420: static dgroup_t  m_dgroup[MAX_DGROUPS];
        !           421: static dgroup_t *m_dgrptr[MAX_DGROUPS];
        !           422: static uint64_t  m_memsize_u64;        // memsize in bytes
        !           423: 
        !           424: /*
        !           425:  * local functions
        !           426:  *******************************************************************************
        !           427:  */
        !           428: static void
        !           429: progbar( void )
        !           430: {
        !           431:        static uint8_t  bar[] =
        !           432:                        { '|', '/', '-', '\\', 0 };
        !           433:        static uint32_t idx = 0;
        !           434: 
        !           435:        printf( "\b%c", bar[idx] );
        !           436: 
        !           437:        if( bar[++idx] == 0 ) {
        !           438:                idx = 0;
        !           439:        }
        !           440: 
        !           441: }
        !           442: 
        !           443: static void
        !           444: or32_ci( uint64_t r, uint32_t m )
        !           445: {
        !           446:        uint32_t v;
        !           447: 
        !           448:        v  = load32_ci( r );
        !           449:        v |= m;
        !           450:        store32_ci( r, v );
        !           451: }
        !           452: 
        !           453: static void
        !           454: and32_ci( uint64_t r, uint32_t m )
        !           455: {
        !           456:        uint32_t v;
        !           457: 
        !           458:        v  = load32_ci( r );
        !           459:        v &= m;
        !           460:        store32_ci( r, v );
        !           461: }
        !           462: 
        !           463: static void
        !           464: dly( uint64_t volatile f_wait_u64 ) \
        !           465: {
        !           466:        while( f_wait_u64 ) {
        !           467:                f_wait_u64--;
        !           468:        }
        !           469: }
        !           470: 
        !           471: /*
        !           472:  * local i2c access functions
        !           473:  */
        !           474: static void
        !           475: i2c_term( void )
        !           476: {
        !           477:        uint32_t l_stat_u32;
        !           478: 
        !           479:        /*
        !           480:         * clear out all pending int's and wait
        !           481:         * for the stop condition to occur
        !           482:         */
        !           483:        do {
        !           484:                l_stat_u32 = load32_ci( I2C_ISR_R );
        !           485:                store32_ci( I2C_ISR_R, l_stat_u32 );
        !           486:        } while( ( l_stat_u32 & IBIT(29) ) == 0 );
        !           487: 
        !           488: }
        !           489: 
        !           490: static int32_t
        !           491: i2c_read( uint32_t f_addr_u32, uint32_t f_suba_u32, uint8_t *f_buf_pu08, uint32_t f_len_u32 )
        !           492: {
        !           493:        uint32_t  l_val_u32;
        !           494:        int32_t   l_ret_i32 = 1;
        !           495: 
        !           496:        /*
        !           497:         * parameter check
        !           498:         */
        !           499:        if( ( f_addr_u32 > (uint32_t) 0x7f ) ||
        !           500:            ( f_suba_u32 > (uint32_t) 0xff ) ||
        !           501:            ( f_len_u32 == (uint32_t) 0x00 ) ) {
        !           502:                return RET_ERR;
        !           503:        }
        !           504: 
        !           505:        /*
        !           506:         * set I2C Interface to combined mode
        !           507:         */
        !           508:        store32_ci( I2C_MODE_R, IBIT(28) | IBIT(29) );
        !           509: 
        !           510:        /*
        !           511:         * set address, subaddress & read mode
        !           512:         */
        !           513:        store32_ci( I2C_ADDR_R, ( f_addr_u32 << 1 ) | (uint32_t) 0x1 );
        !           514:        store32_ci( I2C_SUBA_R, f_suba_u32 );
        !           515: 
        !           516:        /*
        !           517:         * start address transmission phase
        !           518:         */
        !           519:        store32_ci( I2C_CTRL_R, IBIT(30) );
        !           520: 
        !           521:        /*
        !           522:         * wait for address transmission to finish
        !           523:         */
        !           524:        do {
        !           525:                l_val_u32 = load32_ci( I2C_ISR_R );
        !           526:        } while( ( l_val_u32 & IBIT(30) ) == 0 );
        !           527: 
        !           528:        /*
        !           529:         * check for success
        !           530:         */
        !           531:        if( ( load32_ci( I2C_STAT_R ) & IBIT(30) ) == 0 ) {
        !           532:                i2c_term();
        !           533:                return RET_ERR;
        !           534:        } else {
        !           535:                // send ack
        !           536:                store32_ci( I2C_CTRL_R, IBIT(31) );
        !           537:                // clear int
        !           538:                store32_ci( I2C_ISR_R, IBIT(30) );
        !           539:        }
        !           540: 
        !           541:        /*
        !           542:         * read data
        !           543:         */
        !           544:        while( l_ret_i32 > 0 ) {
        !           545:                l_val_u32 = load32_ci( I2C_ISR_R );
        !           546: 
        !           547:                if( ( l_val_u32 & IBIT(31) ) != 0 ) {
        !           548:                        // data was received
        !           549:                        *f_buf_pu08 = ( uint8_t ) load32_ci( I2C_DATA_R );
        !           550: 
        !           551:                        f_buf_pu08++;
        !           552:                        f_len_u32--;
        !           553: 
        !           554:                        /*
        !           555:                         * continue when there is more data to read or
        !           556:                         * exit if not
        !           557:                         */
        !           558:                        if( f_len_u32 != 0 ) {
        !           559:                                // send ack
        !           560:                                store32_ci( I2C_CTRL_R, IBIT(31) );
        !           561:                                // clear int
        !           562:                                store32_ci( I2C_ISR_R, IBIT(31) );
        !           563:                        } else {
        !           564:                                // send nack
        !           565:                                store32_ci( I2C_CTRL_R, 0 );
        !           566:                                // set exit flag
        !           567:                                l_ret_i32 = RET_OK;
        !           568:                        }
        !           569: 
        !           570:                } else if( ( l_val_u32 & IBIT(29) ) != 0 ) {
        !           571:                        // early stop condition
        !           572:                        // set exit flag
        !           573:                        l_ret_i32 = RET_ERR;
        !           574:                }
        !           575: 
        !           576:        };
        !           577: 
        !           578:        i2c_term();
        !           579: 
        !           580:        return( l_ret_i32 );
        !           581: }
        !           582: 
        !           583: static uint32_t
        !           584: i2c_get_slot( uint32_t i2c_addr )
        !           585: {
        !           586:        uint32_t slot;
        !           587: 
        !           588:        slot = ( i2c_addr - I2C_START ) / 2;
        !           589: 
        !           590:        if( ( i2c_addr & 0x1 ) != 0 ) {
        !           591:                slot += SLOT_ADJ();
        !           592:        }
        !           593: 
        !           594:        return slot;
        !           595: }
        !           596: 
        !           597: /*
        !           598:  * 'serial presence detect' interpretation functions
        !           599:  */
        !           600: static uint32_t
        !           601: ddr2_get_dimm_rank( uint8_t *f_spd_pu08 )
        !           602: {
        !           603:        static const int RANK_IDX = (int) 5;
        !           604: 
        !           605:        return (uint32_t) ( f_spd_pu08[RANK_IDX] & 0x3 ) + 1;
        !           606: }
        !           607: 
        !           608: static uint32_t
        !           609: ddr2_get_dimm_size( uint8_t *f_spd_pu08 )
        !           610: {
        !           611:        static const int SIZE_IDX   = (int) 31;
        !           612:        uint8_t          l_smsk_u08;
        !           613:        uint32_t         i;
        !           614: 
        !           615:        l_smsk_u08 = ( f_spd_pu08[SIZE_IDX] << 3 ) |
        !           616:                     ( f_spd_pu08[SIZE_IDX] >> 5 );
        !           617: 
        !           618:        for( i = 0; ( ( l_smsk_u08 & ( (uint8_t) 0x1 << i ) ) == 0 ) ; i++ );
        !           619: 
        !           620:        return (uint32_t) 0x80 << i;
        !           621: }
        !           622: 
        !           623: static uint32_t
        !           624: ddr2_get_dimm_type( uint8_t *f_spd_pu08 )
        !           625: {
        !           626:        static const int TYPE_IDX = (int) 20;
        !           627: 
        !           628:        return (uint32_t) f_spd_pu08[TYPE_IDX] & DIMM_TYPE_MSK;
        !           629: }
        !           630: 
        !           631: static uint32_t
        !           632: ddr2_get_dimm_org( uint8_t *f_spd_pu08, uint32_t /*out*/ *f_omsk_pu32 )
        !           633: {
        !           634:        static const int ORG_IDX   = (int) 13;
        !           635:        uint32_t         l_ret_u32 = (uint32_t) f_spd_pu08[ORG_IDX];
        !           636: 
        !           637:        if( l_ret_u32 == 4 ) {
        !           638:                *f_omsk_pu32  = DIMM_ORG_x4;
        !           639:        } else if( l_ret_u32 == 8 ) {
        !           640:                *f_omsk_pu32  = DIMM_ORG_x8;
        !           641:                *f_omsk_pu32 |= DIMM_ORG_MIXx8x16;
        !           642:        } else if( l_ret_u32 == 16 ) {
        !           643:                *f_omsk_pu32  = DIMM_ORG_x16;
        !           644:                *f_omsk_pu32 |= DIMM_ORG_MIXx8x16;
        !           645:        } else {
        !           646:                *f_omsk_pu32  = DIMM_ORG_UNKNOWN;
        !           647:                 l_ret_u32    = (uint32_t) ~0;
        !           648:        }
        !           649: 
        !           650:        return l_ret_u32;
        !           651: }
        !           652: 
        !           653: static uint32_t
        !           654: ddr2_get_dimm_width( uint8_t *f_spd_pu08 )
        !           655: {
        !           656:        static const int WIDTH_IDX = (int) 6;
        !           657: 
        !           658:        return (uint32_t) f_spd_pu08[WIDTH_IDX];
        !           659: }
        !           660: 
        !           661: static uint32_t
        !           662: ddr2_get_dimm_ecc( uint8_t *f_spd_pu08 )
        !           663: {
        !           664:        static const int ECC_IDX = (int) 11;
        !           665: 
        !           666:        return ( f_spd_pu08[ECC_IDX] & BIT(1) ) != 0;
        !           667: }
        !           668: 
        !           669: static uint32_t
        !           670: ddr2_get_dimm_burstlen( uint8_t *f_spd_pu08 )
        !           671: {
        !           672:        static const int BURST_IDX = (int) 16;
        !           673: 
        !           674:        return (uint32_t) f_spd_pu08[BURST_IDX];
        !           675: }
        !           676: 
        !           677: static void
        !           678: ddr2_get_dimm_speed( dimm_t *f_dimm, uint8_t *f_spd_pu08 )
        !           679: {
        !           680:        static const int      SPEED_IDX[] = { 25, 23, 9 };
        !           681:        static const uint32_t NS[]        = { 25, 33, 66, 75 };
        !           682:        uint8_t               l_tmp_u08;
        !           683:        uint32_t              l_dspeed_u32;
        !           684:        uint32_t              idx = 0;
        !           685:        uint32_t              i;
        !           686: 
        !           687:        for( i = NUM_CL - f_dimm->m_clcnt_u32; i < NUM_CL; i++ ) {
        !           688:                l_tmp_u08     = f_spd_pu08[SPEED_IDX[i]];
        !           689:                l_dspeed_u32  = (uint32_t) ( l_tmp_u08 >> 4 ) * 100;
        !           690:                l_tmp_u08    &= (uint8_t) 0xf;
        !           691: 
        !           692:                if( l_tmp_u08 >= (uint8_t) 10 ) {
        !           693:                        l_dspeed_u32 += NS[l_tmp_u08 - 10];
        !           694:                } else {
        !           695:                        l_dspeed_u32 += (uint32_t) l_tmp_u08 * 10;
        !           696:                }
        !           697: 
        !           698:                f_dimm->m_tCK_pu32[idx]    = l_dspeed_u32;
        !           699:                f_dimm->m_speed_pu32[idx]  = (uint32_t) 2000000 / l_dspeed_u32;
        !           700:                f_dimm->m_speed_pu32[idx] += (uint32_t) 5;
        !           701:                f_dimm->m_speed_pu32[idx] /= (uint32_t) 10;
        !           702:                idx++;
        !           703:        }
        !           704: 
        !           705: }
        !           706: 
        !           707: static void
        !           708: ddr2_get_dimm_timings( dimm_t *f_dimm, uint8_t *f_spd_pu08 )
        !           709: {
        !           710:        static const uint32_t NS[]  = { 00, 25, 33, 50, 66, 75, 00, 00 };
        !           711:        static const uint32_t USMUL = (uint32_t) 390625;
        !           712:        static const int tREF_IDX   = (int) 12;
        !           713:        static const int tRP_IDX    = (int) 27;
        !           714:        static const int tRRD_IDX   = (int) 28;
        !           715:        static const int tRCD_IDX   = (int) 29;
        !           716:        static const int tRAS_IDX   = (int) 30;
        !           717:        static const int tWR_IDX    = (int) 36;
        !           718:        static const int tWTR_IDX   = (int) 37;
        !           719:        static const int tRTP_IDX   = (int) 38;
        !           720:        static const int tRC_IDX    = (int) 41; // & 40
        !           721:        static const int tRFC_IDX   = (int) 42; // & 40
        !           722: 
        !           723:        uint32_t         l_tmp_u32;
        !           724: 
        !           725:        f_dimm->m_tRP_u32  = (uint32_t) f_spd_pu08[tRP_IDX]  *  25;
        !           726:        f_dimm->m_tRRD_u32 = (uint32_t) f_spd_pu08[tRRD_IDX] *  25;
        !           727:        f_dimm->m_tRCD_u32 = (uint32_t) f_spd_pu08[tRCD_IDX] *  25;
        !           728:        f_dimm->m_tWR_u32  = (uint32_t) f_spd_pu08[tWR_IDX]  *  25;
        !           729:        f_dimm->m_tWTR_u32 = (uint32_t) f_spd_pu08[tWTR_IDX] *  25;
        !           730:        f_dimm->m_tRTP_u32 = (uint32_t) f_spd_pu08[tRTP_IDX] *  25;
        !           731:        f_dimm->m_tRAS_u32 = (uint32_t) f_spd_pu08[tRAS_IDX] * 100;
        !           732: 
        !           733:        l_tmp_u32          = (uint32_t) ( f_spd_pu08[tRC_IDX - 1] >> 4 );
        !           734:        l_tmp_u32         &= (uint32_t) 0x7;
        !           735:        f_dimm->m_tRC_u32  = (uint32_t) f_spd_pu08[tRC_IDX] * 100 +
        !           736:                                        NS[l_tmp_u32];
        !           737: 
        !           738:        l_tmp_u32           = (uint32_t) f_spd_pu08[tRFC_IDX - 2];
        !           739:        l_tmp_u32          &= (uint32_t) 0xf;
        !           740:        f_dimm->m_tRFC_u32  = (uint32_t) 256 * ( l_tmp_u32 & (uint32_t) 0x1 );
        !           741:        f_dimm->m_tRFC_u32 += (uint32_t) f_spd_pu08[tRFC_IDX];
        !           742:        f_dimm->m_tRFC_u32 *= 100;
        !           743:        l_tmp_u32         >>= 1;
        !           744:        f_dimm->m_tRFC_u32 += NS[l_tmp_u32];
        !           745: 
        !           746:        l_tmp_u32           = (uint32_t) f_spd_pu08[tREF_IDX];
        !           747:        l_tmp_u32          &= (uint32_t) 0x7f;
        !           748: 
        !           749:        if( l_tmp_u32 == 0 ) {
        !           750:                l_tmp_u32 = (uint32_t) 2;
        !           751:        } else if( l_tmp_u32 <= (uint32_t) 2 ) {
        !           752:                l_tmp_u32--;
        !           753:        }
        !           754: 
        !           755:        f_dimm->m_tREF_u32 = ( l_tmp_u32 + 1 ) * USMUL;
        !           756: }
        !           757: 
        !           758: static uint32_t
        !           759: ddr2_get_banks( uint8_t *f_spd_pu08 )
        !           760: {
        !           761:        static const int BANK_IDX = (int) 17;
        !           762: 
        !           763:        return (uint32_t) f_spd_pu08[BANK_IDX];
        !           764: }
        !           765: 
        !           766: static uint32_t
        !           767: ddr2_get_cl_mask( uint8_t *f_spd_pu08 )
        !           768: {
        !           769:        static const int CL_IDX = (int) 18;
        !           770: 
        !           771:        return (uint32_t) f_spd_pu08[CL_IDX];
        !           772: }
        !           773: 
        !           774: static void
        !           775: ddr2_get_cl( dimm_t *f_dimm )
        !           776: {
        !           777:        uint32_t l_clcnt_u32 = 0;
        !           778:        uint32_t i;
        !           779: 
        !           780:        for( i = 0; ( i < 8 ) && ( l_clcnt_u32 < NUM_CL ) ; i++ ) {
        !           781: 
        !           782:                if( ( f_dimm->m_clmsk_u32 & ( (uint32_t) 0x1 << i ) ) != 0 ) {
        !           783:                        f_dimm->m_clval_pu32[l_clcnt_u32] = i;
        !           784:                        l_clcnt_u32++;
        !           785:                }
        !           786: 
        !           787:        }
        !           788: 
        !           789:        f_dimm->m_clcnt_u32 = l_clcnt_u32;
        !           790: }
        !           791: 
        !           792: static uint32_t
        !           793: ddr2_cl2speed( dimm_t *f_dimm, uint32_t f_cl_u32, uint32_t *f_tCK_pu32 )
        !           794: {
        !           795:        uint32_t i;
        !           796: 
        !           797:        for(i = 0; (i < NUM_CL) && (f_dimm->m_clval_pu32[i] != f_cl_u32); i++);
        !           798: 
        !           799:        if( i == NUM_CL ) {
        !           800:                return (uint32_t) ~0;
        !           801:        }
        !           802: 
        !           803:        *f_tCK_pu32 = f_dimm->m_tCK_pu32[i];
        !           804: 
        !           805:        return f_dimm->m_speed_pu32[i];
        !           806: }
        !           807: 
        !           808: static void
        !           809: ddr2_setupDIMM( dimm_t *f_dimm, uint32_t f_bank_u32, uint8_t *f_spd_pu08 )
        !           810: {
        !           811:        f_dimm->m_pop_u32     = SL_POP;
        !           812:        f_dimm->m_bank_u32    = f_bank_u32;
        !           813:        f_dimm->m_size_u32    = ddr2_get_dimm_size( f_spd_pu08 );
        !           814:        f_dimm->m_rank_u32    = ddr2_get_dimm_rank( f_spd_pu08 );
        !           815:        f_dimm->m_type_u32    = ddr2_get_dimm_type( f_spd_pu08 );
        !           816:        f_dimm->m_orgval_u32  = ddr2_get_dimm_org( f_spd_pu08, &f_dimm->m_orgmsk_u32 );
        !           817:        f_dimm->m_width_u32   = ddr2_get_dimm_width( f_spd_pu08 );
        !           818:        f_dimm->m_ecc_u32     = ddr2_get_dimm_ecc( f_spd_pu08 );
        !           819:        f_dimm->m_burst_u32   = ddr2_get_dimm_burstlen( f_spd_pu08 );
        !           820:        f_dimm->m_clmsk_u32   = ddr2_get_cl_mask( f_spd_pu08 );
        !           821:        f_dimm->m_bankcnt_u32 = ddr2_get_banks( f_spd_pu08 );
        !           822: 
        !           823:        ddr2_get_cl( f_dimm );
        !           824:        ddr2_get_dimm_speed( f_dimm, f_spd_pu08 );
        !           825:        ddr2_get_dimm_timings( f_dimm, f_spd_pu08 );
        !           826: }
        !           827: 
        !           828: static int32_t
        !           829: ddr2_checkSPD( uint8_t *f_spd_pu08 )
        !           830: {
        !           831:        uint8_t  crc = 0;
        !           832:        uint32_t i;
        !           833: 
        !           834:        for( i = 0; i < SPD_BUF_SIZE - 1; i++ ) {
        !           835:                crc += f_spd_pu08[i];
        !           836:        }
        !           837: 
        !           838:        if( crc != f_spd_pu08[i] ) {
        !           839:                return RET_ERR;
        !           840:        }
        !           841: 
        !           842:        return RET_OK;
        !           843: }
        !           844: 
        !           845: static int32_t
        !           846: ddr2_readSPDs( void )
        !           847: {
        !           848:        static const uint32_t MAX_SPD_FAIL = 3;
        !           849:        uint8_t  l_spdbuf_pu08[SPD_BUF_SIZE];
        !           850:        uint32_t l_bankfail_u32 = 0;
        !           851:        uint32_t l_spdfail_u32  = 0;
        !           852:        int32_t  l_i2c_i32      = RET_OK;
        !           853:        int32_t  l_spd_i32      = RET_OK;
        !           854:        int32_t  ret            = RET_OK;
        !           855:        uint32_t i;
        !           856: 
        !           857:        /*
        !           858:         * read spd's and detect populated slots
        !           859:         */
        !           860:        for( i = 0; i < NUM_SLOTS; i++ ) {
        !           861:                /*
        !           862:                 * indicate slot as empty
        !           863:                 */
        !           864:                m_dimm[i].m_pop_u32 = 0;
        !           865: 
        !           866:                /*
        !           867:                 * check whether bank is switched off
        !           868:                 */
        !           869:                if( ( m_bankoff_u32 & ( 0x1 << ( i / 2 ) ) ) != 0 ) {
        !           870:                        continue;
        !           871:                }
        !           872: 
        !           873:                /*
        !           874:                 * read SPD data
        !           875:                 */
        !           876: 
        !           877:                /*
        !           878:                 * reset SPD fail counter
        !           879:                 */
        !           880:                l_spdfail_u32 = MAX_SPD_FAIL;
        !           881:                l_spd_i32     = RET_OK;
        !           882: 
        !           883:                while( l_spdfail_u32 != 0 ) {
        !           884:                        l_i2c_i32 = i2c_read( I2C_START + i, 0x0, l_spdbuf_pu08, SPD_BUF_SIZE );
        !           885: 
        !           886:                        if( l_i2c_i32 == RET_OK ) {
        !           887:                                l_spd_i32 = ddr2_checkSPD( l_spdbuf_pu08 );
        !           888: 
        !           889:                                if( l_spd_i32 == RET_OK ) {
        !           890:                                        l_spdfail_u32 = 0;
        !           891:                                } else {
        !           892:                                        l_spdfail_u32--;
        !           893:                                }
        !           894: 
        !           895:                        } else {
        !           896:                                l_spdfail_u32--;
        !           897:                        }
        !           898: 
        !           899:                }
        !           900: 
        !           901:                if( l_spd_i32 != RET_OK ) {
        !           902:                        #ifdef U4_INFO
        !           903:                        printf( "\r\n  [ERROR -> SPD read failure in slot %u]",
        !           904:                                i2c_get_slot( I2C_START + i ) );
        !           905:                        #endif
        !           906: 
        !           907:                        l_bankfail_u32 |= ( 0x1 << ( i / 2 ) );
        !           908:                        ret             = RET_ERR;
        !           909:                } else if( l_i2c_i32 == RET_OK ) {
        !           910:                        /*
        !           911:                         * slot is populated
        !           912:                         */
        !           913:                        ddr2_setupDIMM( &m_dimm[i], i / 2, l_spdbuf_pu08 );
        !           914: 
        !           915:                        m_dptr[m_dcnt_u32] = &m_dimm[i];
        !           916:                        m_dcnt_u32++;
        !           917:                }
        !           918: 
        !           919:        }
        !           920: 
        !           921:        if( ret != RET_OK ) {
        !           922:                m_bankoff_u32 |= l_bankfail_u32;
        !           923:                #ifdef U4_INFO
        !           924:                printf( "\r\n" );
        !           925:                #endif
        !           926:        }
        !           927: 
        !           928:        return ret;
        !           929: }
        !           930: 
        !           931: static int32_t
        !           932: ddr2_setupDIMMcfg( void )
        !           933: {
        !           934:        uint32_t  l_tmp_u32;
        !           935:        uint32_t  l_tmp0_u32;
        !           936:        uint32_t  l_tmp1_u32;
        !           937:        uint32_t  i, j, e, b;
        !           938: 
        !           939:        /*
        !           940:         * check wether on board DIMM slot population is valid
        !           941:         */
        !           942:        e = 0;
        !           943:        b = 0;
        !           944:        for( i = 0; i < NUM_SLOTS; i += 2 ) {
        !           945: 
        !           946:                switch( m_dimm[i].m_pop_u32 + m_dimm[i+1].m_pop_u32 ) {
        !           947:                        case 0: {
        !           948:                                m_bankpop_u32[i/2] = 0;
        !           949:                                break;
        !           950:                        }
        !           951: 
        !           952:                        case 2 * SL_POP: {
        !           953:                                m_bankpop_u32[i/2] = !0;
        !           954:                                b++;
        !           955:                                break;
        !           956:                        }
        !           957: 
        !           958:                        default: {
        !           959:                                #ifdef U4_DEBUG
        !           960:                                printf( "\r\n  [ERROR -> only 1 DIMM installed in bank %u]", i/2 );
        !           961:                                #endif
        !           962:                                e++;
        !           963:                        }
        !           964: 
        !           965:                }
        !           966: 
        !           967:        }
        !           968: 
        !           969:        /*
        !           970:         * return on error
        !           971:         */
        !           972:        if( e != 0 ) {
        !           973:                #ifdef U4_DEBUG
        !           974:                printf( "\r\n" );
        !           975:                #endif
        !           976:                return RET_ERR;
        !           977:        }
        !           978: 
        !           979:        if( b == 0 ) {
        !           980:                #ifdef U4_DEBUG
        !           981:                printf( "\r\n  [ERROR -> no (functional) memory installed]\r\n" );
        !           982:                #endif
        !           983:                return RET_ERR;
        !           984:        }
        !           985: 
        !           986:        /*
        !           987:         * check DIMM compatibility
        !           988:         * configuration is 128 bit data/128 bit bus
        !           989:         * -all DIMMs must be organized as x4
        !           990:         * -all DIMMs must be 72 bit wide with ECC
        !           991:         * -all DIMMs must be registered DIMMs (RDIMMs)
        !           992:         * -paired DIMMs must have the same # of ranks, size & organization
        !           993:         */
        !           994: 
        !           995:        /*
        !           996:         * check DIMM ranks & sizes
        !           997:         */
        !           998:        e = 0;
        !           999:        for( i = 0; i < NUM_SLOTS; i += 2 ) {
        !          1000: 
        !          1001:                if( (   m_bankpop_u32[i/2]   != 0                      ) &&
        !          1002:                    ( ( m_dimm[i].m_rank_u32 != m_dimm[i+1].m_rank_u32 ) ||
        !          1003:                      ( m_dimm[i].m_size_u32 != m_dimm[i+1].m_size_u32 ) ) ) {
        !          1004:                        #ifdef U4_DEBUG
        !          1005:                        printf( "\r\n  [ERROR -> installed DIMMs in bank %u have different ranks/sizes]", i/2 );
        !          1006:                        #endif
        !          1007:                        e++;
        !          1008:                }
        !          1009: 
        !          1010:        }
        !          1011: 
        !          1012:        /*
        !          1013:         * return on error
        !          1014:         */
        !          1015:        if( e != 0 ) {
        !          1016:                #ifdef U4_DEBUG
        !          1017:                printf( "\r\n" );
        !          1018:                #endif
        !          1019:                return RET_ERR;
        !          1020:        }
        !          1021: 
        !          1022:        /*
        !          1023:         * check valid DIMM organisation (must be x4)
        !          1024:         */
        !          1025:        e = 0;
        !          1026:        for( i = 0; i < m_dcnt_u32; i++ ) {
        !          1027: 
        !          1028:                if( ( m_dptr[i]->m_orgmsk_u32 & DIMM_ORG_x4 ) == 0 ) {
        !          1029:                        #ifdef U4_DEBUG
        !          1030:                        printf( "\r\n  [ERROR -> wrong DIMM organisation in bank %u]",
        !          1031:                                m_dptr[i]->m_bank_u32 );
        !          1032:                        #endif
        !          1033:                        e++;
        !          1034:                }
        !          1035: 
        !          1036:        }
        !          1037: 
        !          1038:        /*
        !          1039:         * return on error
        !          1040:         */
        !          1041:        if( e != 0 ) {
        !          1042:                #ifdef U4_DEBUG
        !          1043:                printf( "\r\n" );
        !          1044:                #endif
        !          1045:                return RET_ERR;
        !          1046:        }
        !          1047: 
        !          1048:        e = (uint32_t) ~0;
        !          1049:        for( i = 0; i < m_dcnt_u32; i++ ) {
        !          1050:                e &= m_dptr[i]->m_type_u32;
        !          1051:        }
        !          1052: 
        !          1053:        /*
        !          1054:         * return on error
        !          1055:         */
        !          1056:        if( e == 0 ) {
        !          1057:                #ifdef U4_DEBUG
        !          1058:                printf( "\r\n  [ERROR -> installed DIMMs are of different type]\r\n" );
        !          1059:                #endif
        !          1060:                return RET_ERR;
        !          1061:        }
        !          1062: 
        !          1063:        /*
        !          1064:         * setup generic dimm
        !          1065:         */
        !          1066:        m_gendimm.m_type_u32 = e;
        !          1067: 
        !          1068:        /*
        !          1069:         * check valid width, ecc & burst length
        !          1070:         */
        !          1071:        e = 0;
        !          1072:        for( i = 0; i < m_dcnt_u32; i++ ) {
        !          1073: 
        !          1074:                if( m_dptr[i]->m_width_u32 != DIMM_WIDTH ) {
        !          1075:                        #ifdef U4_DEBUG
        !          1076:                        printf( "\r\n  [ERROR -> invalid DIMM width in bank %u]",
        !          1077:                                m_dptr[i]->m_bank_u32 );
        !          1078:                        #endif
        !          1079:                        e++;
        !          1080:                }
        !          1081: 
        !          1082:                if( m_dptr[i]->m_ecc_u32 == 0 ) {
        !          1083:                        #ifdef U4_DEBUG
        !          1084:                        printf( "\r\n  [ERROR -> DIMM(s) do not support ECC in bank %u]",
        !          1085:                                m_dptr[i]->m_bank_u32 );
        !          1086:                        #endif
        !          1087:                        e++;
        !          1088:                }
        !          1089: 
        !          1090:                if( ( m_dptr[i]->m_burst_u32 & DIMM_BURSTLEN_4 ) == 0 ) {
        !          1091:                        #ifdef U4_DEBUG
        !          1092:                        printf( "\r\n  [ERROR -> DIMM(s) have invalid burst length in bank %u]",
        !          1093:                                m_dptr[i]->m_bank_u32 );
        !          1094:                        #endif
        !          1095:                        e++;
        !          1096:                }
        !          1097: 
        !          1098:        }
        !          1099: 
        !          1100:        /*
        !          1101:         * return on error
        !          1102:         */
        !          1103:        if( e != 0 ) {
        !          1104:                #ifdef U4_DEBUG
        !          1105:                printf( "\r\n" );
        !          1106:                #endif
        !          1107:                return RET_ERR;
        !          1108:        }
        !          1109: 
        !          1110:        /*
        !          1111:         * setup generic dimm
        !          1112:         */
        !          1113:        m_gendimm.m_width_u32 = m_dptr[0]->m_width_u32;
        !          1114:        m_gendimm.m_ecc_u32   = m_dptr[0]->m_ecc_u32;
        !          1115:        m_gendimm.m_burst_u32 = m_dptr[0]->m_burst_u32;
        !          1116: 
        !          1117:        /*
        !          1118:         * success
        !          1119:         */
        !          1120:        m_gendimm.m_pop_u32 = SL_POP;
        !          1121: 
        !          1122:        /*
        !          1123:         * setup timing parameters
        !          1124:         */
        !          1125: 
        !          1126:        /*
        !          1127:         * find smallest common CL value
        !          1128:         */
        !          1129:        l_tmp_u32 = (uint32_t) ~0;
        !          1130:        for( i = 0; i < m_dcnt_u32; i++ ) {
        !          1131:                l_tmp_u32 &= m_dptr[i]->m_clmsk_u32;
        !          1132:        }
        !          1133: 
        !          1134:        m_gendimm.m_clmsk_u32 = l_tmp_u32;
        !          1135:        ddr2_get_cl( &m_gendimm );
        !          1136: 
        !          1137:        /*
        !          1138:         * find fastest common DIMM speed for all common CL values
        !          1139:         */
        !          1140:        for( i = 0; i < m_gendimm.m_clcnt_u32; i++ ) {
        !          1141:                m_gendimm.m_speed_pu32[i] = (uint32_t) ~0;
        !          1142: 
        !          1143:                for( j = 0; j < m_dcnt_u32; j++ ) {
        !          1144:                        l_tmp0_u32 =
        !          1145:                        ddr2_cl2speed( m_dptr[j],
        !          1146:                                       m_gendimm.m_clval_pu32[i],
        !          1147:                                       &l_tmp1_u32 );
        !          1148: 
        !          1149:                        if( m_gendimm.m_speed_pu32[i] > l_tmp0_u32 ) {
        !          1150:                                m_gendimm.m_speed_pu32[i] = l_tmp0_u32;
        !          1151:                                m_gendimm.m_tCK_pu32[i]   = l_tmp1_u32;
        !          1152:                        }
        !          1153: 
        !          1154:                }
        !          1155: 
        !          1156:        }
        !          1157: 
        !          1158:        /*
        !          1159:         * check wether cl values are supported by U4
        !          1160:         */
        !          1161:        for( i = 0; i < m_gendimm.m_clcnt_u32; i++ ) {
        !          1162: 
        !          1163:                if( ( m_gendimm.m_clval_pu32[i] >= U4_MIN_CL ) &&
        !          1164:                    ( m_gendimm.m_clval_pu32[i] <= U4_MAX_CL ) ) {
        !          1165:                        break;
        !          1166:                }
        !          1167: 
        !          1168:        }
        !          1169: 
        !          1170:        if( i == m_gendimm.m_clcnt_u32 ) {
        !          1171:                #ifdef U4_DEBUG
        !          1172:                printf( "\r\n  [ERROR -> DIMM's CL values not supported]\r\n" );
        !          1173:                #endif
        !          1174:                return RET_ERR;
        !          1175:        }
        !          1176: 
        !          1177:        /*
        !          1178:         * choose cl/speed values to use: prefer speed over CL
        !          1179:         * i holds smallest supported cl value of u4 already
        !          1180:         */
        !          1181:        l_tmp_u32 = 0;
        !          1182:        while( i < m_gendimm.m_clcnt_u32 ) {
        !          1183: 
        !          1184:                if( l_tmp_u32 < m_gendimm.m_speed_pu32[i] ) {
        !          1185:                        l_tmp_u32    = m_gendimm.m_speed_pu32[i];
        !          1186:                        m_dclidx_u32 = i;
        !          1187:                }
        !          1188: 
        !          1189:                i++;
        !          1190:        }
        !          1191: 
        !          1192:        /*
        !          1193:         * choose largest number of banks
        !          1194:         */
        !          1195:        m_gendimm.m_bankcnt_u32 = 0;
        !          1196: 
        !          1197:        for( i = 0; i < m_dcnt_u32; i++ ) {
        !          1198: 
        !          1199:                if( m_gendimm.m_bankcnt_u32 < m_dptr[i]->m_bankcnt_u32 ) {
        !          1200:                        m_gendimm.m_bankcnt_u32 = m_dptr[i]->m_bankcnt_u32;
        !          1201:                }
        !          1202: 
        !          1203:        }
        !          1204: 
        !          1205:        /*
        !          1206:         * setup fastest possible timing parameters for all DIMMs
        !          1207:         */
        !          1208:        m_gendimm.m_tRP_u32  = 0;
        !          1209:        m_gendimm.m_tRRD_u32 = 0;
        !          1210:        m_gendimm.m_tRCD_u32 = 0;
        !          1211:        m_gendimm.m_tWR_u32  = 0;
        !          1212:        m_gendimm.m_tWTR_u32 = 0;
        !          1213:        m_gendimm.m_tRTP_u32 = 0;
        !          1214:        m_gendimm.m_tRAS_u32 = 0;
        !          1215:        m_gendimm.m_tRC_u32  = 0;
        !          1216:        m_gendimm.m_tRFC_u32 = 0;
        !          1217:        m_gendimm.m_tREF_u32 = (uint32_t) ~0;
        !          1218: 
        !          1219:        for( i = 0; i < m_dcnt_u32; i++ ) {
        !          1220: 
        !          1221:                if( m_gendimm.m_tRP_u32  < m_dptr[i]->m_tRP_u32  ) {
        !          1222:                        m_gendimm.m_tRP_u32  = m_dptr[i]->m_tRP_u32;
        !          1223:                }
        !          1224: 
        !          1225:                if( m_gendimm.m_tRRD_u32 < m_dptr[i]->m_tRRD_u32 ) {
        !          1226:                        m_gendimm.m_tRRD_u32 = m_dptr[i]->m_tRRD_u32;
        !          1227:                }
        !          1228: 
        !          1229:                if( m_gendimm.m_tRCD_u32 < m_dptr[i]->m_tRCD_u32 ) {
        !          1230:                        m_gendimm.m_tRCD_u32 = m_dptr[i]->m_tRCD_u32;
        !          1231:                }
        !          1232: 
        !          1233:                if( m_gendimm.m_tWR_u32  < m_dptr[i]->m_tWR_u32  ) {
        !          1234:                        m_gendimm.m_tWR_u32  = m_dptr[i]->m_tWR_u32;
        !          1235:                }
        !          1236: 
        !          1237:                if( m_gendimm.m_tWTR_u32 < m_dptr[i]->m_tWTR_u32 ) {
        !          1238:                        m_gendimm.m_tWTR_u32 = m_dptr[i]->m_tWTR_u32;
        !          1239:                }
        !          1240: 
        !          1241:                if( m_gendimm.m_tRTP_u32 < m_dptr[i]->m_tRTP_u32 ) {
        !          1242:                        m_gendimm.m_tRTP_u32 = m_dptr[i]->m_tRTP_u32;
        !          1243:                }
        !          1244: 
        !          1245:                if( m_gendimm.m_tRAS_u32 < m_dptr[i]->m_tRAS_u32 ) {
        !          1246:                        m_gendimm.m_tRAS_u32 = m_dptr[i]->m_tRAS_u32;
        !          1247:                }
        !          1248: 
        !          1249:                if( m_gendimm.m_tRC_u32  < m_dptr[i]->m_tRC_u32  ) {
        !          1250:                        m_gendimm.m_tRC_u32  = m_dptr[i]->m_tRC_u32;
        !          1251:                }
        !          1252: 
        !          1253:                if( m_gendimm.m_tRFC_u32 < m_dptr[i]->m_tRFC_u32 ) {
        !          1254:                        m_gendimm.m_tRFC_u32 = m_dptr[i]->m_tRFC_u32;
        !          1255:                }
        !          1256: 
        !          1257:                if( m_gendimm.m_tREF_u32 > m_dptr[i]->m_tREF_u32 ) {
        !          1258:                        m_gendimm.m_tREF_u32 = m_dptr[i]->m_tREF_u32;
        !          1259:                }
        !          1260: 
        !          1261:        }
        !          1262: 
        !          1263:        return RET_OK;
        !          1264: }
        !          1265: 
        !          1266: static void
        !          1267: u4_group2dimmsDS( dimm_t *f_dimm0, dimm_t *f_dimm1 )
        !          1268: {
        !          1269:        dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
        !          1270: 
        !          1271:        /*
        !          1272:         * known conditions at this point:
        !          1273:         * -at least 2 slots are populated
        !          1274:         * -the 2 DIMMs are equal
        !          1275:         * -DIMMs are double sided (2 ranks)
        !          1276:         *
        !          1277:         * RESULT:
        !          1278:         * 1 group of 2 ranks (2 ranks/2 DIMMs)
        !          1279:         * -> CS mode 1 (one double sided DIMM pair)
        !          1280:         */
        !          1281:        l_dgr->m_size_u32   = 2 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
        !          1282:        l_dgr->m_ss_u32     = 0;
        !          1283:        l_dgr->m_csmode_u32 = 1;
        !          1284:        l_dgr->m_dcnt_u32   = 2;
        !          1285:        l_dgr->m_dptr[0]    = f_dimm0;
        !          1286:        l_dgr->m_dptr[1]    = f_dimm1;
        !          1287: 
        !          1288:        m_dgrcnt_u32++;
        !          1289: }
        !          1290: 
        !          1291: static void
        !          1292: u4_group2dimmsSS( dimm_t *f_dimm0, dimm_t *f_dimm1 )
        !          1293: {
        !          1294:        dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
        !          1295: 
        !          1296:        /*
        !          1297:         * known conditions at this point:
        !          1298:         * -at least 2 slots are populated
        !          1299:         * -the 2 DIMMs are equal
        !          1300:         * -DIMMs are single sided (1 rank)
        !          1301:         *
        !          1302:         * RESULT:
        !          1303:         * 1 group of 1 rank (1 rank/2 DIMMs)
        !          1304:         * -> CS mode 0 (one single sided DIMM pair)
        !          1305:         */
        !          1306:        l_dgr->m_size_u32   = 2 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
        !          1307:        l_dgr->m_ss_u32     = 1;
        !          1308:        l_dgr->m_csmode_u32 = 0;
        !          1309:        l_dgr->m_dcnt_u32   = 2;
        !          1310:        l_dgr->m_dptr[0]    = f_dimm0;
        !          1311:        l_dgr->m_dptr[1]    = f_dimm1;
        !          1312: 
        !          1313:        m_dgrcnt_u32++;
        !          1314: }
        !          1315: 
        !          1316: static void
        !          1317: u4_group4dimmsDS( dimm_t *f_dimm0, dimm_t *f_dimm1,
        !          1318:                  dimm_t *f_dimm2, dimm_t *f_dimm3 )
        !          1319: {
        !          1320:        dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
        !          1321: 
        !          1322:        /*
        !          1323:         * known conditions at this point:
        !          1324:         * -4 slots are populated
        !          1325:         * -all 4 DIMMs are equal
        !          1326:         * -DIMMs are double sided (2 ranks)
        !          1327:         *
        !          1328:         * RESULT:
        !          1329:         * 1 group of 4 ranks (2 ranks/2 DIMMs)
        !          1330:         * -> CS mode 2 (two double sided DIMM pairs)
        !          1331:         */
        !          1332:        l_dgr->m_size_u32   = 4 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
        !          1333:        l_dgr->m_ss_u32     = 0;
        !          1334:        l_dgr->m_csmode_u32 = 2;
        !          1335:        l_dgr->m_dcnt_u32   = 4;
        !          1336:        l_dgr->m_dptr[0]    = f_dimm0;
        !          1337:        l_dgr->m_dptr[1]    = f_dimm1;
        !          1338:        l_dgr->m_dptr[2]    = f_dimm2;
        !          1339:        l_dgr->m_dptr[3]    = f_dimm3;
        !          1340: 
        !          1341:        m_dgrcnt_u32++;
        !          1342: }
        !          1343: 
        !          1344: static void
        !          1345: u4_group4dimmsSS( dimm_t *f_dimm0, dimm_t *f_dimm1,
        !          1346:                  dimm_t *f_dimm2, dimm_t *f_dimm3 )
        !          1347: {
        !          1348:        dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
        !          1349: 
        !          1350:        /*
        !          1351:         * known conditions at this point:
        !          1352:         * -4 slots are populated
        !          1353:         * -all 4 DIMMs are equal
        !          1354:         * -DIMMs are single sided (1 rank)
        !          1355:         *
        !          1356:         * RESULT:
        !          1357:         * 1 group of 2 ranks (1 rank/2 DIMMs)
        !          1358:         * -> CS mode 1 (two single sided DIMM pairs)
        !          1359:         */
        !          1360:        l_dgr->m_size_u32   = 4 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
        !          1361:        l_dgr->m_ss_u32     = 1;
        !          1362:        l_dgr->m_csmode_u32 = 1;
        !          1363:        l_dgr->m_dcnt_u32   = 4;
        !          1364:        l_dgr->m_dptr[0]    = f_dimm0;
        !          1365:        l_dgr->m_dptr[1]    = f_dimm1;
        !          1366:        l_dgr->m_dptr[2]    = f_dimm2;
        !          1367:        l_dgr->m_dptr[3]    = f_dimm3;
        !          1368: 
        !          1369:        m_dgrcnt_u32++;
        !          1370: }
        !          1371: 
        !          1372: static void
        !          1373: u4_group8dimmsDS( dimm_t *f_dimm0, dimm_t *f_dimm1,
        !          1374:                  dimm_t *f_dimm2, dimm_t *f_dimm3,
        !          1375:                  dimm_t *f_dimm4, dimm_t *f_dimm5,
        !          1376:                  dimm_t *f_dimm6, dimm_t *f_dimm7 )
        !          1377: {
        !          1378:        dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
        !          1379: 
        !          1380:        /*
        !          1381:         * known conditions at this point:
        !          1382:         * -8 slots are populated
        !          1383:         * -all 8 DIMMs are equal
        !          1384:         * -DIMMs are double sided (2 ranks)
        !          1385:         *
        !          1386:         * RESULT:
        !          1387:         * 1 group of 8 ranks (2 ranks/2 DIMMs)
        !          1388:         * -> CS mode 3 (four double sided DIMM pairs)
        !          1389:         */
        !          1390:        l_dgr->m_size_u32   = 8 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
        !          1391:        l_dgr->m_ss_u32     = 0;
        !          1392:        l_dgr->m_csmode_u32 = 3;
        !          1393:        l_dgr->m_dcnt_u32   = 8;
        !          1394:        l_dgr->m_dptr[0]    = f_dimm0;
        !          1395:        l_dgr->m_dptr[1]    = f_dimm1;
        !          1396:        l_dgr->m_dptr[2]    = f_dimm2;
        !          1397:        l_dgr->m_dptr[3]    = f_dimm3;
        !          1398:        l_dgr->m_dptr[4]    = f_dimm4;
        !          1399:        l_dgr->m_dptr[5]    = f_dimm5;
        !          1400:        l_dgr->m_dptr[6]    = f_dimm6;
        !          1401:        l_dgr->m_dptr[7]    = f_dimm7;
        !          1402: 
        !          1403:        m_dgrcnt_u32++;
        !          1404: }
        !          1405: 
        !          1406: static void
        !          1407: u4_group8dimmsSS( dimm_t *f_dimm0, dimm_t *f_dimm1,
        !          1408:                  dimm_t *f_dimm2, dimm_t *f_dimm3,
        !          1409:                  dimm_t *f_dimm4, dimm_t *f_dimm5,
        !          1410:                  dimm_t *f_dimm6, dimm_t *f_dimm7 )
        !          1411: {
        !          1412:        dgroup_t *l_dgr = &m_dgroup[m_dgrcnt_u32];
        !          1413: 
        !          1414:        /*
        !          1415:         * known conditions at this point:
        !          1416:         * -8 slots are populated
        !          1417:         * -all 8 DIMMs are equal
        !          1418:         * -DIMMs are single sided (1 rank)
        !          1419:         *
        !          1420:         * RESULT:
        !          1421:         * 1 group of 4 ranks (1 rank/2 DIMMs)
        !          1422:         * -> CS mode 2 (four single sided DIMM pairs)
        !          1423:         */
        !          1424:        l_dgr->m_size_u32   = 8 * ( f_dimm0->m_size_u32 * f_dimm0->m_rank_u32 );
        !          1425:        l_dgr->m_ss_u32     = 1;
        !          1426:        l_dgr->m_csmode_u32 = 2;
        !          1427:        l_dgr->m_dcnt_u32   = 8;
        !          1428:        l_dgr->m_dptr[0]    = f_dimm0;
        !          1429:        l_dgr->m_dptr[1]    = f_dimm1;
        !          1430:        l_dgr->m_dptr[2]    = f_dimm2;
        !          1431:        l_dgr->m_dptr[3]    = f_dimm3;
        !          1432:        l_dgr->m_dptr[4]    = f_dimm4;
        !          1433:        l_dgr->m_dptr[5]    = f_dimm5;
        !          1434:        l_dgr->m_dptr[6]    = f_dimm6;
        !          1435:        l_dgr->m_dptr[7]    = f_dimm7;
        !          1436: 
        !          1437:        m_dgrcnt_u32++;
        !          1438: }
        !          1439: 
        !          1440: static int32_t
        !          1441: u4_Dcmp( dimm_t *f_dimm0, dimm_t *f_dimm1 )
        !          1442: {
        !          1443: 
        !          1444:        if( ( f_dimm0->m_size_u32 == f_dimm1->m_size_u32 ) &&
        !          1445:            ( f_dimm0->m_rank_u32 == f_dimm1->m_rank_u32 ) ) {
        !          1446:                return RET_OK;
        !          1447:        }
        !          1448: 
        !          1449:        return RET_ERR;
        !          1450: }
        !          1451: 
        !          1452: static void
        !          1453: u4_group1banks( uint32_t *bidx )
        !          1454: {
        !          1455:        uint32_t didx = 2 * bidx[0];
        !          1456: 
        !          1457:        /*
        !          1458:         * known conditions at this point:
        !          1459:         * -either DIMMs 0 & 4 or
        !          1460:         *         DIMMs 1 & 5 or
        !          1461:         *         DIMMs 2 & 6 or
        !          1462:         *         DIMMs 3 & 7 are populated
        !          1463:         * -3 (bimini)/1 (maui) pair of slots is empty
        !          1464:         * -installed DIMMs are equal
        !          1465:         */
        !          1466: 
        !          1467:        /*
        !          1468:         * double/single sided setup
        !          1469:         */
        !          1470:        if( m_dimm[didx].m_rank_u32 == 1 ) {
        !          1471:                u4_group2dimmsSS( &m_dimm[didx], &m_dimm[didx+1] );
        !          1472:        } else {
        !          1473:                u4_group2dimmsDS( &m_dimm[didx], &m_dimm[didx+1] );
        !          1474:        }
        !          1475: 
        !          1476: }
        !          1477: 
        !          1478: static void
        !          1479: u4_group2banks( uint32_t *bidx )
        !          1480: {
        !          1481:        uint32_t didx0 = 2 * bidx[0];
        !          1482:        uint32_t didx1 = 2 * bidx[1];
        !          1483: 
        !          1484:        /*
        !          1485:         * known conditions at this point:
        !          1486:         * -4 slots are populated
        !          1487:         */
        !          1488: 
        !          1489:        /*
        !          1490:         * check wether DIMM banks may be grouped
        !          1491:         */
        !          1492:        if( ( ( ( bidx[0] + bidx[1] ) & 0x1 )           != 0 ) &&
        !          1493:            ( u4_Dcmp( &m_dimm[didx0], &m_dimm[didx1] ) == 0 ) ) {
        !          1494:                /*
        !          1495:                 * double/single sided setup
        !          1496:                 * NOTE: at this point all DIMMs have the same amount
        !          1497:                 * of ranks, therefore only the # of ranks on DIMM 0 is checked
        !          1498:                 */
        !          1499:                if( m_dimm[didx0].m_rank_u32 == 1 ) {
        !          1500:                        u4_group4dimmsSS( &m_dimm[didx0], &m_dimm[didx0+1],
        !          1501:                                          &m_dimm[didx1], &m_dimm[didx1+1]);
        !          1502:                } else {
        !          1503:                        u4_group4dimmsDS( &m_dimm[didx0], &m_dimm[didx0+1],
        !          1504:                                          &m_dimm[didx1], &m_dimm[didx1+1]);
        !          1505:                }
        !          1506: 
        !          1507:        } else {
        !          1508:                u4_group1banks( &bidx[0] );
        !          1509:                u4_group1banks( &bidx[1] );
        !          1510:        }
        !          1511: 
        !          1512: }
        !          1513: 
        !          1514: static void
        !          1515: u4_group3banks( uint32_t *bidx )
        !          1516: {
        !          1517: 
        !          1518:        if(        ( bidx[0] == 0 ) && ( bidx[1] == 1 ) ) {
        !          1519:                u4_group2banks( &bidx[0] );
        !          1520:                u4_group1banks( &bidx[2] );
        !          1521:        } else if( ( bidx[1] == 2 ) && ( bidx[2] == 3 ) ) {
        !          1522:                u4_group2banks( &bidx[1] );
        !          1523:                u4_group1banks( &bidx[0] );
        !          1524:        }
        !          1525: 
        !          1526: }
        !          1527: 
        !          1528: static void
        !          1529: u4_group4banks( uint32_t *bidx )
        !          1530: {
        !          1531:        uint32_t didx0 = 2 * bidx[0];
        !          1532:        uint32_t didx1 = 2 * bidx[1];
        !          1533:        uint32_t didx2 = 2 * bidx[2];
        !          1534:        uint32_t didx3 = 2 * bidx[3];
        !          1535: 
        !          1536:        if( ( u4_Dcmp( &m_dimm[didx0], &m_dimm[didx1] ) == RET_OK ) &&
        !          1537:            ( u4_Dcmp( &m_dimm[didx2], &m_dimm[didx3] ) == RET_OK ) &&
        !          1538:            ( u4_Dcmp( &m_dimm[didx0], &m_dimm[didx2] ) == RET_OK ) ) {
        !          1539: 
        !          1540:                if( m_dimm[didx0].m_rank_u32 == 1 ) {
        !          1541:                        u4_group8dimmsSS( &m_dimm[didx0], &m_dimm[didx0+1],
        !          1542:                                          &m_dimm[didx1], &m_dimm[didx1+1],
        !          1543:                                          &m_dimm[didx2], &m_dimm[didx2+1],
        !          1544:                                          &m_dimm[didx3], &m_dimm[didx3+1] );
        !          1545:                } else {
        !          1546:                        u4_group8dimmsDS( &m_dimm[didx0], &m_dimm[didx0+1],
        !          1547:                                          &m_dimm[didx1], &m_dimm[didx1+1],
        !          1548:                                          &m_dimm[didx2], &m_dimm[didx2+1],
        !          1549:                                          &m_dimm[didx3], &m_dimm[didx3+1] );
        !          1550:                }
        !          1551: 
        !          1552:        } else {
        !          1553:                u4_group2banks( &bidx[0] );
        !          1554:                u4_group2banks( &bidx[2] );
        !          1555:        }
        !          1556: 
        !          1557: }
        !          1558: 
        !          1559: static void
        !          1560: u4_sortDIMMgroups( void )
        !          1561: {
        !          1562:        uint32_t i, j;
        !          1563: 
        !          1564:        /*
        !          1565:         * setup global group pointers
        !          1566:         */
        !          1567:        for( i = 0; i < m_dgrcnt_u32; i++ ) {
        !          1568:                m_dgrptr[i] = &m_dgroup[i];
        !          1569:        }
        !          1570: 
        !          1571:        /*
        !          1572:         * use a simple bubble sort to sort groups by size (descending)
        !          1573:         */
        !          1574:        for( i = 0; i < ( m_dgrcnt_u32 - 1 ); i++ ) {
        !          1575: 
        !          1576:                for( j = i + 1; j < m_dgrcnt_u32; j++ ) {
        !          1577: 
        !          1578:                        if( m_dgrptr[i]->m_size_u32 < m_dgrptr[j]->m_size_u32 ) {
        !          1579:                                dgroup_t *l_sgr;
        !          1580: 
        !          1581:                                l_sgr       = m_dgrptr[i];
        !          1582:                                m_dgrptr[i] = m_dgrptr[j];
        !          1583:                                m_dgrptr[j] = l_sgr;
        !          1584:                        }
        !          1585: 
        !          1586:                }
        !          1587: 
        !          1588:        }
        !          1589: 
        !          1590: }
        !          1591: 
        !          1592: static void
        !          1593: u4_calcDIMMcnfg( void )
        !          1594: {
        !          1595:        static const uint32_t _2GB  = (uint32_t) 0x00800;
        !          1596:        static const uint32_t _4GB  = (uint32_t) 0x01000;
        !          1597:        static const uint32_t _64GB = (uint32_t) 0x10000;
        !          1598:        uint32_t l_start_u32        = (uint32_t) 0;
        !          1599:        uint32_t l_end_u32          = (uint32_t) 0;
        !          1600:        uint32_t l_add2g_u32        = (uint32_t) 1;
        !          1601:        uint32_t l_sub2g_u32        = (uint32_t) 1;
        !          1602:        uint32_t i;
        !          1603: 
        !          1604:        /*
        !          1605:         * setup DIMM group parameters
        !          1606:         */
        !          1607:        for( i = 0; i < m_dgrcnt_u32; i++ ) {
        !          1608:                l_end_u32 = l_start_u32 + m_dgrptr[i]->m_size_u32;
        !          1609: 
        !          1610:                if( m_dgrptr[i]->m_size_u32 > _2GB ) {
        !          1611: 
        !          1612:                        if( l_end_u32 < _64GB ) {
        !          1613:                                l_add2g_u32 = ( l_end_u32 >> 11 );
        !          1614:                        } else {
        !          1615:                                l_add2g_u32 = 1;
        !          1616:                        }
        !          1617: 
        !          1618:                        if( l_start_u32 == 0 ) {
        !          1619:                                l_sub2g_u32 = 1;
        !          1620:                        } else {
        !          1621:                                l_sub2g_u32 = ( l_start_u32 >> 11 );
        !          1622:                        }
        !          1623: 
        !          1624:                } else if( l_add2g_u32 != 1 ) {
        !          1625:                        l_start_u32 += _2GB;
        !          1626:                        l_end_u32   += _2GB;
        !          1627:                        l_add2g_u32  = 1;
        !          1628:                        l_sub2g_u32  = 1;
        !          1629:                }
        !          1630: 
        !          1631:                /*
        !          1632:                 * save values for the group
        !          1633:                 */
        !          1634:                m_dgrptr[i]->m_start_u32 = ( l_start_u32 >> 7 ); // = /128
        !          1635:                m_dgrptr[i]->m_end_u32   = ( l_end_u32   >> 7 );
        !          1636:                m_dgrptr[i]->m_add2g_u32 = l_add2g_u32;
        !          1637:                m_dgrptr[i]->m_sub2g_u32 = l_sub2g_u32;
        !          1638: 
        !          1639:                /*
        !          1640:                 * continue with next group
        !          1641:                 */
        !          1642:                if( l_end_u32 != _2GB ) {
        !          1643:                        l_start_u32 = l_end_u32;
        !          1644:                } else {
        !          1645:                        l_start_u32 = _4GB;
        !          1646:                }
        !          1647: 
        !          1648:        }
        !          1649: 
        !          1650: }
        !          1651: 
        !          1652: static int32_t
        !          1653: u4_calcDIMMmemmode( void )
        !          1654: {
        !          1655:        static const uint32_t MAX_ORG  = (uint32_t) 0x10;
        !          1656:        static const uint32_t MIN_BASE = (uint32_t) 0x80;
        !          1657:        static const uint32_t MAX_MODE = (uint32_t) 0x10;
        !          1658:        static const uint32_t MODE_ADD = (uint32_t) 0x04;
        !          1659:        dimm_t   *l_dptr;
        !          1660:        uint32_t  l_modeoffs_u32;
        !          1661:        uint32_t  l_sizebase_u32;
        !          1662:        int32_t   ret = RET_OK;
        !          1663:        uint32_t  i, j;
        !          1664: 
        !          1665:        /*
        !          1666:         * loop through all DIMM groups and calculate memmode setting
        !          1667:         */
        !          1668:        for( i = 0; i < m_dgrcnt_u32; i++ ) {
        !          1669:                l_dptr = m_dgrptr[i]->m_dptr[0]; // all dimms in one group are equal!
        !          1670: 
        !          1671:                l_modeoffs_u32  = MAX_ORG / l_dptr->m_orgval_u32;
        !          1672:                l_modeoffs_u32 /= (uint32_t) 2;
        !          1673:                l_sizebase_u32  = ( MIN_BASE << l_modeoffs_u32 );
        !          1674: 
        !          1675:                j = 0;
        !          1676:                while( ( l_sizebase_u32 != l_dptr->m_size_u32 ) &&
        !          1677:                       ( j               < MAX_MODE           ) ) {
        !          1678:                        l_sizebase_u32 <<= 1;
        !          1679:                        j += (uint32_t) MODE_ADD;
        !          1680:                }
        !          1681: 
        !          1682:                // return on error
        !          1683:                if( j >= MAX_MODE ) {
        !          1684:                        #ifdef U4_INFO
        !          1685:                        uint32_t b, k, l;
        !          1686:                        printf( "\r\n  [ERROR -> unsupported memory type in bank(s)" );
        !          1687: 
        !          1688:                        l = 0;
        !          1689:                        for( k = 0; k < m_dgrptr[i]->m_dcnt_u32; k++ ) {
        !          1690:                                b = m_dgrptr[i]->m_dptr[k]->m_bank_u32;
        !          1691: 
        !          1692:                                if( ( l & ( 1 << b ) ) == 0 ) {
        !          1693:                                        printf( " %u", b );
        !          1694:                                        l |= ( 1 << b );
        !          1695:                                }
        !          1696: 
        !          1697:                        }
        !          1698: 
        !          1699:                        printf( "]\r\n" );
        !          1700:                        #endif
        !          1701: 
        !          1702:                        ret = RET_ERR;
        !          1703:                } else {
        !          1704:                        m_dgrptr[i]->m_memmd_u32 = l_modeoffs_u32 + j;
        !          1705:                }
        !          1706: 
        !          1707:        }
        !          1708: 
        !          1709:        return ret;
        !          1710: }
        !          1711: 
        !          1712: static void
        !          1713: u4_setupDIMMgroups( void )
        !          1714: {
        !          1715:        static const uint64_t _1MB = (uint64_t) 0x100000;
        !          1716:        uint32_t l_bcnt_u32;
        !          1717:        uint32_t l_bidx_u32[NUM_BANKS];
        !          1718:        uint32_t i;
        !          1719: 
        !          1720:        /*
        !          1721:         * calculate number of populated banks
        !          1722:         * IMPORTANT: array must be in ascending order!
        !          1723:         */
        !          1724:        l_bcnt_u32 = 0;
        !          1725:        for( i = 0; i < NUM_BANKS; i++ ) {
        !          1726: 
        !          1727:                if( m_bankpop_u32[i] != 0 ) {
        !          1728:                        l_bidx_u32[l_bcnt_u32] = i;
        !          1729:                        l_bcnt_u32++;
        !          1730:                }
        !          1731: 
        !          1732:        }
        !          1733: 
        !          1734:        switch( l_bcnt_u32 ) {
        !          1735:                case 4: u4_group4banks( &l_bidx_u32[0] ); break;
        !          1736:                case 3: u4_group3banks( &l_bidx_u32[0] ); break;
        !          1737:                case 2: u4_group2banks( &l_bidx_u32[0] ); break;
        !          1738:                case 1: u4_group1banks( &l_bidx_u32[0] ); break;
        !          1739:        }
        !          1740: 
        !          1741:        /*
        !          1742:         * sort DIMM groups by size (descending)
        !          1743:         */
        !          1744:        u4_sortDIMMgroups();
        !          1745: 
        !          1746:        /*
        !          1747:         * calculate overall memory size in bytes
        !          1748:         * (group size is in MB)
        !          1749:         */
        !          1750:        m_memsize_u64 = 0;
        !          1751:        for( i = 0; i < m_dgrcnt_u32; i++ ) {
        !          1752:                m_memsize_u64 += (uint64_t) m_dgrptr[i]->m_size_u32 * _1MB;
        !          1753:        }
        !          1754: 
        !          1755: }
        !          1756: 
        !          1757: static int32_t
        !          1758: u4_setup_core_clock( void )
        !          1759: {
        !          1760:        static const uint32_t MCLK = (uint32_t) 266;
        !          1761:        static const uint32_t CDIV = (uint32_t) 66;
        !          1762:        static const uint32_t CMAX = (uint32_t) 7;
        !          1763:        static const uint32_t MERR = (uint32_t) 10;
        !          1764:        uint32_t volatile     l_cclk_u32;
        !          1765:        uint32_t volatile     l_pll2_u32;
        !          1766:        uint32_t              i, s;
        !          1767: 
        !          1768:        #ifdef U4_INFO
        !          1769:        printf( "  [core clock reset:          ]" );
        !          1770:        #endif
        !          1771: 
        !          1772:        /*
        !          1773:         * calculate speed value
        !          1774:         */
        !          1775:        s  = m_gendimm.m_speed_pu32[m_dclidx_u32];
        !          1776:        s -= MCLK;
        !          1777:        s /= CDIV;
        !          1778: 
        !          1779:        /*
        !          1780:         * insert new core clock value
        !          1781:         */
        !          1782:        l_cclk_u32  = load32_ci( ClkCntl_R );
        !          1783:        l_cclk_u32 &= ~CLK_DDR_CLK_MSK;
        !          1784:        l_cclk_u32 |= ( s << 18 );
        !          1785: 
        !          1786: 
        !          1787:        // return on error
        !          1788:        if( s > CMAX ) {
        !          1789:                #ifdef U4_INFO
        !          1790:                printf( "\b\b\b\bERR\r\n" );
        !          1791:                #endif
        !          1792:                return RET_ERR;
        !          1793:        }
        !          1794: 
        !          1795:        /*
        !          1796:         * reset core clock
        !          1797:         */
        !          1798:        store32_ci( ClkCntl_R, l_cclk_u32 );
        !          1799:        dly( 0x1000000 );
        !          1800:        or32_ci( PLL2Cntl_R, IBIT(0) );
        !          1801:        dly( 0x1000000 );
        !          1802: 
        !          1803:        /*
        !          1804:         * wait for reset to finish
        !          1805:         */
        !          1806:        do {
        !          1807:                l_pll2_u32 = load32_ci( PLL2Cntl_R );
        !          1808:        } while( ( l_pll2_u32 & IBIT(0) ) != 0 );
        !          1809: 
        !          1810:        /*
        !          1811:         * wait for stable PLL
        !          1812:         */
        !          1813:        s = 0;
        !          1814:        do {
        !          1815:                l_pll2_u32  = ( load32_ci( PLL2Cntl_R ) & IBIT(2) );
        !          1816: 
        !          1817:                for( i = 0; i < 4; i++ ) {
        !          1818:                        l_pll2_u32 &= ( load32_ci( PLL2Cntl_R ) & IBIT(2) );
        !          1819:                        l_pll2_u32 &= ( load32_ci( PLL2Cntl_R ) & IBIT(2) );
        !          1820:                        l_pll2_u32 &= ( load32_ci( PLL2Cntl_R ) & IBIT(2) );
        !          1821:                        dly( 0x10000 );
        !          1822:                }
        !          1823: 
        !          1824:        } while( ( l_pll2_u32 == 0 ) && ( s++ < MERR ) );
        !          1825: 
        !          1826:        if( s >= MERR ) {
        !          1827:                #ifdef U4_INFO
        !          1828:                printf( "\b\b\b\bERR\r\n" );
        !          1829:                #endif
        !          1830:                return RET_ERR;
        !          1831:        }
        !          1832: 
        !          1833:        #ifdef U4_INFO
        !          1834:        printf( "\b\b\bOK\r\n" );
        !          1835:        #endif
        !          1836: 
        !          1837:        return RET_OK;
        !          1838: }
        !          1839: 
        !          1840: static void
        !          1841: u4_auto_calib_init( void )
        !          1842: {
        !          1843:        static const uint32_t SEQ[] = {
        !          1844:                0xb1000000, 0xd1000000, 0xd1000000, 0xd1000000,
        !          1845:                0xd1000000, 0xd1000000, 0xd1000000, 0xd1000000,
        !          1846:                0xd1000000, 0xd1000000, 0xd1000000, 0xd1000000,
        !          1847:                0xd1000000, 0xd1000000, 0xd1000400, 0x00000000,
        !          1848:        };
        !          1849: 
        !          1850:        uint64_t i;
        !          1851:        uint32_t j;
        !          1852: 
        !          1853:        for( i = MemInit00_R, j = 0; i <= MemInit15_R; i += 0x10, j++ ) {
        !          1854:                store32_ci( i, SEQ[j] );
        !          1855:        }
        !          1856: 
        !          1857: }
        !          1858: 
        !          1859: #if 0
        !          1860: static uint32_t
        !          1861: u4_RSL_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 )
        !          1862: {
        !          1863:        static const uint32_t MemProgCntl_V = (uint32_t) 0x80000500;
        !          1864:        static const uint32_t CalConf0_V    = (uint32_t) 0x0000aa10;
        !          1865:        uint32_t l_MemProgCntl_u32;
        !          1866:        uint32_t l_CalConf0_u32;
        !          1867:        uint32_t l_MeasStat_u32;
        !          1868:        uint32_t l_CalC_u32;
        !          1869:        uint64_t MeasStat_R;
        !          1870:        uint64_t CalC_R;
        !          1871:        uint64_t VerC_R;
        !          1872:        uint32_t shft;
        !          1873:        uint32_t v;
        !          1874: 
        !          1875:        if( f_BLane_u32 < 4 ) {
        !          1876:                MeasStat_R   = MeasStatusC0_R;
        !          1877:                CalC_R       = CalC0_R;
        !          1878:                VerC_R       = RstLdEnVerniersC0_R;
        !          1879:        } else if( f_BLane_u32  <  8 ) {
        !          1880:                f_BLane_u32 -= 4;
        !          1881:                MeasStat_R   = MeasStatusC1_R;
        !          1882:                CalC_R       = CalC1_R;
        !          1883:                VerC_R       = RstLdEnVerniersC1_R;
        !          1884:        } else if( f_BLane_u32  < 12 ) {
        !          1885:                f_BLane_u32 -= 8;
        !          1886:                MeasStat_R   = MeasStatusC2_R;
        !          1887:                CalC_R       = CalC2_R;
        !          1888:                VerC_R       = RstLdEnVerniersC2_R;
        !          1889:        } else if( f_BLane_u32 == 16 ) {
        !          1890:                f_BLane_u32  = 4;
        !          1891:                MeasStat_R   = MeasStatusC1_R;
        !          1892:                CalC_R       = CalC1_R;
        !          1893:                VerC_R       = RstLdEnVerniersC1_R;
        !          1894:        } else if( f_BLane_u32 == 17 ) {
        !          1895:                f_BLane_u32  = 4;
        !          1896:                MeasStat_R   = MeasStatusC3_R;
        !          1897:                CalC_R       = CalC3_R;
        !          1898:                VerC_R       = RstLdEnVerniersC3_R;
        !          1899:        } else {
        !          1900:                f_BLane_u32 -= 12;
        !          1901:                MeasStat_R   = MeasStatusC3_R;
        !          1902:                CalC_R       = CalC3_R;
        !          1903:                VerC_R       = RstLdEnVerniersC3_R;
        !          1904:        }
        !          1905: 
        !          1906:        shft = (uint32_t) 28 - ( f_BLane_u32 * 4 );
        !          1907: 
        !          1908:        /*
        !          1909:         * start auto calibration logic & wait for completion
        !          1910:         */
        !          1911:        or32_ci( MeasStat_R, IBIT(0) );
        !          1912: 
        !          1913:        do {
        !          1914:                l_MeasStat_u32 = load32_ci( MeasStat_R );
        !          1915:        } while( ( l_MeasStat_u32 & IBIT(0) ) == 1 );
        !          1916: 
        !          1917:        l_CalConf0_u32  = CalConf0_V;
        !          1918:        store32_ci( CalConf0_R, l_CalConf0_u32 );
        !          1919: 
        !          1920:        for( v = 0x000; v < (uint32_t) 0x100; v++ ) {
        !          1921:                store32_ci( VerC_R, ( v << 24 ) | ( v << 16 ) );
        !          1922: 
        !          1923:                l_MemProgCntl_u32  = MemProgCntl_V;
        !          1924:                l_MemProgCntl_u32 |=
        !          1925:                        ( (uint32_t) 0x00800000 >> f_Rank_u32 );
        !          1926:                store32_ci( MemProgCntl_R, l_MemProgCntl_u32 );
        !          1927: 
        !          1928:                do {
        !          1929:                        l_MemProgCntl_u32 = load32_ci( MemProgCntl_R );
        !          1930:                } while( ( l_MemProgCntl_u32 & IBIT(1) ) == 0 );
        !          1931: 
        !          1932:                l_CalC_u32 = ( ( load32_ci( CalC_R ) >> shft ) &
        !          1933:                                 (uint32_t) 0xf );
        !          1934: 
        !          1935:                if( l_CalC_u32 != (uint32_t) 0xa ) {
        !          1936:                        v--;
        !          1937:                        break;
        !          1938:                }
        !          1939: 
        !          1940:        }
        !          1941: 
        !          1942:        if( v == (uint32_t) 0x100 ) {
        !          1943:                v = (uint32_t) ~1;
        !          1944:        }
        !          1945: 
        !          1946:        return v;
        !          1947: }
        !          1948: #endif
        !          1949: 
        !          1950: static uint32_t
        !          1951: u4_RMDF_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 )
        !          1952: {
        !          1953:        static const uint32_t MemProgCntl_V = (uint32_t) 0x80000f00;
        !          1954:        static const uint32_t CalConf0_V    = (uint32_t) 0x0000ac10;
        !          1955:        uint32_t l_MemProgCntl_u32;
        !          1956:        uint32_t l_CalConf0_u32;
        !          1957:        uint32_t l_MeasStat_u32;
        !          1958:        uint32_t l_CalC_u32;
        !          1959:        uint64_t MeasStat_R;
        !          1960:        uint64_t CalC_R;
        !          1961:        uint64_t VerC_R;
        !          1962:        uint32_t shft;
        !          1963:        uint32_t v;
        !          1964: 
        !          1965:        if( f_BLane_u32 < 4 ) {
        !          1966:                MeasStat_R   = MeasStatusC0_R;
        !          1967:                CalC_R       = CalC0_R;
        !          1968:                VerC_R       = RstLdEnVerniersC0_R;
        !          1969:        } else if( f_BLane_u32  <  8 ) {
        !          1970:                f_BLane_u32 -= 4;
        !          1971:                MeasStat_R   = MeasStatusC1_R;
        !          1972:                CalC_R       = CalC1_R;
        !          1973:                VerC_R       = RstLdEnVerniersC1_R;
        !          1974:        } else if( f_BLane_u32  < 12 ) {
        !          1975:                f_BLane_u32 -= 8;
        !          1976:                MeasStat_R   = MeasStatusC2_R;
        !          1977:                CalC_R       = CalC2_R;
        !          1978:                VerC_R       = RstLdEnVerniersC2_R;
        !          1979:        } else if( f_BLane_u32 == 16 ) {
        !          1980:                f_BLane_u32  = 4;
        !          1981:                MeasStat_R   = MeasStatusC1_R;
        !          1982:                CalC_R       = CalC1_R;
        !          1983:                VerC_R       = RstLdEnVerniersC1_R;
        !          1984:        } else if( f_BLane_u32 == 17 ) {
        !          1985:                f_BLane_u32  = 4;
        !          1986:                MeasStat_R   = MeasStatusC3_R;
        !          1987:                CalC_R       = CalC3_R;
        !          1988:                VerC_R       = RstLdEnVerniersC3_R;
        !          1989:        } else {
        !          1990:                f_BLane_u32 -= 12;
        !          1991:                MeasStat_R   = MeasStatusC3_R;
        !          1992:                CalC_R       = CalC3_R;
        !          1993:                VerC_R       = RstLdEnVerniersC3_R;
        !          1994:        }
        !          1995: 
        !          1996:        shft = (uint32_t) 28 - ( f_BLane_u32 * 4 );
        !          1997: 
        !          1998:        /*
        !          1999:         * start auto calibration logic & wait for completion
        !          2000:         */
        !          2001:        or32_ci( MeasStat_R, IBIT(0) );
        !          2002: 
        !          2003:        do {
        !          2004:                l_MeasStat_u32 = load32_ci( MeasStat_R );
        !          2005:        } while( ( l_MeasStat_u32 & IBIT(0) ) == 1 );
        !          2006: 
        !          2007:        l_CalConf0_u32  = CalConf0_V;
        !          2008:        l_CalConf0_u32 |= ( f_BLane_u32 << 5 );
        !          2009:        store32_ci( CalConf0_R, l_CalConf0_u32 );
        !          2010: 
        !          2011:        for( v = 0x000; v < (uint32_t) 0x100; v++ ) {
        !          2012:                store32_ci( VerC_R, ( v << 24 ) | ( v << 16 ) );
        !          2013: 
        !          2014:                l_MemProgCntl_u32  = MemProgCntl_V;
        !          2015:                l_MemProgCntl_u32 |=
        !          2016:                        ( (uint32_t) 0x00800000 >> f_Rank_u32 );
        !          2017:                store32_ci( MemProgCntl_R, l_MemProgCntl_u32 );
        !          2018: 
        !          2019:                do {
        !          2020:                        l_MemProgCntl_u32 = load32_ci( MemProgCntl_R );
        !          2021:                } while( ( l_MemProgCntl_u32 & IBIT(1) ) == 0 );
        !          2022: 
        !          2023:                l_CalC_u32 = ( ( load32_ci( CalC_R ) >> shft ) &
        !          2024:                                 (uint32_t) 0xf );
        !          2025: 
        !          2026:                if( l_CalC_u32 != (uint32_t) 0xa ) {
        !          2027:                        v--;
        !          2028:                        break;
        !          2029:                }
        !          2030: 
        !          2031:        }
        !          2032: 
        !          2033:        if( v == (uint32_t) 0x100 ) {
        !          2034:                v = (uint32_t) ~1;
        !          2035:        }
        !          2036: 
        !          2037:        return v;
        !          2038: }
        !          2039: 
        !          2040: static int32_t
        !          2041: u4_RMDF_Rank( uint32_t  f_Rank_u32,
        !          2042:              uint32_t *f_Buf_pu32 )
        !          2043: {
        !          2044:        int32_t  l_Err_pi32 = 0;
        !          2045:        uint32_t b;
        !          2046: 
        !          2047:        for( b = 0; ( b < MAX_BLANE ) && ( l_Err_pi32 == 0 ); b++ ) {
        !          2048:                f_Buf_pu32[b] = u4_RMDF_BLane( f_Rank_u32, b );
        !          2049: 
        !          2050:                if( f_Buf_pu32[b] == (uint32_t) ~0 ) {
        !          2051:                        f_Buf_pu32[b] = 0;
        !          2052:                        l_Err_pi32++;
        !          2053:                } else if( f_Buf_pu32[b] == (uint32_t) ~1 ) {
        !          2054:                        f_Buf_pu32[b] = (uint32_t) 0xff;
        !          2055:                        l_Err_pi32++;
        !          2056:                }
        !          2057: 
        !          2058:        }
        !          2059: 
        !          2060:        return l_Err_pi32;
        !          2061: }
        !          2062: 
        !          2063: static int32_t
        !          2064: u4_auto_calib_MemBus( auto_calib_t *f_ac_pt )
        !          2065: {
        !          2066:        uint32_t RdMacDly, RdMacCnt;
        !          2067:        uint32_t ResMuxDly, ResMuxCnt;
        !          2068:        uint32_t RdPipeDly;
        !          2069:        uint32_t l_Buf_pu32[MAX_DRANKS][MAX_BLANE];
        !          2070:        uint32_t l_Rnk_pu32[MAX_DRANKS];
        !          2071:        uint32_t l_Ver_u32;
        !          2072:        int32_t  l_Err_i32;
        !          2073:        uint32_t bidx;
        !          2074:        uint32_t n, r, b;
        !          2075: 
        !          2076:        /*
        !          2077:         * read starting delays out of the MemBus register
        !          2078:         */
        !          2079:        RdMacDly  = ( load32_ci( MemBusCnfg_R ) >> 28 ) & 0xf;
        !          2080:        ResMuxDly = ( load32_ci( MemBusCnfg_R ) >> 24 ) & 0xf;
        !          2081: 
        !          2082:        /*
        !          2083:         * initialize ranks as not populated
        !          2084:         */
        !          2085:        for( r = 0; r < MAX_DRANKS; r++ ) {
        !          2086:                l_Rnk_pu32[r] = 0;
        !          2087:        }
        !          2088: 
        !          2089:        /*
        !          2090:         * run through every possible delays of
        !          2091:         * RdMacDly, ResMuxDly & RdPipeDly until
        !          2092:         * the first working configuration is found
        !          2093:         */
        !          2094:        RdPipeDly = 0;
        !          2095:        do {
        !          2096:                and32_ci( MemBusCnfg2_R, ~0x3 );
        !          2097:                or32_ci(  MemBusCnfg2_R, RdPipeDly );
        !          2098: 
        !          2099:                RdMacCnt  =  RdMacDly;
        !          2100:                ResMuxCnt =  ResMuxDly;
        !          2101: 
        !          2102:                /*
        !          2103:                 * RdMacDly >= ResMuxDly
        !          2104:                 */
        !          2105:                do {
        !          2106:                        and32_ci( MemBusCnfg_R, ( 1 << 24 ) - 1 );
        !          2107:                        or32_ci(  MemBusCnfg_R, ( RdMacCnt  << 28 ) |
        !          2108:                                                ( ResMuxCnt << 24 ) );
        !          2109:                        and32_ci( MemBusCnfg2_R, ( 1 << 28 ) - 1 );
        !          2110:                        or32_ci(  MemBusCnfg2_R, ( RdMacCnt << 28 ) );
        !          2111: 
        !          2112:                        /*
        !          2113:                         * check the current value for every installed
        !          2114:                         * DIMM on each side for every bytelane
        !          2115:                         */
        !          2116:                        l_Err_i32 = 0;
        !          2117:                        for( n = 0;
        !          2118:                             ( n < NUM_SLOTS ) &&
        !          2119:                             ( l_Err_i32 == 0 );
        !          2120:                             n += 2 ) {
        !          2121: 
        !          2122:                                if( m_dimm[n].m_pop_u32 ) {
        !          2123:                                        /*
        !          2124:                                         * run through all 18 bytelanes of every rank
        !          2125:                                         */
        !          2126:                                        for( r = n;
        !          2127:                                             ( r < n + m_dimm[n].m_rank_u32 ) &&
        !          2128:                                             ( l_Err_i32 == 0 );
        !          2129:                                             r++ ) {
        !          2130:                                                l_Rnk_pu32[r] = 1;
        !          2131: 
        !          2132:                                                l_Err_i32 =
        !          2133:                                                u4_RMDF_Rank( r,
        !          2134:                                                              &l_Buf_pu32[r][0] );
        !          2135:                                        }
        !          2136: 
        !          2137:                                }
        !          2138: 
        !          2139:                        }
        !          2140: 
        !          2141:                        /*
        !          2142:                         * decrementation before exit is wanted!
        !          2143:                         */
        !          2144:                        RdMacCnt--;
        !          2145:                        ResMuxCnt--;
        !          2146:                } while( ( ResMuxCnt  > 0 ) &&
        !          2147:                         ( l_Err_i32 != 0 ) );
        !          2148: 
        !          2149:                if( l_Err_i32 != 0 ) {
        !          2150:                        RdPipeDly++;
        !          2151:                }
        !          2152: 
        !          2153:        } while( ( RdPipeDly   < 4 ) &&
        !          2154:                 ( l_Err_i32 != 0 ) );
        !          2155: 
        !          2156:        /*
        !          2157:         * if l_Err_pi32 == 0 the auto calibration passed ok
        !          2158:         */
        !          2159:        if( l_Err_i32 != 0 ) {
        !          2160:                return RET_ERR;
        !          2161:        }
        !          2162: 
        !          2163:        /*
        !          2164:         * insert delay values into return struct
        !          2165:         */
        !          2166:        and32_ci( MemBusCnfg_R, ( 1 << 24 ) - 1 );
        !          2167:        or32_ci(  MemBusCnfg_R, ( RdMacCnt  << 28 ) |
        !          2168:                                ( ResMuxCnt << 24 ) );
        !          2169:        and32_ci( MemBusCnfg2_R, ( ( 1 << 28 ) - 1 ) & ~0x3 );
        !          2170:        or32_ci(  MemBusCnfg2_R, ( RdMacCnt << 28 ) | RdPipeDly );
        !          2171: 
        !          2172:        f_ac_pt->m_MemBusCnfg_u32  = load32_ci( MemBusCnfg_R );
        !          2173:        f_ac_pt->m_MemBusCnfg2_u32 = load32_ci( MemBusCnfg2_R );
        !          2174: 
        !          2175:        /*
        !          2176:         * calculate the average vernier setting for the
        !          2177:         * bytelanes which share one vernier
        !          2178:         */
        !          2179:        for( b = 0; b < MAX_BLANE - 2; b += 2 ) {
        !          2180:                n         = 0;
        !          2181:                l_Ver_u32 = 0;
        !          2182: 
        !          2183:                for( r = 0; r < MAX_DRANKS; r++ ) {
        !          2184:                        /*
        !          2185:                         * calculation is done or populated ranks only
        !          2186:                         */
        !          2187:                        if( l_Rnk_pu32[r] != 0 ) {
        !          2188:                                /*
        !          2189:                                 * calculate average value
        !          2190:                                 */
        !          2191:                                l_Ver_u32 += l_Buf_pu32[r][b];
        !          2192:                                l_Ver_u32 += l_Buf_pu32[r][b+1];
        !          2193:                                n         += 2;
        !          2194: 
        !          2195:                                if( b == 4 ) {
        !          2196:                                        l_Ver_u32 += l_Buf_pu32[r][16];
        !          2197:                                        n++;
        !          2198:                                } else if( b == 12 ) {
        !          2199:                                        l_Ver_u32 += l_Buf_pu32[r][17];
        !          2200:                                        n++;
        !          2201:                                }
        !          2202: 
        !          2203:                        }
        !          2204: 
        !          2205:                }
        !          2206: 
        !          2207:                /*
        !          2208:                 * average the values
        !          2209:                 */
        !          2210:                l_Ver_u32 /= n;
        !          2211: 
        !          2212:                /*
        !          2213:                 * set appropiate vernier register for
        !          2214:                 * the current bytelane
        !          2215:                 */
        !          2216:                bidx = ( b >> 2 );
        !          2217:                if( ( b & (uint32_t) 0x3 ) == 0 ) {
        !          2218:                        l_Ver_u32 <<= 24;
        !          2219:                        f_ac_pt->m_RstLdEnVerniers_pu32[bidx]  = l_Ver_u32;
        !          2220:                } else {
        !          2221:                        l_Ver_u32 <<= 16;
        !          2222:                        f_ac_pt->m_RstLdEnVerniers_pu32[bidx] |= l_Ver_u32;
        !          2223:                }
        !          2224: 
        !          2225:        }
        !          2226: 
        !          2227:        return RET_OK;
        !          2228: }
        !          2229: 
        !          2230: static int32_t
        !          2231: u4_auto_calib( auto_calib_t *f_ac_pt )
        !          2232: {
        !          2233:        uint32_t l_MemBusCnfg_S;
        !          2234:        uint32_t l_MemBusCnfg2_S;
        !          2235:        uint32_t l_RstLdEnVerniers_S[4];
        !          2236:        int32_t  l_Ret_i32;
        !          2237: 
        !          2238:        /*
        !          2239:         * save manipulated registers
        !          2240:         */
        !          2241:        l_MemBusCnfg_S         = load32_ci( MemBusCnfg_R );
        !          2242:        l_MemBusCnfg2_S        = load32_ci( MemBusCnfg2_R );
        !          2243:        l_RstLdEnVerniers_S[0] = load32_ci( RstLdEnVerniersC0_R );
        !          2244:        l_RstLdEnVerniers_S[1] = load32_ci( RstLdEnVerniersC1_R );
        !          2245:        l_RstLdEnVerniers_S[2] = load32_ci( RstLdEnVerniersC2_R );
        !          2246:        l_RstLdEnVerniers_S[3] = load32_ci( RstLdEnVerniersC3_R );
        !          2247: 
        !          2248:        u4_auto_calib_init();
        !          2249:        l_Ret_i32 = u4_auto_calib_MemBus( f_ac_pt );
        !          2250: 
        !          2251:        /*
        !          2252:         * restore manipulated registers
        !          2253:         */
        !          2254:        store32_ci( MemBusCnfg_R,  l_MemBusCnfg_S );
        !          2255:        store32_ci( MemBusCnfg2_R, l_MemBusCnfg2_S );
        !          2256:        store32_ci( RstLdEnVerniersC0_R, l_RstLdEnVerniers_S[0] );
        !          2257:        store32_ci( RstLdEnVerniersC1_R, l_RstLdEnVerniers_S[1] );
        !          2258:        store32_ci( RstLdEnVerniersC2_R, l_RstLdEnVerniers_S[2] );
        !          2259:        store32_ci( RstLdEnVerniersC3_R, l_RstLdEnVerniers_S[3] );
        !          2260: 
        !          2261:        return l_Ret_i32;
        !          2262: }
        !          2263: 
        !          2264: static int32_t
        !          2265: u4_checkeccerr( eccerror_t *f_ecc_pt )
        !          2266: {
        !          2267:        uint32_t l_val_u32;
        !          2268:        int32_t  ret = RET_OK;
        !          2269: 
        !          2270:        l_val_u32   = load32_ci( MESR_R );
        !          2271:        l_val_u32 >>= 29;
        !          2272: 
        !          2273:        if( ( l_val_u32 & (uint32_t) 0x7 ) != 0 ) {
        !          2274: 
        !          2275:                if(        ( l_val_u32 & (uint32_t) 0x4 ) != 0 ) {
        !          2276:                        /* UE */
        !          2277:                        ret = RET_ACERR_UE;
        !          2278:                } else if( ( l_val_u32 & (uint32_t) 0x1 ) != 0 ) {
        !          2279:                        /* UEWT */
        !          2280:                        ret = RET_ACERR_UEWT;
        !          2281:                } else {
        !          2282:                        /* CE */
        !          2283:                        ret = RET_ACERR_CE;
        !          2284:                }
        !          2285: 
        !          2286:        }
        !          2287: 
        !          2288:        f_ecc_pt->m_err_i32   = ret;
        !          2289: 
        !          2290:        l_val_u32             = load32_ci( MEAR1_R );
        !          2291:        f_ecc_pt->m_uecnt_u32 = ( ( l_val_u32 >> 24 ) & (uint32_t) 0xff );
        !          2292:        f_ecc_pt->m_cecnt_u32 = ( ( l_val_u32 >> 16 ) & (uint32_t) 0xff );
        !          2293: 
        !          2294:        l_val_u32             = load32_ci( MEAR0_R );
        !          2295:        f_ecc_pt->m_rank_u32  = ( ( l_val_u32 >> 29 ) & (uint32_t) 0x7 );
        !          2296:        f_ecc_pt->m_col_u32   = ( ( l_val_u32 >> 18 ) & (uint32_t) 0x7ff );
        !          2297:        f_ecc_pt->m_row_u32   = ( ( l_val_u32 >>  0 ) & (uint32_t) 0x7fff );
        !          2298:        f_ecc_pt->m_bank_u32  = ( ( l_val_u32 >> 15 ) & (uint32_t) 0x7 );
        !          2299: 
        !          2300:        return ret;
        !          2301: }
        !          2302: 
        !          2303: static uint32_t
        !          2304: u4_CalcScrubEnd( void )
        !          2305: {
        !          2306:        uint64_t l_scrend_u64 = m_memsize_u64;
        !          2307: 
        !          2308:        /*
        !          2309:         * check for memory hole at 2GB
        !          2310:         */
        !          2311:        if( l_scrend_u64 > _2GB ) {
        !          2312:                l_scrend_u64 += _2GB;
        !          2313:        }
        !          2314: 
        !          2315:        l_scrend_u64 -= 0x40;
        !          2316:        l_scrend_u64 /= 0x10;
        !          2317: 
        !          2318:        return( (uint32_t) l_scrend_u64 );
        !          2319: }
        !          2320: 
        !          2321: static int32_t
        !          2322: u4_Scrub( uint32_t f_scrub_u32, uint32_t f_pattern_u32, eccerror_t *f_eccerr_pt )
        !          2323: {
        !          2324:        uint32_t i;
        !          2325:        int32_t  ret;
        !          2326: 
        !          2327:        /*
        !          2328:         * setup scrub parameters
        !          2329:         */
        !          2330:        store32_ci( MSCR_R, 0 );                        // stop scrub
        !          2331:        store32_ci( MSRSR_R, 0x0 );                     // set start
        !          2332:        store32_ci( MSRER_R, u4_CalcScrubEnd() );       // set end
        !          2333:        store32_ci( MSPR_R, f_pattern_u32 );            // set pattern
        !          2334: 
        !          2335:        /*
        !          2336:         * clear out ECC error registers
        !          2337:         */
        !          2338:        store32_ci( MEAR0_R, 0x0 );
        !          2339:        store32_ci( MEAR1_R, 0x0 );
        !          2340:        store32_ci( MESR_R, 0x0 );
        !          2341: 
        !          2342:        /*
        !          2343:         * Setup Scrub Type
        !          2344:         */
        !          2345:        store32_ci( MSCR_R, f_scrub_u32 );
        !          2346: 
        !          2347:        if( f_scrub_u32 != BACKGROUND_SCRUB ) {
        !          2348:                /*
        !          2349:                 * wait for scrub to complete
        !          2350:                 */
        !          2351:                do {
        !          2352:                        progbar();
        !          2353:                        dly( 15000000 );
        !          2354:                        i = load32_ci( MSCR_R );
        !          2355:                } while( ( i & f_scrub_u32 ) != 0 );
        !          2356: 
        !          2357:                ret = u4_checkeccerr( f_eccerr_pt );
        !          2358:        } else {
        !          2359:                ret = RET_OK;
        !          2360:        }
        !          2361: 
        !          2362:        return ret;
        !          2363: }
        !          2364: 
        !          2365: static eccerror_t
        !          2366: u4_InitialScrub( void )
        !          2367: {
        !          2368:        eccerror_t l_eccerr_st[2];
        !          2369:        int32_t    l_err_i32[2] = { 0, 0 };
        !          2370: 
        !          2371:        l_err_i32[0] = u4_Scrub( IMMEDIATE_SCRUB_WITH_FILL, 0x0, &l_eccerr_st[0] );
        !          2372: 
        !          2373:        if( l_err_i32[0] >= -1 /*CE*/ ) {
        !          2374:                l_err_i32[1] = u4_Scrub( IMMEDIATE_SCRUB, 0x0, &l_eccerr_st[1] );
        !          2375:        }
        !          2376: 
        !          2377:        if( l_err_i32[0] < l_err_i32[1] ) {
        !          2378:                return l_eccerr_st[0];
        !          2379:        } else {
        !          2380:                return l_eccerr_st[1];
        !          2381:        }
        !          2382: 
        !          2383: }
        !          2384: 
        !          2385: /*
        !          2386:  * RND: calculates Timer cycles from the given frequency
        !          2387:  *     devided by the clock frequency. Values are rounded
        !          2388:  *     up to the nearest integer value if the division is not even.
        !          2389:  */
        !          2390: #define RND( tXXX )    ( ( ( tXXX ) + tCK - 1 ) / tCK )
        !          2391: 
        !          2392: static void
        !          2393: u4_MemInitSequence( uint32_t tRP, uint32_t tWR, uint32_t tRFC, uint32_t CL,
        !          2394:                    uint32_t tCK, uint32_t TD )
        !          2395: {
        !          2396:        /*
        !          2397:         * DIMM init sequence
        !          2398:         */
        !          2399:        static const uint32_t INI_SEQ[] = {
        !          2400:                0xa0000400, 0x80020000, 0x80030000, 0x80010404,
        !          2401:                0x8000100a, 0xa0000400, 0x90000000, 0x90000000,
        !          2402:                0x8ff0100a, 0x80010784, 0x80010404, 0x00000000,
        !          2403:                0x00000000, 0x00000000, 0x00000000, 0x00000000
        !          2404:        };
        !          2405: 
        !          2406:        uint32_t l_MemInit_u32;
        !          2407:        uint64_t r;
        !          2408:        uint32_t i;
        !          2409: 
        !          2410:        for( r = MemInit00_R, i = 0; r <= MemInit15_R; r += 0x10, i++ ) {
        !          2411:                l_MemInit_u32 = INI_SEQ[i];
        !          2412: 
        !          2413:                switch( i ) {
        !          2414:                        case 0:
        !          2415:                        case 5: {
        !          2416:                                l_MemInit_u32 |= ( ( RND( tRP ) - TD )  << 20 );
        !          2417:                                break;
        !          2418:                        }
        !          2419:                        case 3: {
        !          2420:                                store32_ci( EMRSRegCntl_R, l_MemInit_u32 &
        !          2421:                                                           (uint32_t) 0xffff );
        !          2422:                                break;
        !          2423:                        }
        !          2424:                        case 4: {
        !          2425:                                l_MemInit_u32 |= IBIT(23);
        !          2426:                        }
        !          2427:                        case 8: {
        !          2428:                                l_MemInit_u32 |= ( ( RND( tWR ) - 1 )  <<  9 );
        !          2429:                                l_MemInit_u32 |= ( CL                  <<  4 );
        !          2430: 
        !          2431:                                store32_ci( MRSRegCntl_R, l_MemInit_u32 &
        !          2432:                                                          (uint32_t) 0xffff );
        !          2433:                                break;
        !          2434:                        }
        !          2435:                        case 6:
        !          2436:                        case 7: {
        !          2437:                                l_MemInit_u32 |= ( ( RND( tRFC ) - TD ) << 20 );
        !          2438:                                break;
        !          2439:                        }
        !          2440: 
        !          2441:                }
        !          2442: 
        !          2443:                store32_ci( r, l_MemInit_u32 );
        !          2444: 
        !          2445: #ifdef U4_SHOW_REGS
        !          2446:                printf( "\r\nMemInit%02d (0x%04X): 0x%08X", i, (uint16_t) r, l_MemInit_u32 );
        !          2447: #endif
        !          2448:        }
        !          2449: #ifdef U4_SHOW_REGS
        !          2450:        printf( "\r\n" );
        !          2451: #endif
        !          2452:        /*
        !          2453:         * Kick off memory init sequence & wait for completion
        !          2454:         */
        !          2455:        store32_ci( MemProgCntl_R, IBIT(0) );
        !          2456: 
        !          2457:        do {
        !          2458:                i = load32_ci( MemProgCntl_R );
        !          2459:        } while( ( i & IBIT(1) ) == 0 );
        !          2460: 
        !          2461: }
        !          2462: 
        !          2463: /*
        !          2464:  * static DIMM configuartion settings
        !          2465:  */
        !          2466: static reg_statics_t reg_statics_maui[NUM_SPEED_IDX] = {
        !          2467:        {       /* 400 Mhz */
        !          2468:                .RRMux          = 1,
        !          2469:                .WRMux          = 1,
        !          2470:                .WWMux          = 1,
        !          2471:                .RWMux          = 1,
        !          2472: 
        !          2473:                .MemRdQCnfg     = 0x20020820,
        !          2474:                .MemWrQCnfg     = 0x40041040,
        !          2475:                .MemQArb        = 0x00000000,
        !          2476:                .MemRWArb       = 0x30413cc0,
        !          2477: 
        !          2478:                .ODTCntl        = 0x60000000,
        !          2479:                .IOPadCntl      = 0x001a4000,
        !          2480:                .MemPhyModeCntl = 0x00000000,
        !          2481:                .OCDCalCntl     = 0x00000000,
        !          2482:                .OCDCalCmd      = 0x00000000,
        !          2483: 
        !          2484:                .CKDelayL       = 0x34000000,
        !          2485:                .CKDelayU       = 0x34000000,
        !          2486: 
        !          2487:                .MemBusCnfg     = 0x00000050                  |
        !          2488:                                  ( (   MAX_RMD       << 28 ) |
        !          2489:                                    ( ( MAX_RMD - 2 ) << 24 ) ),
        !          2490: 
        !          2491:                .CAS1Dly0       = 0,
        !          2492:                .CAS1Dly1       = 0,
        !          2493: 
        !          2494:                .ByteWrClkDel   = {
        !          2495:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2496:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2497:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2498:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2499:                        0x00000000, 0x00000000
        !          2500:                },
        !          2501:                .ReadStrobeDel  = {
        !          2502:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2503:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2504:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2505:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2506:                        0x00000000, 0x00000000
        !          2507:                }
        !          2508: 
        !          2509:        },
        !          2510:        {       /* 533 Mhz */
        !          2511:                .RRMux          = 1,
        !          2512:                .WRMux          = 1,
        !          2513:                .WWMux          = 1,
        !          2514:                .RWMux          = 1,
        !          2515: 
        !          2516:                .MemRdQCnfg     = 0x20020820,
        !          2517:                .MemWrQCnfg     = 0x40041040,
        !          2518:                .MemQArb        = 0x00000000,
        !          2519:                .MemRWArb       = 0x30413cc0,
        !          2520: 
        !          2521:                .ODTCntl        = 0x60000000,
        !          2522:                .IOPadCntl      = 0x001a4000,
        !          2523:                .MemPhyModeCntl = 0x00000000,
        !          2524:                .OCDCalCntl     = 0x00000000,
        !          2525:                .OCDCalCmd      = 0x00000000,
        !          2526: 
        !          2527:                .CKDelayL       = 0x18000000,
        !          2528:                .CKDelayU       = 0x18000000,
        !          2529: 
        !          2530:                .MemBusCnfg     = 0x00002070                  |
        !          2531:                                  ( (   MAX_RMD       << 28 ) |
        !          2532:                                    ( ( MAX_RMD - 3 ) << 24 ) ),
        !          2533: 
        !          2534:                .CAS1Dly0       = 0,
        !          2535:                .CAS1Dly1       = 0,
        !          2536: 
        !          2537:                .ByteWrClkDel   = {
        !          2538: 
        !          2539:                        0x12000000, 0x12000000, 0x12000000 , 0x12000000,
        !          2540:                        0x12000000, 0x12000000, 0x12000000 , 0x12000000,
        !          2541:                        0x12000000, 0x12000000, 0x12000000 , 0x12000000,
        !          2542:                        0x12000000, 0x12000000, 0x12000000 , 0x12000000,
        !          2543:                        0x12000000, 0x12000000
        !          2544:                },
        !          2545:                .ReadStrobeDel  = {
        !          2546:                        0x00000000, 0x00000000, 0x00000000 , 0x00000000,
        !          2547:                        0x00000000, 0x00000000, 0x00000000 , 0x00000000,
        !          2548:                        0x00000000, 0x00000000, 0x00000000 , 0x00000000,
        !          2549:                        0x00000000, 0x00000000, 0x00000000 , 0x00000000,
        !          2550:                        0x00000000, 0x00000000
        !          2551:                }
        !          2552: 
        !          2553:        },
        !          2554:        {       /* 667 Mhz */
        !          2555:                .RRMux          = 1,
        !          2556:                .WRMux          = 1,
        !          2557:                .WWMux          = 1,
        !          2558:                .RWMux          = 3,
        !          2559: 
        !          2560:                .MemRdQCnfg     = 0x20020820,
        !          2561:                .MemWrQCnfg     = 0x40041040,
        !          2562:                .MemQArb        = 0x00000000,
        !          2563:                .MemRWArb       = 0x30413cc0,
        !          2564: 
        !          2565:                .ODTCntl        = 0x60000000,
        !          2566:                .IOPadCntl      = 0x001a4000,
        !          2567:                .MemPhyModeCntl = 0x00000000,
        !          2568:                .OCDCalCntl     = 0x00000000,
        !          2569:                .OCDCalCmd      = 0x00000000,
        !          2570: 
        !          2571:                .CKDelayL       = 0x0a000000,
        !          2572:                .CKDelayU       = 0x0a000000,
        !          2573: 
        !          2574:                .MemBusCnfg     = 0x000040a0                  |
        !          2575:                                  ( (   MAX_RMD       << 28 ) |
        !          2576:                                    ( ( MAX_RMD - 3 ) << 24 ) ),
        !          2577: 
        !          2578:                .CAS1Dly0       = 2,
        !          2579:                .CAS1Dly1       = 2,
        !          2580: 
        !          2581:                .ByteWrClkDel   = {
        !          2582: 
        !          2583:                        0x12000000, 0x12000000, 0x12000000, 0x12000000,
        !          2584:                        0x12000000, 0x12000000, 0x12000000, 0x12000000,
        !          2585:                        0x12000000, 0x12000000, 0x12000000, 0x12000000,
        !          2586:                        0x12000000, 0x12000000, 0x12000000, 0x12000000,
        !          2587:                        0x12000000, 0x12000000
        !          2588: /*
        !          2589:                        0x31000000, 0x31000000, 0x31000000, 0x31000000,
        !          2590:                        0x31000000, 0x31000000, 0x31000000, 0x31000000,
        !          2591:                        0x31000000, 0x31000000, 0x31000000, 0x31000000,
        !          2592:                        0x31000000, 0x31000000, 0x31000000, 0x31000000,
        !          2593:                        0x31000000, 0x31000000
        !          2594: */
        !          2595:                },
        !          2596:                .ReadStrobeDel  = {
        !          2597:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2598:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2599:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2600:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2601:                        0x00000000, 0x00000000
        !          2602:                }
        !          2603: 
        !          2604:        }
        !          2605: };
        !          2606: 
        !          2607: static reg_statics_t reg_statics_bimini[NUM_SPEED_IDX] = {
        !          2608:        {       /* 400 Mhz */
        !          2609:                .RRMux          = 2,
        !          2610:                .WRMux          = 2,
        !          2611:                .WWMux          = 2,
        !          2612:                .RWMux          = 2,
        !          2613: 
        !          2614:                .MemRdQCnfg     = 0x20020820,
        !          2615:                .MemWrQCnfg     = 0x40041040,
        !          2616:                .MemQArb        = 0x00000000,
        !          2617:                .MemRWArb       = 0x30413cc0,
        !          2618: 
        !          2619:                .ODTCntl        = 0x40000000,
        !          2620:                .IOPadCntl      = 0x001a4000,
        !          2621:                .MemPhyModeCntl = 0x00000000,
        !          2622:                .OCDCalCntl     = 0x00000000,
        !          2623:                .OCDCalCmd      = 0x00000000,
        !          2624: 
        !          2625:                .CKDelayL       = 0x00000000,
        !          2626:                .CKDelayU       = 0x28000000,
        !          2627: 
        !          2628:                .MemBusCnfg     = 0x00552070                  |
        !          2629:                                  ( (   MAX_RMD       << 28 ) |
        !          2630:                                    ( ( MAX_RMD - 2 ) << 24 ) ),
        !          2631: 
        !          2632:                .CAS1Dly0       = 0,
        !          2633:                .CAS1Dly1       = 0,
        !          2634: 
        !          2635:                .ByteWrClkDel   = {
        !          2636:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2637:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2638:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2639:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2640:                        0x00000000, 0x00000000
        !          2641:                },
        !          2642:                .ReadStrobeDel  = {
        !          2643:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2644:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2645:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2646:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2647:                        0x00000000, 0x00000000
        !          2648:                }
        !          2649: 
        !          2650:        },
        !          2651:        {       /* 533 Mhz */
        !          2652:                .RRMux          = 3,
        !          2653:                .WRMux          = 3,
        !          2654:                .WWMux          = 3,
        !          2655:                .RWMux          = 3,
        !          2656: 
        !          2657:                .MemRdQCnfg     = 0x20020820,
        !          2658:                .MemWrQCnfg     = 0x40041040,
        !          2659:                .MemQArb        = 0x00000000,
        !          2660:                .MemRWArb       = 0x30413cc0,
        !          2661: 
        !          2662:                .ODTCntl        = 0x40000000,
        !          2663:                .IOPadCntl      = 0x001a4000,
        !          2664:                .MemPhyModeCntl = 0x00000000,
        !          2665:                .OCDCalCntl     = 0x00000000,
        !          2666:                .OCDCalCmd      = 0x00000000,
        !          2667: 
        !          2668:                .CKDelayL       = 0x00000000,
        !          2669:                .CKDelayU       = 0x20000000,
        !          2670: 
        !          2671:                .MemBusCnfg     = 0x00644190                  |
        !          2672:                                  ( (   MAX_RMD       << 28 ) |
        !          2673:                                    ( ( MAX_RMD - 3 ) << 24 ) ),
        !          2674: 
        !          2675:                .CAS1Dly0       = 2,
        !          2676:                .CAS1Dly1       = 2,
        !          2677: 
        !          2678:                .ByteWrClkDel   = {
        !          2679:                        0x14000000, 0x14000000, 0x14000000, 0x14000000,
        !          2680:                        0x14000000, 0x14000000, 0x14000000, 0x14000000,
        !          2681:                        0x14000000, 0x14000000, 0x14000000, 0x14000000,
        !          2682:                        0x14000000, 0x14000000, 0x14000000, 0x14000000,
        !          2683:                        0x14000000, 0x14000000
        !          2684:                },
        !          2685:                .ReadStrobeDel  = {
        !          2686:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2687:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2688:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2689:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2690:                        0x00000000, 0x00000000
        !          2691:                }
        !          2692: 
        !          2693:        },
        !          2694:        {       /* 667 Mhz */
        !          2695:                .RRMux          = 3,
        !          2696:                .WRMux          = 3,
        !          2697:                .WWMux          = 3,
        !          2698:                .RWMux          = 3,
        !          2699: 
        !          2700:                .MemRdQCnfg     = 0x20020820,
        !          2701:                .MemWrQCnfg     = 0x40041040,
        !          2702:                .MemQArb        = 0x00000000,
        !          2703:                .MemRWArb       = 0x30413cc0,
        !          2704: 
        !          2705:                .ODTCntl        = 0x40000000,
        !          2706:                .IOPadCntl      = 0x001a4000,
        !          2707:                .MemPhyModeCntl = 0x00000000,
        !          2708:                .OCDCalCntl     = 0x00000000,
        !          2709:                .OCDCalCmd      = 0x00000000,
        !          2710: 
        !          2711:                .CKDelayL       = 0x00000000,
        !          2712:                .CKDelayU       = 0x00000000,
        !          2713: 
        !          2714:                .MemBusCnfg     = 0x00666270                  |
        !          2715:                                  ( (   MAX_RMD       << 28 ) |
        !          2716:                                    ( ( MAX_RMD - 3 ) << 24 ) ),
        !          2717: 
        !          2718:                .CAS1Dly0       = 2,
        !          2719:                .CAS1Dly1       = 2,
        !          2720: 
        !          2721:                .ByteWrClkDel   = {
        !          2722:                        0x14000000, 0x14000000, 0x14000000, 0x14000000,
        !          2723:                        0x14000000, 0x14000000, 0x14000000, 0x14000000,
        !          2724:                        0x14000000, 0x14000000, 0x14000000, 0x14000000,
        !          2725:                        0x14000000, 0x14000000, 0x14000000, 0x14000000,
        !          2726:                        0x14000000, 0x14000000
        !          2727:                },
        !          2728:                .ReadStrobeDel  = {
        !          2729:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2730:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2731:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2732:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2733:                        0x00000000, 0x00000000
        !          2734:                }
        !          2735: 
        !          2736:        }
        !          2737: };
        !          2738: 
        !          2739: static reg_statics_t reg_statics_kauai[NUM_SPEED_IDX] = {
        !          2740:        {       /* 400 Mhz */
        !          2741:                .RRMux          = 0,
        !          2742:                .WRMux          = 0,
        !          2743:                .WWMux          = 0,
        !          2744:                .RWMux          = 0,
        !          2745: 
        !          2746:                .MemRdQCnfg     = 0,
        !          2747:                .MemWrQCnfg     = 0,
        !          2748:                .MemQArb        = 0,
        !          2749:                .MemRWArb       = 0,
        !          2750: 
        !          2751:                .ODTCntl        = 0,
        !          2752:                .IOPadCntl      = 0,
        !          2753:                .MemPhyModeCntl = 0,
        !          2754:                .OCDCalCntl     = 0,
        !          2755:                .OCDCalCmd      = 0,
        !          2756: 
        !          2757:                .CKDelayL       = 0,
        !          2758:                .CKDelayU       = 0,
        !          2759: 
        !          2760:                .MemBusCnfg     = 0,
        !          2761: 
        !          2762:                .CAS1Dly0       = 0,
        !          2763:                .CAS1Dly1       = 0,
        !          2764: 
        !          2765:                .ByteWrClkDel   = {
        !          2766:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2767:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2768:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2769:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2770:                        0x00000000, 0x00000000
        !          2771:                },
        !          2772:                .ReadStrobeDel  = {
        !          2773:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2774:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2775:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2776:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2777:                        0x00000000, 0x00000000
        !          2778:                }
        !          2779: 
        !          2780:        },
        !          2781:        {       /* 533 Mhz */
        !          2782:                .RRMux          = 0,
        !          2783:                .WRMux          = 0,
        !          2784:                .WWMux          = 0,
        !          2785:                .RWMux          = 0,
        !          2786: 
        !          2787:                .MemRdQCnfg     = 0,
        !          2788:                .MemWrQCnfg     = 0,
        !          2789:                .MemQArb        = 0,
        !          2790:                .MemRWArb       = 0,
        !          2791: 
        !          2792:                .ODTCntl        = 0,
        !          2793:                .IOPadCntl      = 0,
        !          2794:                .MemPhyModeCntl = 0,
        !          2795:                .OCDCalCntl     = 0,
        !          2796:                .OCDCalCmd      = 0,
        !          2797: 
        !          2798:                .CKDelayL       = 0,
        !          2799:                .CKDelayU       = 0,
        !          2800: 
        !          2801:                .MemBusCnfg     = 0,
        !          2802: 
        !          2803:                .CAS1Dly0       = 0,
        !          2804:                .CAS1Dly1       = 0,
        !          2805: 
        !          2806:                .ByteWrClkDel   = {
        !          2807:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2808:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2809:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2810:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2811:                        0x00000000, 0x00000000
        !          2812:                },
        !          2813:                .ReadStrobeDel  = {
        !          2814:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2815:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2816:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2817:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2818:                        0x00000000, 0x00000000
        !          2819:                }
        !          2820: 
        !          2821:        },
        !          2822:        {       /* 667 Mhz */
        !          2823:                .RRMux          = 0,
        !          2824:                .WRMux          = 0,
        !          2825:                .WWMux          = 0,
        !          2826:                .RWMux          = 0,
        !          2827: 
        !          2828:                .MemRdQCnfg     = 0,
        !          2829:                .MemWrQCnfg     = 0,
        !          2830:                .MemQArb        = 0,
        !          2831:                .MemRWArb       = 0,
        !          2832: 
        !          2833:                .ODTCntl        = 0,
        !          2834:                .IOPadCntl      = 0,
        !          2835:                .MemPhyModeCntl = 0,
        !          2836:                .OCDCalCntl     = 0,
        !          2837:                .OCDCalCmd      = 0,
        !          2838: 
        !          2839:                .CKDelayL       = 0,
        !          2840:                .CKDelayU       = 0,
        !          2841: 
        !          2842:                .MemBusCnfg     = 0,
        !          2843: 
        !          2844:                .CAS1Dly0       = 0,
        !          2845:                .CAS1Dly1       = 0,
        !          2846: 
        !          2847:                .ByteWrClkDel   = {
        !          2848:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2849:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2850:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2851:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2852:                        0x00000000, 0x00000000
        !          2853:                },
        !          2854:                .ReadStrobeDel  = {
        !          2855:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2856:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2857:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2858:                        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        !          2859:                        0x00000000, 0x00000000
        !          2860:                }
        !          2861: 
        !          2862:        }
        !          2863: };
        !          2864: 
        !          2865: static int32_t
        !          2866: u4_start( eccerror_t *f_ecc_pt )
        !          2867: {
        !          2868:        /*
        !          2869:         * maximum runs for auto calibration
        !          2870:         */
        !          2871:        static const uint32_t MAX_ACERR = (uint32_t) 5;
        !          2872: 
        !          2873:        /*
        !          2874:         * fixed u4/DIMM timer/timing values for calculation
        !          2875:         */
        !          2876:        static const uint32_t TD      = (uint32_t) 2;   // u4 delay cycles for loading a timer
        !          2877:        static const uint32_t AL      = (uint32_t) 0;   // additional latency (fix)
        !          2878:        static const uint32_t BL      = (uint32_t) 4;   // burst length (fix)
        !          2879: 
        !          2880:        uint32_t              SPEED   = m_gendimm.m_speed_pu32[m_dclidx_u32];
        !          2881:        uint32_t              CL      = m_gendimm.m_clval_pu32[m_dclidx_u32];
        !          2882:        uint32_t              RL      = AL + CL;
        !          2883:        uint32_t              WL      = RL - 1;
        !          2884:        uint32_t              tCK     = m_gendimm.m_tCK_pu32[m_dclidx_u32];
        !          2885:        uint32_t              tRAS    = m_gendimm.m_tRAS_u32;
        !          2886:        uint32_t              tRTP    = m_gendimm.m_tRTP_u32;
        !          2887:        uint32_t              tRP     = m_gendimm.m_tRP_u32;
        !          2888:        uint32_t              tWR     = m_gendimm.m_tWR_u32;
        !          2889:        uint32_t              tRRD    = m_gendimm.m_tRRD_u32;
        !          2890:        uint32_t              tRC     = m_gendimm.m_tRC_u32;
        !          2891:        uint32_t              tRCD    = m_gendimm.m_tRCD_u32;
        !          2892:        uint32_t              tWTR    = m_gendimm.m_tWTR_u32;
        !          2893:        uint32_t              tRFC    = m_gendimm.m_tRFC_u32;
        !          2894:        uint32_t              tREF    = m_gendimm.m_tREF_u32;
        !          2895: 
        !          2896:        reg_statics_t *rst = 0;
        !          2897: 
        !          2898:        uint32_t       l_RAS0_u32;
        !          2899:        uint32_t       l_RAS1_u32;
        !          2900:        uint32_t       l_CAS0_u32;
        !          2901:        uint32_t       l_CAS1_u32;
        !          2902:        uint32_t       l_MemRfshCntl_u32;
        !          2903:        uint32_t       l_UsrCnfg_u32;
        !          2904:        uint32_t       l_DmCnfg_u32;
        !          2905: 
        !          2906:        uint32_t       l_MemArbWt_u32;
        !          2907:        uint32_t       l_MemRWArb_u32;
        !          2908:        uint32_t       l_MemBusCnfg_u32;
        !          2909: 
        !          2910:        auto_calib_t   l_ac_st;
        !          2911:        int32_t        l_ac_i32;
        !          2912:        uint32_t       l_acerr_i32;
        !          2913:        uint32_t       sidx;
        !          2914:        uint32_t       i, j, t0, t1;
        !          2915: 
        !          2916:        /*
        !          2917:         * set index for different 400/533/667 Mhz setup
        !          2918:         */
        !          2919:        switch( SPEED ) {
        !          2920:                case 400:
        !          2921:                case 533:
        !          2922:                case 667: {
        !          2923:                        sidx  = SPEED;
        !          2924:                        sidx -= 400;
        !          2925:                        sidx /= 133;
        !          2926:                        break;
        !          2927:                }
        !          2928: 
        !          2929:                default: {
        !          2930:                        #ifdef U4_DEBUG2
        !          2931:                        printf( "\r\n-> DIMM speed of %03u not supported\r\n",
        !          2932:                                m_gendimm.m_speed_pu32[m_dclidx_u32]  );
        !          2933:                        #endif
        !          2934:                        return RET_ERR;
        !          2935:                }
        !          2936: 
        !          2937:        }
        !          2938: 
        !          2939:        /*
        !          2940:         * setup pointer to the static register settings
        !          2941:         */
        !          2942:        if( IS_MAUI ) {
        !          2943:                rst = &reg_statics_maui[sidx];
        !          2944:        } else if( IS_BIMINI ) {
        !          2945:                rst = &reg_statics_bimini[sidx];
        !          2946:        } else if( IS_KAUAI ) {
        !          2947:                rst = &reg_statics_kauai[sidx];
        !          2948:        }
        !          2949: 
        !          2950:        /*
        !          2951:         * Switch off Fast Path by default for all DIMMs
        !          2952:         * running with more than 400Mhz
        !          2953:         */
        !          2954:        if( SPEED == 400 ) {
        !          2955:                or32_ci( APIMemRdCfg_R, IBIT(30) );
        !          2956:                #ifdef U4_INFO
        !          2957:                printf( "  [fastpath        :        ON]\r\n" );
        !          2958:                #endif
        !          2959:        } else {
        !          2960:                and32_ci( APIMemRdCfg_R, ~IBIT(30) );
        !          2961:                #ifdef U4_INFO
        !          2962:                printf( "  [fastpath        :       OFF]\r\n" );
        !          2963:                #endif
        !          2964:        }
        !          2965: 
        !          2966: 
        !          2967:        #ifdef U4_INFO
        !          2968:        printf( "  [register setup  :          ]" );
        !          2969:        #endif
        !          2970: 
        !          2971:        /*
        !          2972:         * setup RAS/CAS timers2
        !          2973:         * NOTE: subtract TD from all values because of the delay
        !          2974:         * caused by reloading timers (see spec)
        !          2975:         */
        !          2976: 
        !          2977:        /*
        !          2978:         * RAS Timer 0
        !          2979:         */
        !          2980:        // TiAtP = RND(tRAS) -> RAS0[0:4]
        !          2981:        l_RAS0_u32  = ( ( RND( tRAS )                           - TD ) << 27 );
        !          2982:        // TiRtP = AL + BL/2 - 2 + RND(tRTP) -> RAS01[5:9]
        !          2983:        l_RAS0_u32 |= ( ( AL + BL/2 - 2 + RND( tRTP )           - TD ) << 22 );
        !          2984:        // TiWtP = WL + BL/2 + RND(tWR) -> RAS0[10:14]
        !          2985:        l_RAS0_u32 |= ( ( WL + BL/2 + RND( tWR )                - TD ) << 17 );
        !          2986:        // TiPtA = RND(tRP) -> RAS0[15:19]
        !          2987:        l_RAS0_u32 |= ( ( RND( tRP )                            - TD ) << 12 );
        !          2988:        // TiPAtA = RND(tRP) or
        !          2989:        //          RND(tRP) + 1 for 8 bank devices -> RAS0[20:24]
        !          2990:        if( m_gendimm.m_bankcnt_u32 <= 4 ) {
        !          2991:                l_RAS0_u32 |= ( ( RND( tRP )                    - TD ) <<  7 );
        !          2992:        } else {
        !          2993:                l_RAS0_u32 |= ( ( RND( tRP ) + 1                - TD ) <<  7 );
        !          2994:        }
        !          2995: 
        !          2996:        /*
        !          2997:         * RAS Timer 1
        !          2998:         */
        !          2999:        // TiRAPtA = AL + BL/2 - 2 + RND(tRTP + tRP) -> RAS1[0:4]
        !          3000:        l_RAS1_u32  = ( ( AL + BL/2 - 2 + RND( tRTP + tRP )     - TD ) << 27 );
        !          3001:        // TiWAPtA = CL + AL + BL/2 - 1 + RND(tWR + tRP) -> RAS1[5:9]
        !          3002:        l_RAS1_u32 |= ( ( CL + AL + BL/2 - 1 + RND( tWR + tRP ) - TD ) << 22 );
        !          3003:        // TiAtARk = tRRD -> RAS1[10:14]
        !          3004:        l_RAS1_u32 |= ( ( RND( tRRD )                           - TD ) << 17 );
        !          3005:        // TiAtABk = tRC -> RAS1[15:19]
        !          3006:        l_RAS1_u32 |= ( ( RND( tRC )                            - TD ) << 12 );
        !          3007:        // TiAtRW = tRCD -> RAS1[20:24]
        !          3008:        l_RAS1_u32 |= ( ( RND( tRCD )                           - TD ) <<  7 );
        !          3009:        // TiSAtARk Win = 4 * tRRD + 2 -> RAS1[25:29]
        !          3010:        l_RAS1_u32 |= ( ( RND( 4 * tRRD ) + 2                   - TD ) <<  2 );
        !          3011: 
        !          3012:        /*
        !          3013:         * CAS Timer 0
        !          3014:         */
        !          3015:        // TiRtRRk = BL/2 -> CAS0[0:4]
        !          3016:        l_CAS0_u32  = ( ( BL/2                                  - TD ) << 27 );
        !          3017:        // TiRtRDm = BL/2 + 1 -> CAS0[5:9]
        !          3018:        l_CAS0_u32 |= ( ( BL/2 + 1                              - TD ) << 22 );
        !          3019:        // TiRtRSy = BL/2 + RRMux -> CAS0[10:14]
        !          3020:        l_CAS0_u32 |= ( ( BL/2 + rst->RRMux                     - TD ) << 17 );
        !          3021:        // TiWtRRk = CL - 1 + BL/2 + tWTR ->CAS0[15:19]
        !          3022:        l_CAS0_u32 |= ( ( CL - 1 + BL/2 + RND( tWTR )           - TD ) << 12 );
        !          3023:        // TiWtRDm = BL/2 + 1 -> CAS0[20:24]
        !          3024:        l_CAS0_u32 |= ( ( BL/2 + 1                              - TD ) <<  7 );
        !          3025:        // TiWtRSy = BL/2 + WRMux -> CAS0[25:29]
        !          3026:        l_CAS0_u32 |= ( ( BL/2 + rst->WRMux                     - TD ) <<  2 );
        !          3027: 
        !          3028:        /*
        !          3029:         * CAS Timer 1
        !          3030:         */
        !          3031:        // TiWtWRk = BL/2 -> CAS1[0:4]
        !          3032:        l_CAS1_u32  = ( ( BL/2                                  - TD ) << 27 );
        !          3033:        // TiWtWDm = BL/2 + 1 -> CAS1[5:9]
        !          3034:        l_CAS1_u32 |= ( ( BL/2 + 1                              - TD ) << 22 );
        !          3035:        // TiWtWSy = BL/2 + WWMux -> CAS1[10:14]
        !          3036:        l_CAS1_u32 |= ( ( BL/2 + rst->WWMux                     - TD ) << 17 );
        !          3037:        // TiRtWRk = BL/2 + 2 -> CAS1[15:19]
        !          3038:        l_CAS1_u32 |= ( ( BL/2 + 2            + rst->CAS1Dly0   - TD ) << 12 );
        !          3039:        // TiRtWDm = BL/2 + 2 -> CAS1[20:24]
        !          3040:        l_CAS1_u32 |= ( ( BL/2 + 2            + rst->CAS1Dly1   - TD ) <<  7 );
        !          3041:        // TiRtWSy = BL/2 + RWMux + 1 -> CAS1[25:29]
        !          3042:        l_CAS1_u32 |= ( ( BL/2 + rst->RWMux + 1                 - TD ) <<  2 );
        !          3043: 
        !          3044:        store32_ci( RASTimer0_R, l_RAS0_u32 );
        !          3045:        store32_ci( RASTimer1_R, l_RAS1_u32 );
        !          3046:        store32_ci( CASTimer0_R, l_CAS0_u32 );
        !          3047:        store32_ci( CASTimer1_R, l_CAS1_u32 );
        !          3048: 
        !          3049:        /*
        !          3050:         * Mem Refresh Control register
        !          3051:         */
        !          3052:        l_MemRfshCntl_u32  = ( ( ( tREF / tCK ) / 16 ) << 23 );
        !          3053:        l_MemRfshCntl_u32 |= ( ( RND( tRFC )    - TD ) <<  8 );
        !          3054:        store32_ci( MemRfshCntl_R, l_MemRfshCntl_u32 );
        !          3055: 
        !          3056:        /*
        !          3057:         * setup DmXCnfg registers
        !          3058:         */
        !          3059:        store32_ci( Dm0Cnfg_R, (uint32_t) 0x0 );
        !          3060:        store32_ci( Dm1Cnfg_R, (uint32_t) 0x0 );
        !          3061:        store32_ci( Dm2Cnfg_R, (uint32_t) 0x0 );
        !          3062:        store32_ci( Dm3Cnfg_R, (uint32_t) 0x0 );
        !          3063: 
        !          3064:        /*
        !          3065:         * create DmCnfg & UsrCnfg values out of group data
        !          3066:         */
        !          3067:        l_UsrCnfg_u32 = 0;
        !          3068:        for( i = 0; i < m_dgrcnt_u32; i++ ) {
        !          3069:                l_DmCnfg_u32  = ( m_dgrptr[i]->m_add2g_u32 << 27 );
        !          3070:                l_DmCnfg_u32 |= ( m_dgrptr[i]->m_sub2g_u32 << 19 );
        !          3071:                l_DmCnfg_u32 |= ( m_dgrptr[i]->m_memmd_u32 << 12 );
        !          3072:                l_DmCnfg_u32 |= ( m_dgrptr[i]->m_start_u32 <<  3 );
        !          3073:                l_DmCnfg_u32 |= ( m_dgrptr[i]->m_ss_u32    <<  1 );
        !          3074:                l_DmCnfg_u32 |= IBIT(31);       // enable bit
        !          3075: 
        !          3076:                /*
        !          3077:                 * write value into DmXCnfg registers
        !          3078:                 */
        !          3079:                for( j = 0; j < m_dgrptr[i]->m_dcnt_u32; j++ ) {
        !          3080:                        t0 = m_dgrptr[i]->m_dptr[j]->m_bank_u32;
        !          3081:                        t1 = Dm0Cnfg_R + 0x10 * t0;
        !          3082: 
        !          3083:                        if( load32_ci( t1 ) == 0 ) {
        !          3084:                                store32_ci( t1, l_DmCnfg_u32 );
        !          3085:                                l_UsrCnfg_u32 |=
        !          3086:                                ( m_dgrptr[i]->m_csmode_u32 << ( 30 - 2 * t0 ) );
        !          3087:                        }
        !          3088: 
        !          3089:                }
        !          3090: 
        !          3091:        }
        !          3092: 
        !          3093:        /*
        !          3094:         * setup UsrCnfg register
        !          3095:         *- cs mode is selected above
        !          3096:         *- Interleave on L2 cache line
        !          3097:         *- Usually closed page policy
        !          3098:         */
        !          3099:        l_UsrCnfg_u32 |=  IBIT(8);      // interleave on L2 cache line
        !          3100:        l_UsrCnfg_u32 &= ~IBIT(9);      // usually closed
        !          3101:        l_UsrCnfg_u32 |=  IBIT(10);
        !          3102:        store32_ci( UsrCnfg_R, l_UsrCnfg_u32 );
        !          3103: 
        !          3104:        /*
        !          3105:         * Memory Arbiter Weight Register
        !          3106:         */
        !          3107:        // CohWt  -> MemAWt[0:1]
        !          3108:        l_MemArbWt_u32  = ( (uint32_t) 1 << 30 );
        !          3109:        // NCohWt -> MemAWt[2:3]
        !          3110:        l_MemArbWt_u32 |= ( (uint32_t) 1 << 28 );
        !          3111:        // ScrbWt -> MemAWt[4:5]
        !          3112:        l_MemArbWt_u32 |= ( (uint32_t) 0 << 26 );
        !          3113:        store32_ci( MemArbWt_R, l_MemArbWt_u32 );
        !          3114: 
        !          3115:        /*
        !          3116:         * misc fixed register setup
        !          3117:         */
        !          3118:        store32_ci( ODTCntl_R,        rst->ODTCntl );
        !          3119:        store32_ci( IOPadCntl_R,      rst->IOPadCntl );
        !          3120:        store32_ci( MemPhyModeCntl_R, rst->MemPhyModeCntl );
        !          3121:        store32_ci( OCDCalCntl_R,     rst->OCDCalCntl );
        !          3122:        store32_ci( OCDCalCmd_R,      rst->OCDCalCmd );
        !          3123: 
        !          3124:        /*
        !          3125:         * CK Delay registers
        !          3126:         */
        !          3127:        store32_ci( CKDelayL_R, rst->CKDelayL );
        !          3128:        store32_ci( CKDelayU_R, rst->CKDelayU );
        !          3129: 
        !          3130:        /*
        !          3131:         * read/write strobe delays
        !          3132:         */
        !          3133:        store32_ci( ByteWrClkDelC0B00_R, rst->ByteWrClkDel[ 0] );
        !          3134:        store32_ci( ByteWrClkDelC0B01_R, rst->ByteWrClkDel[ 1] );
        !          3135:        store32_ci( ByteWrClkDelC0B02_R, rst->ByteWrClkDel[ 2] );
        !          3136:        store32_ci( ByteWrClkDelC0B03_R, rst->ByteWrClkDel[ 3] );
        !          3137:        store32_ci( ByteWrClkDelC0B04_R, rst->ByteWrClkDel[ 4] );
        !          3138:        store32_ci( ByteWrClkDelC0B05_R, rst->ByteWrClkDel[ 5] );
        !          3139:        store32_ci( ByteWrClkDelC0B06_R, rst->ByteWrClkDel[ 6] );
        !          3140:        store32_ci( ByteWrClkDelC0B07_R, rst->ByteWrClkDel[ 7] );
        !          3141:        store32_ci( ByteWrClkDelC0B16_R, rst->ByteWrClkDel[16] );
        !          3142:        store32_ci( ByteWrClkDelC0B08_R, rst->ByteWrClkDel[ 8] );
        !          3143:        store32_ci( ByteWrClkDelC0B09_R, rst->ByteWrClkDel[ 9] );
        !          3144:        store32_ci( ByteWrClkDelC0B10_R, rst->ByteWrClkDel[10] );
        !          3145:        store32_ci( ByteWrClkDelC0B11_R, rst->ByteWrClkDel[11] );
        !          3146:        store32_ci( ByteWrClkDelC0B12_R, rst->ByteWrClkDel[12] );
        !          3147:        store32_ci( ByteWrClkDelC0B13_R, rst->ByteWrClkDel[13] );
        !          3148:        store32_ci( ByteWrClkDelC0B14_R, rst->ByteWrClkDel[14] );
        !          3149:        store32_ci( ByteWrClkDelC0B15_R, rst->ByteWrClkDel[15] );
        !          3150:        store32_ci( ByteWrClkDelC0B17_R, rst->ByteWrClkDel[17] );
        !          3151:        store32_ci( ReadStrobeDelC0B00_R, rst->ReadStrobeDel[ 0] );
        !          3152:        store32_ci( ReadStrobeDelC0B01_R, rst->ReadStrobeDel[ 1] );
        !          3153:        store32_ci( ReadStrobeDelC0B02_R, rst->ReadStrobeDel[ 2] );
        !          3154:        store32_ci( ReadStrobeDelC0B03_R, rst->ReadStrobeDel[ 3] );
        !          3155:        store32_ci( ReadStrobeDelC0B04_R, rst->ReadStrobeDel[ 4] );
        !          3156:        store32_ci( ReadStrobeDelC0B05_R, rst->ReadStrobeDel[ 5] );
        !          3157:        store32_ci( ReadStrobeDelC0B06_R, rst->ReadStrobeDel[ 6] );
        !          3158:        store32_ci( ReadStrobeDelC0B07_R, rst->ReadStrobeDel[ 7] );
        !          3159:        store32_ci( ReadStrobeDelC0B16_R, rst->ReadStrobeDel[16] );
        !          3160:        store32_ci( ReadStrobeDelC0B08_R, rst->ReadStrobeDel[ 8] );
        !          3161:        store32_ci( ReadStrobeDelC0B09_R, rst->ReadStrobeDel[ 9] );
        !          3162:        store32_ci( ReadStrobeDelC0B10_R, rst->ReadStrobeDel[10] );
        !          3163:        store32_ci( ReadStrobeDelC0B11_R, rst->ReadStrobeDel[11] );
        !          3164:        store32_ci( ReadStrobeDelC0B12_R, rst->ReadStrobeDel[12] );
        !          3165:        store32_ci( ReadStrobeDelC0B13_R, rst->ReadStrobeDel[13] );
        !          3166:        store32_ci( ReadStrobeDelC0B14_R, rst->ReadStrobeDel[14] );
        !          3167:        store32_ci( ReadStrobeDelC0B15_R, rst->ReadStrobeDel[15] );
        !          3168:        store32_ci( ReadStrobeDelC0B17_R, rst->ReadStrobeDel[17] );
        !          3169: 
        !          3170:        /*
        !          3171:         * Mem Bus Configuration
        !          3172:         * initial setup used in auto calibration
        !          3173:         * final values will be written after
        !          3174:         * auto calibration has finished
        !          3175:         */
        !          3176:        l_MemBusCnfg_u32  = rst->MemBusCnfg;
        !          3177: 
        !          3178: /*     values calculation has been dropped, static values are used instead
        !          3179:        // WdbRqDly = 2 * (CL - 3) (registered DIMMs) -> MBC[16:19]
        !          3180:        l_MemBusCnfg_u32 += ( ( 2 * ( CL - 3 ) ) << 12 );
        !          3181:        // RdOEOnDly = 0 (typically)
        !          3182:        l_MemBusCnfg_u32 += ( ( 0 )              <<  8 );
        !          3183:        // RdOEOffDly = (2 * CL) - 4 -> MBC[24:27]
        !          3184:        // NOTE: formula is not working, changed to:
        !          3185:        // RdOEOffDly = (2 * CL) - 1
        !          3186:        l_MemBusCnfg_u32 += ( ( ( 2 * CL ) - 1 ) <<  4 );
        !          3187: */
        !          3188: 
        !          3189:        store32_ci( MemBusCnfg_R, l_MemBusCnfg_u32 );
        !          3190:        store32_ci( MemBusCnfg2_R, rst->MemBusCnfg & (uint32_t) 0xf0000000 );
        !          3191: 
        !          3192:        /*
        !          3193:         * reset verniers registers
        !          3194:         */
        !          3195:        store32_ci( RstLdEnVerniersC0_R, 0x0 );
        !          3196:        store32_ci( RstLdEnVerniersC1_R, 0x0 );
        !          3197:        store32_ci( RstLdEnVerniersC2_R, 0x0 );
        !          3198:        store32_ci( RstLdEnVerniersC3_R, 0x0 );
        !          3199:        store32_ci( ExtMuxVernier0_R,    0x0 );
        !          3200:        store32_ci( ExtMuxVernier1_R,    0x0 );
        !          3201: 
        !          3202:        /*
        !          3203:         * Queue Configuration
        !          3204:         */
        !          3205:        store32_ci( MemRdQCnfg_R, rst->MemRdQCnfg );
        !          3206:        store32_ci( MemWrQCnfg_R, rst->MemWrQCnfg );
        !          3207:        store32_ci( MemQArb_R,    rst->MemQArb );
        !          3208:        store32_ci( MemRWArb_R,   rst->MemRWArb );
        !          3209: 
        !          3210:        #ifdef U4_INFO
        !          3211:        printf( "\b\b\bOK\r\n" );
        !          3212:        #endif
        !          3213: 
        !          3214:        /*
        !          3215:         * start up clocks & wait for pll2 to stabilize
        !          3216:         */
        !          3217:        #ifdef U4_INFO
        !          3218:        printf( "  [start DDR clock :          ]" );
        !          3219:        #endif
        !          3220: 
        !          3221:        store32_ci( MemModeCntl_R, IBIT(0) | IBIT(8) );
        !          3222:        dly( 50000000 );
        !          3223: 
        !          3224:        #ifdef U4_INFO
        !          3225:        printf( "\b\b\bOK\r\n" );
        !          3226: 
        !          3227:        #endif
        !          3228: 
        !          3229:        /*
        !          3230:         * memory initialization sequence
        !          3231:         */
        !          3232:        #ifdef U4_INFO
        !          3233:        printf( "  [memory init     :          ]" );
        !          3234:        #endif
        !          3235:        u4_MemInitSequence( tRP, tWR, tRFC, CL, tCK, TD );
        !          3236:        #ifdef U4_INFO
        !          3237:        printf( "\b\b\bOK\r\n" );
        !          3238:        #endif
        !          3239: 
        !          3240:        /*
        !          3241:         * start ECC before auto calibration to enable ECC bytelane
        !          3242:         */
        !          3243:        store32_ci( MCCR_R, IBIT(0) );
        !          3244:        dly( 15000000 );
        !          3245: 
        !          3246:        /*
        !          3247:         * start up auto calibration
        !          3248:         */
        !          3249:        #ifdef U4_INFO
        !          3250:        printf( "  [auto calibration:          ]\b" );
        !          3251:        #endif
        !          3252: 
        !          3253:        /*
        !          3254:         * start auto calibration
        !          3255:        */
        !          3256:        l_acerr_i32 = 0;
        !          3257:        do {
        !          3258:                progbar();
        !          3259: 
        !          3260:                l_ac_i32 = u4_auto_calib( &l_ac_st );
        !          3261: 
        !          3262:                if( l_ac_i32 != 0 ) {
        !          3263:                        l_acerr_i32++;
        !          3264:                }
        !          3265: 
        !          3266:                dly( 15000000 );
        !          3267:        } while( ( l_ac_i32    != 0             ) &&
        !          3268:                 ( l_acerr_i32 <= MAX_ACERR     ) );
        !          3269: 
        !          3270:        if( l_acerr_i32 > MAX_ACERR ) {
        !          3271:                #ifdef U4_INFO
        !          3272:                printf( "\b\b\bERR\r\n" );
        !          3273:                #endif
        !          3274:                return RET_ERR;
        !          3275:        }
        !          3276: 
        !          3277:        /*
        !          3278:         * insert auto calibration results
        !          3279:         */
        !          3280:        store32_ci( MemBusCnfg_R,        l_ac_st.m_MemBusCnfg_u32 );
        !          3281:        store32_ci( MemBusCnfg2_R,       l_ac_st.m_MemBusCnfg2_u32 );
        !          3282:        store32_ci( RstLdEnVerniersC0_R, l_ac_st.m_RstLdEnVerniers_pu32[0] );
        !          3283:        store32_ci( RstLdEnVerniersC1_R, l_ac_st.m_RstLdEnVerniers_pu32[1] );
        !          3284:        store32_ci( RstLdEnVerniersC2_R, l_ac_st.m_RstLdEnVerniers_pu32[2] );
        !          3285:        store32_ci( RstLdEnVerniersC3_R, l_ac_st.m_RstLdEnVerniers_pu32[3] );
        !          3286: 
        !          3287:        /*
        !          3288:         * insert final timing value into MemRWArb
        !          3289:         */
        !          3290:        l_MemRWArb_u32  = ( ( l_ac_st.m_MemBusCnfg_u32 >> 28 /*RdMacDel*/) + 1 );
        !          3291:        l_MemRWArb_u32 *= 10;   // needed for rounding
        !          3292:        l_MemRWArb_u32 /= 2;    // due to spec
        !          3293:        l_MemRWArb_u32 += 9;    // round up
        !          3294:        l_MemRWArb_u32 /= 10;   // value is rounded now
        !          3295:        l_MemRWArb_u32  = l_MemRWArb_u32 + 6 - WL - TD;
        !          3296:        l_MemRWArb_u32 |= rst->MemRWArb;
        !          3297:        store32_ci( MemRWArb_R, l_MemRWArb_u32 );
        !          3298: 
        !          3299:        progbar();
        !          3300:        dly( 15000000 );
        !          3301: 
        !          3302:        /*
        !          3303:         * do initial scrubbing
        !          3304:         */
        !          3305:        *f_ecc_pt = u4_InitialScrub();
        !          3306: 
        !          3307:        switch( f_ecc_pt->m_err_i32 ) {
        !          3308:                case  RET_OK: {
        !          3309:                        #ifdef U4_INFO
        !          3310:                        printf( "\b\bOK\r\n" );
        !          3311:                        #endif
        !          3312:                        break;
        !          3313:                }
        !          3314: 
        !          3315:                case RET_ACERR_CE: {
        !          3316:                        #ifdef U4_INFO
        !          3317:                        printf( "\b\b\b\bWEAK][correctable errors during scrub (%u)]\r\n",
        !          3318:                                f_ecc_pt->m_cecnt_u32 );
        !          3319:                        #endif
        !          3320:                        break;
        !          3321:                }
        !          3322: 
        !          3323:                case RET_ACERR_UEWT:
        !          3324:                case RET_ACERR_UE: {
        !          3325:                        #ifdef U4_INFO
        !          3326:                        printf( "\b\b\bERR][uncorrectable errors during scrub (%u)]\r\n",
        !          3327:                                f_ecc_pt->m_uecnt_u32 );
        !          3328:                        #endif
        !          3329:                        return RET_ACERR_UE;
        !          3330:                }
        !          3331: 
        !          3332:        }
        !          3333: 
        !          3334:        /*
        !          3335:         * start continuous background scrub
        !          3336:         */
        !          3337:        #ifdef U4_INFO
        !          3338:        printf( "  [background scrub:          ]" );
        !          3339:        #endif
        !          3340: 
        !          3341:        u4_Scrub( BACKGROUND_SCRUB, 0, NULL );
        !          3342: 
        !          3343:        #ifdef U4_INFO
        !          3344:        printf( "\b\b\bOK\r\n" );
        !          3345:        #endif
        !          3346: 
        !          3347:        /*
        !          3348:         * finally clear API Exception register
        !          3349:         * (read to clear)
        !          3350:         */
        !          3351:        load32_ci( APIExcp_R );
        !          3352: 
        !          3353:        return RET_OK;
        !          3354: }
        !          3355: 
        !          3356: #undef RND
        !          3357: 
        !          3358: void
        !          3359: u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags)
        !          3360: 
        !          3361: {
        !          3362:        #define TEND                    99
        !          3363:        #define TCHK                    100
        !          3364:        static const uint64_t _2GB   = (uint64_t) 0x80000000;
        !          3365:        static const uint64_t _start = (uint64_t) 0x08000000;   // 128Mb
        !          3366:        static const uint64_t _bsize = (uint64_t) 0x08000000;   // 128MB
        !          3367:        static const uint64_t _line  = (uint64_t) 128;
        !          3368:        static const uint64_t _256MB = (uint64_t) 0x10000000;
        !          3369: 
        !          3370:        static const uint64_t PATTERN[] = {
        !          3371:                0x9090909090909090, 0x0020002000200020,
        !          3372:                0x0c0c0c0c0c0c0c0c, 0x8080808080808080,
        !          3373:                0x1004010004001041, 0x0000000000000000
        !          3374:        };
        !          3375: 
        !          3376:        uint64_t mend      = (uint64_t) 0x200000000;//m_memsize_u64;
        !          3377:        uint64_t numblocks = ( mend - _start ) / _bsize;        // 128Mb blocks
        !          3378:        uint64_t numlines  = _bsize / _line;
        !          3379:        uint64_t tstate    = 0;
        !          3380:        uint64_t tlast     = 0;
        !          3381:        uint64_t pidx      = 0;
        !          3382:        uint64_t rotr      = 0;
        !          3383:        uint64_t rotl      = 0;
        !          3384:        uint64_t block;
        !          3385:        uint64_t line;
        !          3386:        uint64_t addr;
        !          3387:        uint64_t i;
        !          3388:        uint64_t check = 0;
        !          3389:        uint64_t dcnt;
        !          3390:        uint64_t uerr = 0;
        !          3391:        uint64_t cerr = 0;
        !          3392:        uint64_t merr = 0;
        !          3393:        char     c;
        !          3394: 
        !          3395:        printf( "\n\nU4 memory test" );
        !          3396:        printf( "\n--------------" );
        !          3397: 
        !          3398:        /*
        !          3399:         * mask out UEC & CEC
        !          3400:         */
        !          3401:        or32_ci( MCCR_R, IBIT(6) | IBIT(7) );
        !          3402: 
        !          3403:        while( PATTERN[pidx] ) {
        !          3404: 
        !          3405:                switch( tstate )
        !          3406:                {
        !          3407:                case 0: {
        !          3408:                        printf( "\npattern fill 0x%08X%08X: ", (uint32_t) (PATTERN[pidx] >> 32), (uint32_t) PATTERN[pidx] );
        !          3409: 
        !          3410:                        /*
        !          3411:                         * first switch lines, then blocks. This way the CPU
        !          3412:                         * is not able to cache data
        !          3413:                         */
        !          3414:                        for( line = 0, dcnt = 0; line < numlines; line++ ) {
        !          3415: 
        !          3416:                                for( block = 0; block < numblocks; block++ ) {
        !          3417: 
        !          3418:                                        for( i = 0; i < _line; i += 8 ) {
        !          3419:                                                addr =  _start +
        !          3420:                                                        ( block * _bsize ) +
        !          3421:                                                        ( line * _line )   +
        !          3422:                                                        i;
        !          3423: 
        !          3424:                                                if( addr >= _2GB ) {
        !          3425:                                                        addr += _2GB;
        !          3426:                                                }
        !          3427: 
        !          3428:                                                *( (uint64_t *) addr ) = PATTERN[pidx];
        !          3429: 
        !          3430:                                                /*
        !          3431:                                                 * print out a dot every 256Mb
        !          3432:                                                 */
        !          3433:                                                dcnt += 8;
        !          3434:                                                if( dcnt == _256MB ) {
        !          3435:                                                        dcnt = 0;
        !          3436:                                                        printf( "*" );
        !          3437: 
        !          3438:                                                        if( io_getchar( &c ) ) {
        !          3439:                                                                goto mtend;
        !          3440:                                                        }
        !          3441: 
        !          3442:                                                }
        !          3443: 
        !          3444:                                        }
        !          3445: 
        !          3446:                                }
        !          3447: 
        !          3448:                        }
        !          3449: 
        !          3450:                        check  = PATTERN[pidx];
        !          3451:                        tlast  = 0;
        !          3452:                        tstate = TCHK;
        !          3453:                }       break;
        !          3454: 
        !          3455:                case 1: {
        !          3456:                        uint64_t one;
        !          3457: 
        !          3458:                        /*
        !          3459:                         * new check pattern
        !          3460: 
        !          3461:                         */
        !          3462:                        one     = ( ( check & 0x1 ) != 0 );
        !          3463:                        check >>= 1;
        !          3464:                        if( one ) {
        !          3465:                                check |= 0x8000000000000000;
        !          3466:                        }
        !          3467: 
        !          3468:                        printf( "\nrotate right 0x%08X%08X: ", (uint32_t) (check >> 32), (uint32_t) check );
        !          3469: 
        !          3470:                        /*
        !          3471:                         * first switch lines, then blocks. This way the CPU
        !          3472:                         * is not able to cache data
        !          3473:                         */
        !          3474:                        for( line = 0, dcnt = 0; line < numlines; line++ ) {
        !          3475: 
        !          3476:                                for( block = 0; block < numblocks; block++ ) {
        !          3477: 
        !          3478:                                        for( i = 0; i < _line; i += 8 ) {
        !          3479:                                                addr =  _start +
        !          3480:                                                        ( block * _bsize ) +
        !          3481:                                                        ( line * _line )   +
        !          3482:                                                        i;
        !          3483: 
        !          3484:                                                if( addr >= _2GB ) {
        !          3485:                                                        addr += _2GB;
        !          3486:                                                }
        !          3487: 
        !          3488:                                                *( (uint64_t *) addr ) >>= 1;
        !          3489: 
        !          3490:                                                if( one ) {
        !          3491:                                                        *( (uint64_t *) addr ) |=
        !          3492:                                                                (uint64_t) 0x8000000000000000;
        !          3493:                                                }
        !          3494: 
        !          3495:                                                /*
        !          3496:                                                 * print out a dot every 256Mb
        !          3497:                                                 */
        !          3498:                                                dcnt += 8;
        !          3499:                                                if( dcnt == _256MB ) {
        !          3500:                                                        dcnt = 0;
        !          3501:                                                        printf( "*" );
        !          3502: 
        !          3503:                                                        if( io_getchar( &c ) ) {
        !          3504:                                                                goto mtend;
        !          3505:                                                        }
        !          3506: 
        !          3507:                                                }
        !          3508: 
        !          3509:                                        }
        !          3510: 
        !          3511:                                }
        !          3512: 
        !          3513:                        }
        !          3514: 
        !          3515:                        tlast  = 1;
        !          3516:                        tstate = TCHK;
        !          3517:                }       break;
        !          3518: 
        !          3519:                case 2: {
        !          3520: 
        !          3521:                        if( rotr < 6 ) {
        !          3522:                                rotr++;
        !          3523:                                tstate = 1;
        !          3524:                        } else {
        !          3525:                                rotr   = 0;
        !          3526:                                tstate = 3;
        !          3527:                        }
        !          3528: 
        !          3529:                }       break;
        !          3530: 
        !          3531:                case 3: {
        !          3532:                        /*
        !          3533:                         * new check pattern
        !          3534:                         */
        !          3535:                        check ^= (uint64_t) ~0;
        !          3536: 
        !          3537:                        printf( "\ninverting    0x%08X%08X: ", (uint32_t) (check >> 32), (uint32_t) check );
        !          3538: 
        !          3539:                        /*
        !          3540:                         * first switch lines, then blocks. This way the CPU
        !          3541:                         * is not able to cache data
        !          3542:                         */
        !          3543:                        for( line = 0, dcnt = 0; line < numlines; line++ ) {
        !          3544: 
        !          3545:                                for( block = 0; block < numblocks; block++ ) {
        !          3546: 
        !          3547:                                        for( i = 0; i < _line; i += 8 ) {
        !          3548:                                                addr =  _start +
        !          3549:                                                        ( block * _bsize ) +
        !          3550:                                                        ( line * _line )   +
        !          3551:                                                        i;
        !          3552: 
        !          3553:                                                if( addr >= _2GB ) {
        !          3554:                                                        addr += _2GB;
        !          3555:                                                }
        !          3556: 
        !          3557:                                                *( (uint64_t *) addr ) ^= (uint64_t) ~0;
        !          3558: 
        !          3559:                                                /*
        !          3560:                                                 * print out a dot every 256Mb
        !          3561:                                                 */
        !          3562:                                                dcnt += 8;
        !          3563:                                                if( dcnt == _256MB ) {
        !          3564:                                                        dcnt = 0;
        !          3565:                                                        printf( "*" );
        !          3566: 
        !          3567:                                                        if( io_getchar( &c ) ) {
        !          3568:                                                                goto mtend;
        !          3569:                                                        }
        !          3570: 
        !          3571:                                                }
        !          3572: 
        !          3573:                                        }
        !          3574: 
        !          3575:                                }
        !          3576: 
        !          3577:                        }
        !          3578: 
        !          3579:                        tlast  = 3;
        !          3580:                        tstate = TCHK;
        !          3581:                }       break;
        !          3582: 
        !          3583:                case 4: {
        !          3584:                        uint64_t one;
        !          3585: 
        !          3586:                        /*
        !          3587:                         * new check pattern
        !          3588:                         */
        !          3589:                        one     = ( ( check & 0x8000000000000000 ) != 0 );
        !          3590:                        check <<= 1;
        !          3591:                        if( one ) {
        !          3592:                                check |= 0x1;
        !          3593:                        }
        !          3594: 
        !          3595:                        printf( "\nrotate left  0x%08X%08X: ", (uint32_t) (check >> 32), (uint32_t) check );
        !          3596: 
        !          3597:                        /*
        !          3598:                         * first switch lines, then blocks. This way the CPU
        !          3599:                         * is not able to cache data
        !          3600:                         */
        !          3601:                        for( line = 0, dcnt = 0; line < numlines; line++ ) {
        !          3602: 
        !          3603:                                for( block = 0; block < numblocks; block++ ) {
        !          3604: 
        !          3605:                                        for( i = 0; i < _line; i += 8 ) {
        !          3606:                                                addr =  _start +
        !          3607:                                                        ( block * _bsize ) +
        !          3608:                                                        ( line * _line )   +
        !          3609:                                                        i;
        !          3610: 
        !          3611:                                                if( addr >= _2GB ) {
        !          3612:                                                        addr += _2GB;
        !          3613:                                                }
        !          3614: 
        !          3615:                                                *( (uint64_t *) addr ) <<= 1;
        !          3616: 
        !          3617:                                                if( one ) {
        !          3618:                                                        *( (uint64_t *) addr ) |=
        !          3619:                                                                (uint64_t) 0x1;
        !          3620:                                                }
        !          3621: 
        !          3622:                                                /*
        !          3623:                                                 * print out a dot every 256Mb
        !          3624:                                                 */
        !          3625:                                                dcnt += 8;
        !          3626:                                                if( dcnt == _256MB ) {
        !          3627:                                                        dcnt = 0;
        !          3628:                                                        printf( "*" );
        !          3629: 
        !          3630:                                                        if( io_getchar( &c ) ) {
        !          3631:                                                                goto mtend;
        !          3632:                                                        }
        !          3633: 
        !          3634:                                                }
        !          3635: 
        !          3636:                                        }
        !          3637: 
        !          3638:                                }
        !          3639: 
        !          3640:                        }
        !          3641: 
        !          3642:                        tlast  = 4;
        !          3643:                        tstate = TCHK;
        !          3644:                }       break;
        !          3645: 
        !          3646:                case 5: {
        !          3647: 
        !          3648:                        if( rotl < 6 ) {
        !          3649:                                rotl++;
        !          3650:                                tstate = 4;
        !          3651:                        } else {
        !          3652:                                rotl   = 0;
        !          3653:                                tstate = 6;
        !          3654:                        }
        !          3655: 
        !          3656:                }       break;
        !          3657: 
        !          3658:                case 6: {
        !          3659:                        /*
        !          3660:                         * new check pattern
        !          3661:                         */
        !          3662:                        check *= ~check;
        !          3663:                        printf( "\nmultiply     0x%08X%08X: ", (uint32_t) (check >> 32), (uint32_t) check );
        !          3664: 
        !          3665:                        /*
        !          3666:                         * first switch lines, then blocks. This way the CPU
        !          3667:                         * is not able to cache data
        !          3668:                         */
        !          3669:                        for( line = 0, dcnt = 0; line < numlines; line++ ) {
        !          3670: 
        !          3671:                                for( block = 0; block < numblocks; block++ ) {
        !          3672: 
        !          3673:                                        for( i = 0; i < _line; i += 8 ) {
        !          3674:                                                addr =  _start +
        !          3675:                                                        ( block * _bsize ) +
        !          3676:                                                        ( line * _line )   +
        !          3677:                                                        i;
        !          3678: 
        !          3679:                                                if( addr >= _2GB ) {
        !          3680:                                                        addr += _2GB;
        !          3681:                                                }
        !          3682: 
        !          3683:                                                *( (uint64_t *) addr ) *= ~( *( (uint64_t *) addr ) );
        !          3684: 
        !          3685:                                                /*
        !          3686:                                                 * print out a dot every 256Mb
        !          3687:                                                 */
        !          3688:                                                dcnt += 8;
        !          3689:                                                if( dcnt == _256MB ) {
        !          3690:                                                        dcnt = 0;
        !          3691:                                                        printf( "*" );
        !          3692: 
        !          3693:                                                        if( io_getchar( &c ) ) {
        !          3694:                                                                goto mtend;
        !          3695:                                                        }
        !          3696: 
        !          3697:                                                }
        !          3698: 
        !          3699:                                        }
        !          3700: 
        !          3701:                                }
        !          3702: 
        !          3703:                        }
        !          3704: 
        !          3705:                        tlast  = TEND - 1;
        !          3706:                        tstate = TCHK;
        !          3707:                }       break;
        !          3708: 
        !          3709:                case TEND: {
        !          3710:                        pidx++;
        !          3711:                        tstate = 0;
        !          3712:                }       break;
        !          3713: 
        !          3714:                case TCHK: {
        !          3715:                        uint64_t err;
        !          3716:                        /*
        !          3717:                         * check data
        !          3718:                         */
        !          3719:                        printf( "\nchecking                       : " );
        !          3720: 
        !          3721:                        for( line = 0, dcnt = 0; line < numlines; line++ ) {
        !          3722: 
        !          3723:                                for( block = 0; block < numblocks; block++ ) {
        !          3724: 
        !          3725:                                        for( i = 0; i < _line; i += 8 ) {
        !          3726:                                                addr =  _start +
        !          3727:                                                        ( block * _bsize ) +
        !          3728:                                                        ( line * _line )   +
        !          3729:                                                        i;
        !          3730: 
        !          3731:                                                if( addr >= _2GB ) {
        !          3732:                                                        addr += _2GB;
        !          3733:                                                }
        !          3734: 
        !          3735:                                                err = ( *( (uint64_t *) addr ) != check );
        !          3736: 
        !          3737:                                                if( err ) {
        !          3738:                                                        merr++;
        !          3739:                                                }
        !          3740: 
        !          3741:                                                /*
        !          3742:                                                 * print out a dot every 256Mb
        !          3743:                                                 */
        !          3744:                                                dcnt += 8;
        !          3745:                                                if( dcnt == _256MB ) {
        !          3746:                                                        dcnt = 0;
        !          3747: 
        !          3748:                                                        if( err ) {
        !          3749:                                                                printf( "X" );
        !          3750:                                                        } else {
        !          3751:                                                                printf( "*" );
        !          3752:                                                        }
        !          3753: 
        !          3754:                                                        if( io_getchar( &c ) ) {
        !          3755:                                                                goto mtend;
        !          3756:                                                        }
        !          3757: 
        !          3758:                                                }
        !          3759: 
        !          3760:                                        }
        !          3761: 
        !          3762:                                }
        !          3763: 
        !          3764:                        }
        !          3765: 
        !          3766:                        err   = (uint64_t) load32_ci( MEAR1_R );
        !          3767:                        uerr += ( err >> 24 ) & (uint64_t) 0xff;
        !          3768:                        cerr += ( err >> 16 ) & (uint64_t) 0xff;
        !          3769: 
        !          3770:                        printf( " (UE: %02llX, CE: %02llX)", ( err >> 24 ) & (uint64_t) 0xff, ( err >> 16 ) & (uint64_t) 0xff );
        !          3771: 
        !          3772:                        tstate = tlast + 1;
        !          3773:                        tlast  = TCHK;
        !          3774:                }       break;
        !          3775: 
        !          3776:                }
        !          3777: 
        !          3778:        }
        !          3779: 
        !          3780: mtend:
        !          3781:        printf( "\n\nmemory test results" );
        !          3782:        printf( "\n-------------------" );
        !          3783:        printf( "\nuncorrectable errors: %u", (uint32_t) uerr );
        !          3784:        printf( "\ncorrectable errors  : %u", (uint32_t) cerr );
        !          3785:        printf( "\nread/write errors   : %u\n", (uint32_t) merr );
        !          3786: 
        !          3787:        and32_ci( MCCR_R, ~( IBIT(6) | IBIT(7) ) );
        !          3788: }
        !          3789: 
        !          3790: void
        !          3791: u4_dump(uint8_t argCnt, char *pArgs[], uint64_t flags)
        !          3792: {
        !          3793:        printf( "\r\n*** u4 register dump ***\r\n\n" );
        !          3794:        printf( "register      (offset): value\r\n" );
        !          3795:        printf( "----------------------------------\r\n" );
        !          3796:        printf( "Clock Control (0x%04X): 0x%08X\r\n", (uint16_t) ClkCntl_R, load32_ci( ClkCntl_R ) );
        !          3797:        printf( "PLL2 Control  (0x%04X): 0x%08X\r\n", (uint16_t) PLL2Cntl_R, load32_ci( PLL2Cntl_R ) );
        !          3798:        printf( "MemModeCntl   (0x%04X): 0x%08X\r\n", (uint16_t) MemModeCntl_R, load32_ci( MemModeCntl_R ) );
        !          3799:        printf( "RASTimer0     (0x%04X): 0x%08X\r\n", (uint16_t) RASTimer0_R, load32_ci( RASTimer0_R ) );
        !          3800:        printf( "RASTimer1     (0x%04X): 0x%08X\r\n", (uint16_t) RASTimer1_R, load32_ci( RASTimer1_R ) );
        !          3801:        printf( "CASTimer0     (0x%04X): 0x%08X\r\n", (uint16_t) CASTimer0_R, load32_ci( CASTimer0_R ) );
        !          3802:        printf( "CASTimer1     (0x%04X): 0x%08X\r\n", (uint16_t) CASTimer1_R, load32_ci( CASTimer1_R ) );
        !          3803:        printf( "MemRfshCntl   (0x%04X): 0x%08X\r\n", (uint16_t) MemRfshCntl_R, load32_ci( MemRfshCntl_R ) );
        !          3804:        printf( "Dm0Cnfg       (0x%04X): 0x%08X\r\n", (uint16_t) Dm0Cnfg_R, load32_ci( Dm0Cnfg_R ) );
        !          3805:        printf( "Dm1Cnfg       (0x%04X): 0x%08X\r\n", (uint16_t) Dm1Cnfg_R, load32_ci( Dm1Cnfg_R ) );
        !          3806:        printf( "Dm2Cnfg       (0x%04X): 0x%08X\r\n", (uint16_t) Dm2Cnfg_R, load32_ci( Dm2Cnfg_R ) );
        !          3807:        printf( "Dm3Cnfg       (0x%04X): 0x%08X\r\n", (uint16_t) Dm3Cnfg_R, load32_ci( Dm3Cnfg_R ) );
        !          3808:        printf( "UsrCnfg       (0x%04X): 0x%08X\r\n", (uint16_t) UsrCnfg_R, load32_ci( UsrCnfg_R ) );
        !          3809:        printf( "MemArbWt      (0x%04X): 0x%08X\r\n", (uint16_t) MemArbWt_R, load32_ci( MemArbWt_R ) );
        !          3810:        printf( "ODTCntl       (0x%04X): 0x%08X\r\n", (uint16_t) ODTCntl_R, load32_ci( ODTCntl_R ) );
        !          3811:        printf( "IOPadCntl     (0x%04X): 0x%08X\r\n", (uint16_t) IOPadCntl_R, load32_ci( IOPadCntl_R ) );
        !          3812:        printf( "MemPhyMode    (0x%04X): 0x%08X\r\n", (uint16_t) MemPhyModeCntl_R, load32_ci( MemPhyModeCntl_R ) );
        !          3813:        printf( "OCDCalCntl    (0x%04X): 0x%08X\r\n", (uint16_t) OCDCalCntl_R, load32_ci( OCDCalCntl_R ) );
        !          3814:        printf( "OCDCalCmd     (0x%04X): 0x%08X\r\n", (uint16_t) OCDCalCmd_R, load32_ci( OCDCalCmd_R ) );
        !          3815:        printf( "CKDelayL      (0x%04X): 0x%08X\r\n", (uint16_t) CKDelayL_R, load32_ci( CKDelayL_R ) );
        !          3816:        printf( "CKDelayH      (0x%04X): 0x%08X\r\n", (uint16_t) CKDelayU_R, load32_ci( CKDelayU_R ) );
        !          3817:        printf( "MemBusCnfg    (0x%04X): 0x%08X\r\n", (uint16_t) MemBusCnfg_R, load32_ci( MemBusCnfg_R ) );
        !          3818:        printf( "MemBusCnfg2   (0x%04X): 0x%08X\r\n", (uint16_t) MemBusCnfg2_R, load32_ci( MemBusCnfg2_R ) );
        !          3819:        printf( "MemRdQCnfg    (0x%04X): 0x%08X\r\n", (uint16_t) MemRdQCnfg_R, load32_ci( MemRdQCnfg_R ) );
        !          3820:        printf( "MemWrQCnfg    (0x%04X): 0x%08X\r\n", (uint16_t) MemWrQCnfg_R, load32_ci( MemWrQCnfg_R ) );
        !          3821:        printf( "MemQArb       (0x%04X): 0x%08X\r\n", (uint16_t) MemQArb_R, load32_ci( MemQArb_R ) );
        !          3822:        printf( "MemRWArb      (0x%04X): 0x%08X\r\n", (uint16_t) MemRWArb_R, load32_ci( MemRWArb_R ) );
        !          3823:        printf( "ByteWrClkDel  (0x%04X): 0x%08X\r\n", (uint16_t) ByteWrClkDelC0B00_R, load32_ci( ByteWrClkDelC0B00_R ) );
        !          3824:        printf( "ReadStrobeDel (0x%04X): 0x%08X\r\n", (uint16_t) ReadStrobeDelC0B00_R, load32_ci( ReadStrobeDelC0B00_R ) );
        !          3825:        printf( "RstLdEnVerC0  (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC0_R, load32_ci( RstLdEnVerniersC0_R ) );
        !          3826:        printf( "RstLdEnVerC1  (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC1_R, load32_ci( RstLdEnVerniersC1_R ) );
        !          3827:        printf( "RstLdEnVerC2  (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC2_R, load32_ci( RstLdEnVerniersC2_R ) );
        !          3828:        printf( "RstLdEnVerC3  (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC3_R, load32_ci( RstLdEnVerniersC3_R ) );
        !          3829:        printf( "APIMemRdCfg   (0x%04X): 0x%08X\r\n", (uint16_t) APIMemRdCfg_R, load32_ci( APIMemRdCfg_R ) );
        !          3830:        printf( "scrub start   (0x%04X): 0x%08X\r\n", (uint16_t) MSRSR_R, load32_ci( MSRSR_R ) );
        !          3831:        printf( "scrub end     (0x%04X): 0x%08X\r\n", (uint16_t) MSRER_R, load32_ci( MSRER_R ) );
        !          3832: }
        !          3833: 
        !          3834: int32_t
        !          3835: u4_memBegin( eccerror_t *f_ecc_pt )
        !          3836: {
        !          3837:        int32_t i;
        !          3838: 
        !          3839:        #ifdef U4_INFO
        !          3840:        printf( "\r\n" );
        !          3841:        printf( "U4 DDR2 memory controller setup V%u.%u\r\n",
        !          3842:                VER, SUBVER );
        !          3843:        printf( "------------------------------------\r\n" );
        !          3844:        printf( "> detected board              : " );
        !          3845: 
        !          3846:        if( IS_MAUI ) {
        !          3847:                printf( "MAUI" );
        !          3848:        } else if( IS_BIMINI ) {
        !          3849:                printf( "BIMINI" );
        !          3850:        } else if( IS_KAUAI ) {
        !          3851:                printf( "KAUAI" );
        !          3852:        } else {
        !          3853:                printf( "unknown!" );
        !          3854:                return RET_ERR;
        !          3855:        }
        !          3856:        #endif
        !          3857: 
        !          3858:        do {
        !          3859:                /*
        !          3860:                 * initialize variables
        !          3861:                 */
        !          3862:                m_memsize_u64    = 0;
        !          3863:                m_dcnt_u32       = 0;
        !          3864:                m_dgrcnt_u32     = 0;
        !          3865:                m_dclidx_u32     = 0;
        !          3866: 
        !          3867:                for( i = 0; i < NUM_SLOTS; i++ ) {
        !          3868:                        m_dptr[i] = NULL;
        !          3869:                        memset( ( void * ) &m_dimm[i], 0, sizeof( dimm_t ) );
        !          3870:                }
        !          3871: 
        !          3872:                for( i = 0; i < MAX_DGROUPS; i++ ) {
        !          3873:                        m_dgrptr[i] = NULL;
        !          3874:                        memset( ( void * ) &m_dgroup[i], 0, sizeof( dimm_t ) );
        !          3875:                }
        !          3876: 
        !          3877:                /*
        !          3878:                 * start configuration
        !          3879:                 */
        !          3880:                #ifdef U4_INFO
        !          3881:                printf( "\r\n> detected DIMM configuration : " );
        !          3882:                #endif
        !          3883: 
        !          3884:                i = ddr2_readSPDs();
        !          3885: 
        !          3886:                if( i != RET_OK ) {
        !          3887:                        #ifdef U4_INFO
        !          3888:                        printf( "\r\n-------------------------------------------------------------" );
        !          3889:                        printf( "\r\n  switching off memory bank(s) due to SPD integrity failure" );
        !          3890:                        printf( "\r\n-------------------------------------------------------------\r\n" );
        !          3891:                        #endif
        !          3892:                }
        !          3893: 
        !          3894:        } while( i != RET_OK );
        !          3895: 
        !          3896:        /*
        !          3897:         * check DIMM configuration
        !          3898:         */
        !          3899:        if( ddr2_setupDIMMcfg() != RET_OK ) {
        !          3900:                #ifdef U4_INFO
        !          3901:                printf( "> initialization failure.\r\n" );
        !          3902:                #endif
        !          3903:                return RET_ERR;
        !          3904:        }
        !          3905: 
        !          3906:        /*
        !          3907:         * create DIMM groups
        !          3908:         */
        !          3909:        u4_setupDIMMgroups();
        !          3910: 
        !          3911:        /*
        !          3912:         * start configuration of u4
        !          3913:         */
        !          3914:        u4_calcDIMMcnfg();
        !          3915: 
        !          3916:        if( u4_calcDIMMmemmode() != RET_OK ) {
        !          3917:                #ifdef U4_INFO
        !          3918:                printf( "> initialization failure.\r\n" );
        !          3919:                #endif
        !          3920:                return RET_ERR;
        !          3921:        }
        !          3922: 
        !          3923:        #ifdef U4_INFO
        !          3924:        printf( "%uMb @ %uMhz, CL %u\r\n",
        !          3925:                (uint32_t) ( m_memsize_u64 / 0x100000 ),
        !          3926:                m_gendimm.m_speed_pu32[m_dclidx_u32],
        !          3927:                m_gendimm.m_clval_pu32[m_dclidx_u32] );
        !          3928: 
        !          3929:        printf( "> initializing memory         :\r\n" );
        !          3930:        #endif
        !          3931: 
        !          3932:        if( u4_setup_core_clock() != RET_OK ) {
        !          3933:                #ifdef U4_INFO
        !          3934:                printf( "> initialization failure.\r\n" );
        !          3935:                #endif
        !          3936:                return RET_ERR;
        !          3937:        }
        !          3938: 
        !          3939:        i = u4_start( f_ecc_pt );
        !          3940:        if( i != RET_OK ) {
        !          3941:                #ifdef U4_INFO
        !          3942:                printf( "> initialization failure.\r\n" );
        !          3943:                #endif
        !          3944:                return i;
        !          3945:        }
        !          3946: 
        !          3947:        #ifdef U4_INFO
        !          3948:        printf( "  [flush cache     :          ]" );
        !          3949:        #endif
        !          3950: 
        !          3951:        flush_cache( 0x0, L2_CACHE_SIZE );
        !          3952: 
        !          3953:        #ifdef U4_INFO
        !          3954:        printf( "\b\b\bOK\r\n" );
        !          3955:        printf( "> initialization complete.\r\n" );
        !          3956:        #endif
        !          3957: 
        !          3958: #ifdef U4_SHOW_REGS
        !          3959:        u4_dump(0,0,0);
        !          3960: #endif
        !          3961: 
        !          3962:        return RET_OK;
        !          3963: }
        !          3964: 
        !          3965: static int32_t scrubstarted = 0;
        !          3966: 
        !          3967: void
        !          3968: u4_scrubStart(uint8_t argCnt, char *pArgs[], uint64_t flags )
        !          3969: {
        !          3970:        scrubstarted = 1;
        !          3971: 
        !          3972:        /*
        !          3973:         * setup scrub parameters
        !          3974:         */
        !          3975:        store32_ci( MSCR_R, 0 );                        // stop scrub
        !          3976:        store32_ci( MSRSR_R, 0x0 );                     // set start
        !          3977:        store32_ci( MSRER_R, 0x1c );                    // set end
        !          3978:        store32_ci( MSPR_R, 0x0 );                      // set pattern
        !          3979: 
        !          3980:        /*
        !          3981:         * clear out ECC error registers
        !          3982:         */
        !          3983:        store32_ci( MEAR0_R, 0x0 );
        !          3984:        store32_ci( MEAR1_R, 0x0 );
        !          3985:        store32_ci( MESR_R, 0x0 );
        !          3986: 
        !          3987:        /*
        !          3988:         * Setup Scrub Type
        !          3989:         */
        !          3990:        store32_ci( MSCR_R, IBIT(1) );
        !          3991:        printf( "\r\nscrub started\r\n" );
        !          3992: }
        !          3993: 
        !          3994: void
        !          3995: u4_scrubEnd(uint8_t argCnt, char *pArgs[], uint64_t flags )
        !          3996: {
        !          3997:        store32_ci( MSCR_R, 0 );                        // stop scrub
        !          3998:        scrubstarted = 0;
        !          3999:        printf( "\r\nscrub stopped\r\n" );
        !          4000: }
        !          4001: 
        !          4002: void
        !          4003: u4_memwr(uint8_t argCnt, char *pArgs[], uint64_t flags )
        !          4004: {
        !          4005:        uint32_t i;
        !          4006:        uint32_t v = 0;
        !          4007: 
        !          4008:        for( i = 0; i < 0x200; i += 4 ) {
        !          4009: 
        !          4010:                if( ( i & 0xf ) == 0 ) {
        !          4011:                        v = ~v;
        !          4012:                }
        !          4013: 
        !          4014:                store32_ci( i, v );
        !          4015:        }
        !          4016: 
        !          4017: }
        !          4018: 
        !          4019: void
        !          4020: u4memInit()
        !          4021: {
        !          4022:        static uint32_t l_isInit_u32 = 0;
        !          4023:        eccerror_t      l_ecc_t;
        !          4024:        int32_t         ret;
        !          4025: 
        !          4026:        /*
        !          4027:         * do not initialize memory more than once
        !          4028:         */
        !          4029:        if( l_isInit_u32 ) {
        !          4030:                #ifdef U4_INFO
        !          4031:                printf( "\r\n\nmemory already initialized\r\n" );
        !          4032:                #endif
        !          4033:                return;
        !          4034:        } else {
        !          4035:                l_isInit_u32 = 1;
        !          4036:        }
        !          4037: 
        !          4038:        /*
        !          4039:         * enable all DIMM banks on first run
        !          4040:         */
        !          4041:        m_bankoff_u32 = 0;
        !          4042: 
        !          4043:        do {
        !          4044:                ret = u4_memBegin( &l_ecc_t );
        !          4045: 
        !          4046:                if( ret < RET_ERR ) {
        !          4047:                        uint32_t l_bank_u32 = l_ecc_t.m_rank_u32 / 2;
        !          4048:                        printf( "\r\n-----------------------------------------------------" );
        !          4049:                        printf( "\r\n  switching off memory bank %u due to memory failure", l_bank_u32 );
        !          4050:                        printf( "\r\n-----------------------------------------------------" );
        !          4051:                        m_bankoff_u32 |= ( 1 << l_bank_u32 );
        !          4052:                }
        !          4053: 
        !          4054:        } while( ret < RET_ERR );
        !          4055: 
        !          4056: }
        !          4057: 
        !          4058: void
        !          4059: monitorDDR2( uint8_t argCnt, char *pArgs[], uint64_t flags )
        !          4060: {
        !          4061:        u4memInit();
        !          4062: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.