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

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: 
1.1.1.2 ! root     3358: #if 0
1.1       root     3359: void
                   3360: u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags)
                   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: }
1.1.1.2 ! root     3789: #endif
1.1       root     3790: 
1.1.1.2 ! root     3791: #if 0
1.1       root     3792: void
                   3793: u4_dump(uint8_t argCnt, char *pArgs[], uint64_t flags)
                   3794: {
                   3795:        printf( "\r\n*** u4 register dump ***\r\n\n" );
                   3796:        printf( "register      (offset): value\r\n" );
                   3797:        printf( "----------------------------------\r\n" );
                   3798:        printf( "Clock Control (0x%04X): 0x%08X\r\n", (uint16_t) ClkCntl_R, load32_ci( ClkCntl_R ) );
                   3799:        printf( "PLL2 Control  (0x%04X): 0x%08X\r\n", (uint16_t) PLL2Cntl_R, load32_ci( PLL2Cntl_R ) );
                   3800:        printf( "MemModeCntl   (0x%04X): 0x%08X\r\n", (uint16_t) MemModeCntl_R, load32_ci( MemModeCntl_R ) );
                   3801:        printf( "RASTimer0     (0x%04X): 0x%08X\r\n", (uint16_t) RASTimer0_R, load32_ci( RASTimer0_R ) );
                   3802:        printf( "RASTimer1     (0x%04X): 0x%08X\r\n", (uint16_t) RASTimer1_R, load32_ci( RASTimer1_R ) );
                   3803:        printf( "CASTimer0     (0x%04X): 0x%08X\r\n", (uint16_t) CASTimer0_R, load32_ci( CASTimer0_R ) );
                   3804:        printf( "CASTimer1     (0x%04X): 0x%08X\r\n", (uint16_t) CASTimer1_R, load32_ci( CASTimer1_R ) );
                   3805:        printf( "MemRfshCntl   (0x%04X): 0x%08X\r\n", (uint16_t) MemRfshCntl_R, load32_ci( MemRfshCntl_R ) );
                   3806:        printf( "Dm0Cnfg       (0x%04X): 0x%08X\r\n", (uint16_t) Dm0Cnfg_R, load32_ci( Dm0Cnfg_R ) );
                   3807:        printf( "Dm1Cnfg       (0x%04X): 0x%08X\r\n", (uint16_t) Dm1Cnfg_R, load32_ci( Dm1Cnfg_R ) );
                   3808:        printf( "Dm2Cnfg       (0x%04X): 0x%08X\r\n", (uint16_t) Dm2Cnfg_R, load32_ci( Dm2Cnfg_R ) );
                   3809:        printf( "Dm3Cnfg       (0x%04X): 0x%08X\r\n", (uint16_t) Dm3Cnfg_R, load32_ci( Dm3Cnfg_R ) );
                   3810:        printf( "UsrCnfg       (0x%04X): 0x%08X\r\n", (uint16_t) UsrCnfg_R, load32_ci( UsrCnfg_R ) );
                   3811:        printf( "MemArbWt      (0x%04X): 0x%08X\r\n", (uint16_t) MemArbWt_R, load32_ci( MemArbWt_R ) );
                   3812:        printf( "ODTCntl       (0x%04X): 0x%08X\r\n", (uint16_t) ODTCntl_R, load32_ci( ODTCntl_R ) );
                   3813:        printf( "IOPadCntl     (0x%04X): 0x%08X\r\n", (uint16_t) IOPadCntl_R, load32_ci( IOPadCntl_R ) );
                   3814:        printf( "MemPhyMode    (0x%04X): 0x%08X\r\n", (uint16_t) MemPhyModeCntl_R, load32_ci( MemPhyModeCntl_R ) );
                   3815:        printf( "OCDCalCntl    (0x%04X): 0x%08X\r\n", (uint16_t) OCDCalCntl_R, load32_ci( OCDCalCntl_R ) );
                   3816:        printf( "OCDCalCmd     (0x%04X): 0x%08X\r\n", (uint16_t) OCDCalCmd_R, load32_ci( OCDCalCmd_R ) );
                   3817:        printf( "CKDelayL      (0x%04X): 0x%08X\r\n", (uint16_t) CKDelayL_R, load32_ci( CKDelayL_R ) );
                   3818:        printf( "CKDelayH      (0x%04X): 0x%08X\r\n", (uint16_t) CKDelayU_R, load32_ci( CKDelayU_R ) );
                   3819:        printf( "MemBusCnfg    (0x%04X): 0x%08X\r\n", (uint16_t) MemBusCnfg_R, load32_ci( MemBusCnfg_R ) );
                   3820:        printf( "MemBusCnfg2   (0x%04X): 0x%08X\r\n", (uint16_t) MemBusCnfg2_R, load32_ci( MemBusCnfg2_R ) );
                   3821:        printf( "MemRdQCnfg    (0x%04X): 0x%08X\r\n", (uint16_t) MemRdQCnfg_R, load32_ci( MemRdQCnfg_R ) );
                   3822:        printf( "MemWrQCnfg    (0x%04X): 0x%08X\r\n", (uint16_t) MemWrQCnfg_R, load32_ci( MemWrQCnfg_R ) );
                   3823:        printf( "MemQArb       (0x%04X): 0x%08X\r\n", (uint16_t) MemQArb_R, load32_ci( MemQArb_R ) );
                   3824:        printf( "MemRWArb      (0x%04X): 0x%08X\r\n", (uint16_t) MemRWArb_R, load32_ci( MemRWArb_R ) );
                   3825:        printf( "ByteWrClkDel  (0x%04X): 0x%08X\r\n", (uint16_t) ByteWrClkDelC0B00_R, load32_ci( ByteWrClkDelC0B00_R ) );
                   3826:        printf( "ReadStrobeDel (0x%04X): 0x%08X\r\n", (uint16_t) ReadStrobeDelC0B00_R, load32_ci( ReadStrobeDelC0B00_R ) );
                   3827:        printf( "RstLdEnVerC0  (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC0_R, load32_ci( RstLdEnVerniersC0_R ) );
                   3828:        printf( "RstLdEnVerC1  (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC1_R, load32_ci( RstLdEnVerniersC1_R ) );
                   3829:        printf( "RstLdEnVerC2  (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC2_R, load32_ci( RstLdEnVerniersC2_R ) );
                   3830:        printf( "RstLdEnVerC3  (0x%04X): 0x%08X\r\n", (uint16_t) RstLdEnVerniersC3_R, load32_ci( RstLdEnVerniersC3_R ) );
                   3831:        printf( "APIMemRdCfg   (0x%04X): 0x%08X\r\n", (uint16_t) APIMemRdCfg_R, load32_ci( APIMemRdCfg_R ) );
                   3832:        printf( "scrub start   (0x%04X): 0x%08X\r\n", (uint16_t) MSRSR_R, load32_ci( MSRSR_R ) );
                   3833:        printf( "scrub end     (0x%04X): 0x%08X\r\n", (uint16_t) MSRER_R, load32_ci( MSRER_R ) );
                   3834: }
1.1.1.2 ! root     3835: #endif
1.1       root     3836: 
1.1.1.2 ! root     3837: static int32_t
1.1       root     3838: u4_memBegin( eccerror_t *f_ecc_pt )
                   3839: {
                   3840:        int32_t i;
                   3841: 
                   3842:        #ifdef U4_INFO
                   3843:        printf( "\r\n" );
                   3844:        printf( "U4 DDR2 memory controller setup V%u.%u\r\n",
                   3845:                VER, SUBVER );
                   3846:        printf( "------------------------------------\r\n" );
                   3847:        printf( "> detected board              : " );
                   3848: 
                   3849:        if( IS_MAUI ) {
                   3850:                printf( "MAUI" );
                   3851:        } else if( IS_BIMINI ) {
                   3852:                printf( "BIMINI" );
                   3853:        } else if( IS_KAUAI ) {
                   3854:                printf( "KAUAI" );
                   3855:        } else {
                   3856:                printf( "unknown!" );
                   3857:                return RET_ERR;
                   3858:        }
                   3859:        #endif
                   3860: 
                   3861:        do {
                   3862:                /*
                   3863:                 * initialize variables
                   3864:                 */
                   3865:                m_memsize_u64    = 0;
                   3866:                m_dcnt_u32       = 0;
                   3867:                m_dgrcnt_u32     = 0;
                   3868:                m_dclidx_u32     = 0;
                   3869: 
                   3870:                for( i = 0; i < NUM_SLOTS; i++ ) {
                   3871:                        m_dptr[i] = NULL;
                   3872:                        memset( ( void * ) &m_dimm[i], 0, sizeof( dimm_t ) );
                   3873:                }
                   3874: 
                   3875:                for( i = 0; i < MAX_DGROUPS; i++ ) {
                   3876:                        m_dgrptr[i] = NULL;
                   3877:                        memset( ( void * ) &m_dgroup[i], 0, sizeof( dimm_t ) );
                   3878:                }
                   3879: 
                   3880:                /*
                   3881:                 * start configuration
                   3882:                 */
                   3883:                #ifdef U4_INFO
                   3884:                printf( "\r\n> detected DIMM configuration : " );
                   3885:                #endif
                   3886: 
                   3887:                i = ddr2_readSPDs();
                   3888: 
                   3889:                if( i != RET_OK ) {
                   3890:                        #ifdef U4_INFO
                   3891:                        printf( "\r\n-------------------------------------------------------------" );
                   3892:                        printf( "\r\n  switching off memory bank(s) due to SPD integrity failure" );
                   3893:                        printf( "\r\n-------------------------------------------------------------\r\n" );
                   3894:                        #endif
                   3895:                }
                   3896: 
                   3897:        } while( i != RET_OK );
                   3898: 
                   3899:        /*
                   3900:         * check DIMM configuration
                   3901:         */
                   3902:        if( ddr2_setupDIMMcfg() != RET_OK ) {
                   3903:                #ifdef U4_INFO
                   3904:                printf( "> initialization failure.\r\n" );
                   3905:                #endif
                   3906:                return RET_ERR;
                   3907:        }
                   3908: 
                   3909:        /*
                   3910:         * create DIMM groups
                   3911:         */
                   3912:        u4_setupDIMMgroups();
                   3913: 
                   3914:        /*
                   3915:         * start configuration of u4
                   3916:         */
                   3917:        u4_calcDIMMcnfg();
                   3918: 
                   3919:        if( u4_calcDIMMmemmode() != RET_OK ) {
                   3920:                #ifdef U4_INFO
                   3921:                printf( "> initialization failure.\r\n" );
                   3922:                #endif
                   3923:                return RET_ERR;
                   3924:        }
                   3925: 
                   3926:        #ifdef U4_INFO
                   3927:        printf( "%uMb @ %uMhz, CL %u\r\n",
                   3928:                (uint32_t) ( m_memsize_u64 / 0x100000 ),
                   3929:                m_gendimm.m_speed_pu32[m_dclidx_u32],
                   3930:                m_gendimm.m_clval_pu32[m_dclidx_u32] );
                   3931: 
                   3932:        printf( "> initializing memory         :\r\n" );
                   3933:        #endif
                   3934: 
                   3935:        if( u4_setup_core_clock() != RET_OK ) {
                   3936:                #ifdef U4_INFO
                   3937:                printf( "> initialization failure.\r\n" );
                   3938:                #endif
                   3939:                return RET_ERR;
                   3940:        }
                   3941: 
                   3942:        i = u4_start( f_ecc_pt );
                   3943:        if( i != RET_OK ) {
                   3944:                #ifdef U4_INFO
                   3945:                printf( "> initialization failure.\r\n" );
                   3946:                #endif
                   3947:                return i;
                   3948:        }
                   3949: 
                   3950:        #ifdef U4_INFO
                   3951:        printf( "  [flush cache     :          ]" );
                   3952:        #endif
                   3953: 
                   3954:        flush_cache( 0x0, L2_CACHE_SIZE );
                   3955: 
                   3956:        #ifdef U4_INFO
                   3957:        printf( "\b\b\bOK\r\n" );
                   3958:        printf( "> initialization complete.\r\n" );
                   3959:        #endif
                   3960: 
                   3961: #ifdef U4_SHOW_REGS
                   3962:        u4_dump(0,0,0);
                   3963: #endif
                   3964: 
                   3965:        return RET_OK;
                   3966: }
                   3967: 
                   3968: 
1.1.1.2 ! root     3969: #if 0
        !          3970: static int32_t scrubstarted = 0;
1.1       root     3971: void
                   3972: u4_scrubStart(uint8_t argCnt, char *pArgs[], uint64_t flags )
                   3973: {
                   3974:        scrubstarted = 1;
                   3975: 
                   3976:        /*
                   3977:         * setup scrub parameters
                   3978:         */
                   3979:        store32_ci( MSCR_R, 0 );                        // stop scrub
                   3980:        store32_ci( MSRSR_R, 0x0 );                     // set start
                   3981:        store32_ci( MSRER_R, 0x1c );                    // set end
                   3982:        store32_ci( MSPR_R, 0x0 );                      // set pattern
                   3983: 
                   3984:        /*
                   3985:         * clear out ECC error registers
                   3986:         */
                   3987:        store32_ci( MEAR0_R, 0x0 );
                   3988:        store32_ci( MEAR1_R, 0x0 );
                   3989:        store32_ci( MESR_R, 0x0 );
                   3990: 
                   3991:        /*
                   3992:         * Setup Scrub Type
                   3993:         */
                   3994:        store32_ci( MSCR_R, IBIT(1) );
                   3995:        printf( "\r\nscrub started\r\n" );
                   3996: }
1.1.1.2 ! root     3997: #endif
1.1       root     3998: 
1.1.1.2 ! root     3999: #if 0
1.1       root     4000: void
                   4001: u4_scrubEnd(uint8_t argCnt, char *pArgs[], uint64_t flags )
                   4002: {
                   4003:        store32_ci( MSCR_R, 0 );                        // stop scrub
                   4004:        scrubstarted = 0;
                   4005:        printf( "\r\nscrub stopped\r\n" );
                   4006: }
1.1.1.2 ! root     4007: #endif
1.1       root     4008: 
1.1.1.2 ! root     4009: #if 0
1.1       root     4010: void
                   4011: u4_memwr(uint8_t argCnt, char *pArgs[], uint64_t flags )
                   4012: {
                   4013:        uint32_t i;
                   4014:        uint32_t v = 0;
                   4015: 
                   4016:        for( i = 0; i < 0x200; i += 4 ) {
                   4017: 
                   4018:                if( ( i & 0xf ) == 0 ) {
                   4019:                        v = ~v;
                   4020:                }
                   4021: 
                   4022:                store32_ci( i, v );
                   4023:        }
                   4024: 
                   4025: }
1.1.1.2 ! root     4026: #endif
1.1       root     4027: 
                   4028: void
                   4029: u4memInit()
                   4030: {
                   4031:        static uint32_t l_isInit_u32 = 0;
                   4032:        eccerror_t      l_ecc_t;
                   4033:        int32_t         ret;
                   4034: 
                   4035:        /*
                   4036:         * do not initialize memory more than once
                   4037:         */
                   4038:        if( l_isInit_u32 ) {
                   4039:                #ifdef U4_INFO
                   4040:                printf( "\r\n\nmemory already initialized\r\n" );
                   4041:                #endif
                   4042:                return;
                   4043:        } else {
                   4044:                l_isInit_u32 = 1;
                   4045:        }
                   4046: 
                   4047:        /*
                   4048:         * enable all DIMM banks on first run
                   4049:         */
                   4050:        m_bankoff_u32 = 0;
                   4051: 
                   4052:        do {
                   4053:                ret = u4_memBegin( &l_ecc_t );
                   4054: 
                   4055:                if( ret < RET_ERR ) {
                   4056:                        uint32_t l_bank_u32 = l_ecc_t.m_rank_u32 / 2;
                   4057:                        printf( "\r\n-----------------------------------------------------" );
                   4058:                        printf( "\r\n  switching off memory bank %u due to memory failure", l_bank_u32 );
                   4059:                        printf( "\r\n-----------------------------------------------------" );
                   4060:                        m_bankoff_u32 |= ( 1 << l_bank_u32 );
                   4061:                }
                   4062: 
                   4063:        } while( ret < RET_ERR );
                   4064: 
                   4065: }

unix.superglobalmegacorp.com

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