BOOLEAN MemNResetRxFifoPtrON ( IN OUT MEM_NB_BLOCK *NBPtr, IN OUT VOID *OptParam ) { if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { MemNSetBitFieldNb (NBPtr, BFRxPtrInitReq, 1); MemNPollBitFieldNb (NBPtr, BFRxPtrInitReq, 0, PCI_ACCESS_TIMEOUT, FALSE); } return TRUE; }
UINT32 MemNcmnGetSetTrainDlyUnb ( IN OUT MEM_NB_BLOCK *NBPtr, IN UINT8 IsSet, IN TRN_DLY_TYPE TrnDly, IN DRBN DrbnVar, IN UINT16 Field ) { UINT16 Index; UINT16 Offset; UINT32 Value; UINT32 Address; UINT8 Dimm; UINT8 Rank; UINT8 Byte; UINT8 Nibble; UINT8 DimmNibble; Dimm = DRBN_DIMM (DrbnVar); Rank = DRBN_RANK (DrbnVar); Byte = DRBN_BYTE (DrbnVar); Nibble = DRBN_NBBL (DrbnVar); DimmNibble = DRBN_DIMM_NBBL (DrbnVar); ASSERT (Dimm < (NBPtr->CsPerChannel / NBPtr->CsPerDelay)); ASSERT (Byte <= ECC_DLY); if ((Byte == ECC_DLY) && (!NBPtr->MCTPtr->Status[SbEccDimms] || !NBPtr->IsSupported[EccByteTraining])) { // When ECC is not enabled if (IsSet) { // On write, ignore return 0; } else { // On read, redirect to byte 0 to correct fence averaging Byte = 0; } } switch (TrnDly) { case AccessRcvEnDly: Index = 0x10; break; case AccessWrDqsDly: Index = 0x30; break; case AccessWrDatDly: Index = 0x01; break; case AccessRdDqsDly: Index = 0x05; break; case AccessRdDqs2dDly: Index = 0x00; break; case AccessPhRecDly: Index = 0x50; break; default: Index = 0; IDS_ERROR_TRAP; } switch (TrnDly) { case AccessRcvEnDly: case AccessWrDqsDly: Index += (Dimm * 3); if (Byte & 0x04) { // if byte 4,5,6,7 Index += 0x10; } if (Byte & 0x02) { // if byte 2,3,6,7 Index++; } if (Byte > 7) { Index += 2; } Offset = 16 * (Byte % 2); Index |= (Rank << 8); Index |= (Nibble << 9); Address = Index; break; case AccessRdDqsDly: case AccessWrDatDly: if (NBPtr->IsSupported[DimmBasedOnSpeed]) { if (NBPtr->DCTPtr->Timings.Speed < DDR800_FREQUENCY) { // if DDR speed is below 800, use DIMM 0 delays for all DIMMs. Dimm = 0; } } Index += (Dimm * 0x100); if (Nibble) { if (Rank) { Index += 0xA0; } else { Index += 0x70; } } else if (Rank) { Index += 0x60; } // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need // to run AccessPhRecDly sequence. case AccessPhRecDly: Index += (Byte / 4); Offset = 8 * (Byte % 4); Address = Index; break; case AccessRdDqs2dDly: Address = 0x0D0F0000; Index += (DimmNibble >> 1) * 0x100; Index += 0x20; Index = Index + Dimm; Offset = 4 * ((DimmNibble & 0x01) * 2); Address += Index; break; default: Offset = 0; IDS_ERROR_TRAP; Address = Index; } MemNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); MemNPollBitFieldNb (NBPtr, BFDctAccessDone, 1, PCI_ACCESS_TIMEOUT, FALSE); Value = MemNGetBitFieldNb (NBPtr, BFDctAddlDataReg); if (TrnDly == AccessRdDqsDly) { NBPtr->FamilySpecificHook[AdjustRdDqsDlyOffset] (NBPtr, &Offset); } if (IsSet) { if (TrnDly == AccessPhRecDly) { Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03]; } if (TrnDly != AccessRdDqs2dDly) { Value = ((UINT32)Field << Offset) | (Value & (~((UINT32) ((TrnDly == AccessRcvEnDly) ? 0x3FF : 0xFF) << Offset))); } else { Value = ((UINT32)Field << Offset) | (Value & (~((UINT32) 0x1F << Offset))); } ASSERT (!NBPtr->IsSupported[ScrubberEn]); // Phy CSR write is not allowed after scrubber is enabled MemNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); Address |= DCT_ACCESS_WRITE; MemNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); MemNPollBitFieldNb (NBPtr, BFDctAccessDone, 1, PCI_ACCESS_TIMEOUT, FALSE); if (TrnDly == AccessPhRecDly) { NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value; } } else { if (TrnDly != AccessRdDqs2dDly) { Value = (Value >> Offset) & (UINT32) ((TrnDly == AccessRcvEnDly) ? 0x3FF : 0xFF); } else {