📄 sysi2cmpc107.c
字号:
* * RETURNS:* zero = operation successful* non-zero = operation failed*/int i2cCycleMpc107KnownState (void) { STATUS status; UINT timeOutCount; UINT statusReg; 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--) { i2cCycleMpc107Delay(1); statusReg = i2cPciIoctl(1, (UINT32)MPC107_I2C_STATUS_REG, 0, 0); SYNC; if (!(statusReg & MPC107_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); }/******************************************************************************* * i2cCycleMpc107Delay - perform interface's I2C delay routine * * This function's purpose is to perform whatever delay * required for the device.* * RETURNS:* none.*/void i2cCycleMpc107Delay ( int mSeconds /* time to delay in milliseconds */ ) { sysMpc107MsDelay(mSeconds); }/******************************************************************************** sysMpc107MsDelay - 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 sysMpc107MsDelay() 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 sysMpc107MsDelay ( 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 = sysMpc107GetDec(); while (decElapsed < totalDelta) { newval = sysMpc107GetDec(); if ( DELTA(oldval,newval) < 1000 ) decElapsed += DELTA(oldval,newval); /* no rollover */ else if (newval > oldval) decElapsed += abs((int)oldval); /* rollover */ oldval = newval; } }/******************************************************************************** sysMpc107GetDec - read from the Decrementer register SPR22.** This routine will read the contents the decrementer (SPR22)** From a C point of view, the routine is defined as follows:** UINT32 sysMpc107GetDec()** RETURNS: value of SPR22 (in r3)*/LOCAL UINT32 sysMpc107GetDec(void) { /* declare "dec" as a UINT assigned to register 3 */ register UINT32 dec __asm__ ("3"); /* * read the decrementer, put it in r3 and tell the compiler that r3 * has been modified. */ __asm__ (" mfspr %0,22" : "=r" (dec) : : "3"); /* Return the decrement value */ return(dec); }/** DEBUG FUNCTIONS **/#ifdef DEBUG_I2C/******************************************************************************** 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 LoPEC 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("$%.2x (&%.3d) %.2x\n", i, i, 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 LoPEC * 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 + -