?? sysi2ckahlua.c
字號:
status = OK; /* * wait until the I2C bus is free. if it doesn't become free * within a *reasonable* amount of time, exit with an error. */ for (timeOutCount = 10; timeOutCount; timeOutCount--) { i2cCycleKahluaDelay(1); statusReg = i2cPciIoctl(1, (UINT32)KAHLUA_I2C_STATUS_REG, 0, 0); SYNC; if (!(statusReg & KAHLUA_I2C_STATUS_REG_MBB)) { status = OK; break; } /* * re-initialize the I2C if the BUS BUSY does not clear * after trying half the *reasonable* amount of reads of the * status register. */ if (!(timeOutCount % 5)) status = i2cDrvInit(I2C_DRV_TYPE); } if (!timeOutCount) status = ERROR; return (status); }/******************************************************************************* * i2cCycleKahluaDelay - perform interface's I2C delay routine * * This function's purpose is to perform whatever delay * required for the device.* * RETURNS:* none.*/void i2cCycleKahluaDelay ( int mSeconds /* time to delay in milliseconds */ ) { sysKahluaMsDelay(mSeconds); }/******************************************************************************** sysKahluaMsDelay - delay for the specified amount of time (MS)** This routine will delay for the specified amount of time by counting* decrementer ticks.** This routine is not dependent on a particular rollover value for* the decrementer, it should work no matter what the rollover* value is.** A small amount of count may be lost at the rollover point resulting in* the sysKahluaMsDelay() causing a slightly longer delay than requested.** This routine will produce incorrect results if the delay time requested* requires a count larger than 0xffffffff to hold the decrementer* elapsed tick count. For a System Bus Speed of 67 MHZ this amounts to* about 258 seconds.** RETURNS: N/A*/void sysKahluaMsDelay ( UINT delay /* length of time in MS to delay */ ) { register UINT32 oldval; /* decrementer value */ register UINT32 newval; /* decrementer value */ register UINT32 totalDelta; /* Dec. delta for entire delay period */ register UINT32 decElapsed; /* cumulative decrementer ticks */ /* Calculate delta of decrementer ticks for desired elapsed time. */ totalDelta = ((DEFAULT_BUS_CLOCK / 4) / 1000) * delay; /* * Now keep grabbing decrementer value and incrementing "decElapsed" until * we hit the desired delay value. Compensate for the fact that we may * read the decrementer at 0xffffffff before the interrupt service * routine has a chance to set in the rollover value. */ decElapsed = 0; oldval = sysKahluaGetDec(); while (decElapsed < totalDelta) { newval = sysKahluaGetDec(); if ( DELTA(oldval,newval) < 1000 ) decElapsed += DELTA(oldval,newval); /* no rollover */ else if (newval > oldval) decElapsed += abs((int)oldval); /* rollover */ oldval = newval; } }/******************************************************************************** sysKahluaGetDec - read from the Decrementer register SPR22.** This routine will read the contents the decrementer (SPR22)** RETURNS: value of SPR22 (in r3)*/LOCAL UINT32 sysKahluaGetDec(void) { return vxDecGet(); }/** DEBUG FUNCTIONS **/#ifdef DEBUG_I2C/* * SDRAM SPD Data for mv2100 SDRAM spec'd parts. 32mb_no_eccaddress data0000000 8008 040c 0801 4000 01a0 6000 8010 00010000010 8f04 0601 0100 0e0d 7000 001e 141e 3c080000020 2510 2510 0000 0000 0000 0000 0000 00000000030 0000 0000 0000 0000 0000 0000 0000 029932mb_eccaddress data0000000 8008 040c 0801 4800 01a0 6002 8010 10010000010 8f04 0601 0100 0e0d 7000 001e 141e 3c080000020 2510 2510 0000 0000 0000 0000 0000 00000000030 0000 0000 0000 0000 0000 0000 0000 02b364mb_no_eccaddress data0000000 8008 040c 0901 4000 01a0 6000 8008 00010000010 8f04 0601 0100 0e0d 7000 001e 141e 3c100000020 2510 2510 0000 0000 0000 0000 0000 00000000030 0000 0000 0000 0000 0000 0000 0000 029a64mb_eccaddress data0000000 8008 040c 0901 4800 01a0 6002 8008 08010000010 8f04 0601 0100 0e0d 7000 001e 141e 3c100000020 2510 2510 0000 0000 0000 0000 0000 00000000030 0000 0000 0000 0000 0000 0000 0000 02ac*//******************************************************************************** i2cProgramSPD - Demonstration function to program an SPD EEPROM.** This routine programs an SPD EEPROM with the contents of* defaultSPD. This program is enabled by defining DEBUG_I2C.** RETURNS: OK/ERROR*/int i2cProgramSPD ( int deviceAddress, /* address of I2C device - 0xa0, 0xa2 */ int size, /* Size of the bank: 32 or 64Mg bytes */ int ecc /* 1 = ECC capable parts */ ) { int index, checksum = 0; char verifyData[REAL_SPD_SIZE]; for (index=0;index<REAL_SPD_SIZE;index++) defaultSPD[index] = 0; defaultSPD[SPD_NUM_BYTES_INDEX] = 0x80; defaultSPD[SPD_DEVICE_SIZE_INDEX] = 0x08; defaultSPD[SPD_MEMORY_TYPE_INDEX] = 0x04; defaultSPD[SPD_ROW_ADDR_INDEX] = 0x0C; if (size == 32) { defaultSPD[SPD_COL_ADDR_INDEX] = 0x08; defaultSPD[SPD_DEV_WIDTH_INDEX] = 0x10; if (ecc) defaultSPD[SPD_ECC_WIDTH_INDEX] = 0x10; else defaultSPD[SPD_ECC_WIDTH_INDEX] = 0x0; defaultSPD[31] = 0x08; /* density */ if (ecc) defaultSPD[SPD_CHECKSUM_INDEX] = 0xb3; else defaultSPD[SPD_CHECKSUM_INDEX] = 0x99; } else { defaultSPD[SPD_COL_ADDR_INDEX] = 0x09; defaultSPD[SPD_DEV_WIDTH_INDEX] = 0x08; if (ecc) defaultSPD[SPD_ECC_WIDTH_INDEX] = 0x08; else defaultSPD[SPD_ECC_WIDTH_INDEX] = 0x0; defaultSPD[31] = 0x10; /* density */ if (ecc) defaultSPD[SPD_CHECKSUM_INDEX] = 0xac; else defaultSPD[SPD_CHECKSUM_INDEX] = 0x9a; } defaultSPD[SPD_NUM_DIMMBANKS_INDEX] = 0x01; if (ecc) defaultSPD[6] = 0x48; /* data width */ else defaultSPD[6] = 0x40; /* data width */ defaultSPD[7] = 0x00; /* data width continued */ defaultSPD[8] = 0x01; /* voltage inerface */ defaultSPD[SPD_TCYC_INDEX] = 0xa0; defaultSPD[10] = 0x60; /* highest CAS latency */ if (ecc) defaultSPD[SPD_DIMM_TYPE_INDEX] = 0x02; else defaultSPD[SPD_DIMM_TYPE_INDEX] = 0x0; defaultSPD[SPD_REFRESH_RATE_INDEX] = 0x80; defaultSPD[15] = 0x01; /* min back-to-back */ defaultSPD[16] = 0x8F; /* burst lengths */ defaultSPD[SPD_DEV_BANKS_INDEX] = 0x04; defaultSPD[SPD_CL_INDEX] = 0x06; defaultSPD[SPD_CS_LATENCY_INDEX] = 0x01; defaultSPD[SPD_WE_LATENCY_INDEX] = 0x01; defaultSPD[21] = 0x00; /* module attributes */ defaultSPD[22] = 0x0E; /* device attributes */ defaultSPD[SPD_TCYC_RCL_INDEX] = 0x0D; defaultSPD[24] = 0x70; /* access frm clk @ clkx1 */ defaultSPD[25] = 0x00; /* min cycle time */ defaultSPD[26] = 0x00; /* max frm clk @ clkx2 */ defaultSPD[SPD_TRP_INDEX] = 0x1E; defaultSPD[28] = 0x14; /* row act 2 row act(Trrd)*/ defaultSPD[SPD_TRCD_INDEX] = 0x1E; defaultSPD[SPD_TRAS_INDEX] = 0x3C; defaultSPD[32] = 0x25; /* superset information */ defaultSPD[33] = 0x10; defaultSPD[34] = 0x25; defaultSPD[35] = 0x10; defaultSPD[62] = 0x02; /* revision code */ i2cWrite (deviceAddress, 0, REAL_SPD_SIZE, defaultSPD); if (i2cRead (deviceAddress, 0, REAL_SPD_SIZE, verifyData) == OK) { for (index = 0; index < SPD_CHECKSUM_INDEX; index++) checksum += verifyData[index]; checksum %= 256; if (checksum != verifyData[SPD_CHECKSUM_INDEX]) { logMsg("Bad Checksum calculated: %x found: %x\n", checksum, verifyData[SPD_CHECKSUM_INDEX],0,0,0,0); } for (index=0;index<REAL_SPD_SIZE;index++) { if (verifyData[index] != defaultSPD[index]) { logMsg("SPD programming Failed: %d: %x != %x\r\n", index, verifyData[index], defaultSPD[index],0,0,0); return (ERROR); } } } return (OK); }/******************************************************************************** i2cShow - Dump i2c device.** This routine prints the number "size" bytes of EEPROM addresses at* "deviceAddress". Valid addresses for the mv2100 are 0xa0 and 0xa2* for SPD SDRAM banks and VPD_BRD_EEPROM_ADRS for the board's VPD* EEPROM. ** RETURNS: OK/ERROR*/int i2cShow ( int deviceAddress, /* address of I2C device - 0xa0, 0xa2 */ int size /* number of bytes to read/display */ ) { int i; char i2cBuff[REAL_SPD_SIZE] = {0}; if (size > REAL_SPD_SIZE) return (ERROR); if (i2cRead (deviceAddress, 0, size, i2cBuff) == ERROR) { logMsg("Driver returned error\n",0,0,0,0,0,0); return (ERROR); } for (i=0;i<size;i++) printf("%x ", i2cBuff[i]); printf("\r\n"); return (0); }/******************************************************************************** i2cFill - block fill a i2c device.** This routine writes the number "size" bytes of EEPROM addresses at* "deviceAddress" with the value "value". Valid addresses for the mv2100 * are 0xa0 and 0xa2 for SPD SDRAM banks and VPD_BRD_EEPROM_ADRS for the * board's VPD EEPROM. This will wipe out the existing data at the address. ** RETURNS: OK/ERROR*/int i2cFill ( int deviceAddress, /* address of I2C device - 0xa0, 0xa2 */ int size, /* number of bytes to write */ int value /* value to fill */ ) { int ii; char ptr[1]; if (size > REAL_SPD_SIZE) return (ERROR); for (ii=0;ii<size;ii++) { ptr[0] = value; i2cWrite (deviceAddress, ii, 1, ptr); } i2cShow (deviceAddress, size); return (OK); }#endif /* DEBUG_I2C */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -