コード例 #1
0
ファイル: modtrdim.c プロジェクト: canistation/coreboot
/**
 *
 *
 *   This function set WrLvOdt for registered DDR3 dimms.
 *
 *     @param      *pMCTData
 *     @param[in]  *pDCTData - Pointer to buffer with information about each DCT
 *     @param      dimm - targeted dimm
 *
 *      @return    WrLvOdt
 */
u8 WrLvOdtRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm)
{
	u8 WrLvOdt1, i;
	WrLvOdt1 = 0;
	i = 0;
	while (i < 8) {
		if (pDCTData->DctCSPresent & (1 << i)) {
			WrLvOdt1 = (u8)bitTestSet(WrLvOdt1, i/2);
		}
		i += 2;
	}
	if (mctGet_NVbits(NV_MAX_DIMMS_PER_CH) == 2) {
		if ((pDCTData->DimmRanks[dimm] == 4) && (pDCTData->MaxDimmsInstalled != 1)) {
			if (dimm >= 2) {
				WrLvOdt1 = (u8)bitTestReset (WrLvOdt1, (dimm - 2));
			} else {
				WrLvOdt1 = (u8)bitTestReset (WrLvOdt1, (dimm + 2));
			}
		} else if ((pDCTData->DimmRanks[dimm] == 2) && (pDCTData->MaxDimmsInstalled == 1)) {
			/* the case for one DR on a 2 dimms per channel is special */
			WrLvOdt1 = 0x8;
		}
	}
	return WrLvOdt1;
}
コード例 #2
0
ファイル: mutilc_d.c プロジェクト: RafaelRMachado/Coreboot
/*-------------------------------------------------
 *  u32 get_ADD_DCT_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func,
 *                         u16 offset,u8 low, u8 high)
 *
 * Description:
 *     This routine gets the Additional PCT register from Function 2 by specified
 *   Node, DCT and PCI address
 *
 * Parameters:
 *   IN  OUT *DCTData - Pointer to buffer with information about each DCT
 *     IN        DCT - DCT number
 *              - 1 indicates DCT 1
 *              - 0 indicates DCT 0
 *              - 2 both DCTs
 *          Node - Node number
 *          Func - PCI Function number
 *          Offset - Additional PCI register number
 *          Low - Low bit of the bit field
 *          High - High bit of the bit field
 *
 *     OUT
 *-------------------------------------------------
 */
static u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData,
		u8 dct, u8 node, u8 func,
		u16 offset, u8 low, u8 high)
{
	u32 tempD;
	tempD = offset;
	tempD = bitTestReset(tempD,DctAccessWrite);
	set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
		PCI_MIN_LOW, PCI_MAX_HIGH, offset);
	while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
			DctAccessDone, DctAccessDone)) == 0);
	return (get_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
			low, high));
}
コード例 #3
0
ファイル: mhwlc_d.c プロジェクト: 0ida/coreboot
/*-----------------------------------------------------------------------------
 * void AgesaHwWlPhase1(SPDStruct *SPDData,MCTStruct *MCTData, DCTStruct *DCTData,
 *                  u8 Dimm, u8 Pass)
 *
 *  Description:
 *       This function initialized Hardware based write levelization phase 1
 *
 *   Parameters:
 *       IN  OUT   *SPDData - Pointer to buffer with information about each DIMMs
 *                            SPD information
 *                 *MCTData - Pointer to buffer with runtime parameters,
 *                 *DCTData - Pointer to buffer with information about each DCT
 *
 *       IN        DIMM - Logical DIMM number
 *                 Pass - First or Second Pass
 *       OUT
 *-----------------------------------------------------------------------------
 */
void AgesaHwWlPhase1(sMCTStruct *pMCTData, sDCTStruct *pDCTData,
		u8 dimm, u8 pass)
{
	u8 ByteLane;
	u32 Value, Addr;
	u16 Addl_Data_Offset, Addl_Data_Port;

	pDCTData->WLPass = pass;
	/* 1. Specify the target DIMM that is to be trained by programming
	 * F2x[1, 0]9C_x08[TrDimmSel].
	 */
	set_DCT_ADDR_Bits(pDCTData, pDCTData->DctTrain, pDCTData->NodeId, FUN_DCT,
			DRAM_ADD_DCT_PHY_CONTROL_REG, TrDimmSelStart,
			TrDimmSelEnd,(u32)dimm);
	/* 2. Prepare the DIMMs for write levelization using DDR3-defined
	 * MR commands. */
	prepareDimms(pMCTData, pDCTData,dimm, TRUE);
	/* 3. After the DIMMs are configured, BIOS waits 40 MEMCLKs to
	 *    satisfy DDR3-defined internal DRAM timing.
	 */
	pMCTData->AgesaDelay(40);
	/* 4. Configure the processor's DDR phy for write levelization training: */
	procConifg(pMCTData,pDCTData, dimm, pass);
	/* 5. Begin write levelization training:
	 *  Program F2x[1, 0]9C_x08[WrtLevelTrEn]=1. */
	if (pDCTData->LogicalCPUID & (AMD_DR_Cx | AMD_DR_Dx))
		set_DCT_ADDR_Bits(pDCTData, pDCTData->DctTrain, pDCTData->NodeId, FUN_DCT,
				DRAM_ADD_DCT_PHY_CONTROL_REG, WrtLvTrEn, WrtLvTrEn, 1);
	else
	{
		/* Broadcast write to all D3Dbyte chipset register offset 0xc
		 * Set bit 0 (wrTrain)
		 * Program bit 4 to nibble being trained (only matters for x4dimms)
		 * retain value of 3:2 (Trdimmsel)
		 * reset bit 5 (FrzPR)
		 */
		if (pDCTData->DctTrain)
		{
			Addl_Data_Offset=0x198;
			Addl_Data_Port=0x19C;
		}
		else
		{
			Addl_Data_Offset=0x98;
			Addl_Data_Port=0x9C;
		}
		Addr=0x0D00000C;
		AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Offset), 31, 0, &Addr);
		while ((get_Bits(pDCTData,FUN_DCT,pDCTData->NodeId, FUN_DCT, Addl_Data_Offset,
				DctAccessDone, DctAccessDone)) == 0);
		AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Port), 31, 0, &Value);
		Value = bitTestSet(Value, 0);	/* enable WL training */
		Value = bitTestReset(Value, 4); /* for x8 only */
		Value = bitTestReset(Value, 5); /* for hardware WL training */
		AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Port), 31, 0, &Value);
		Addr=0x4D030F0C;
		AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Offset), 31, 0, &Addr);
		while ((get_Bits(pDCTData,FUN_DCT,pDCTData->NodeId, FUN_DCT, Addl_Data_Offset,
				DctAccessDone, DctAccessDone)) == 0);
	}

	/* Wait 200 MEMCLKs. If executing pass 2, wait 32 MEMCLKs. */
	pMCTData->AgesaDelay(140);
	/* Program F2x[1, 0]9C_x08[WrtLevelTrEn]=0. */
	set_DCT_ADDR_Bits(pDCTData, pDCTData->DctTrain, pDCTData->NodeId, FUN_DCT,
			DRAM_ADD_DCT_PHY_CONTROL_REG, WrtLvTrEn, WrtLvTrEn, 0);
	/* Read from registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52
	 * to get the gross and fine delay settings
	 * for the target DIMM and save these values. */
	ByteLane = 0;
	while (ByteLane < MAX_BYTE_LANES)
	{
		getWLByteDelay(pDCTData,ByteLane, dimm);
		setWLByteDelay(pDCTData,ByteLane, dimm, 1);
		ByteLane++;
	}

	/* 6. Configure DRAM Phy Control Register so that the phy stops driving
	 *    write levelization ODT. */
	set_DCT_ADDR_Bits(pDCTData, pDCTData->DctTrain, pDCTData->NodeId, FUN_DCT,
			DRAM_ADD_DCT_PHY_CONTROL_REG, WrLvOdtEn, WrLvOdtEn, 0);

	/* Wait 10 MEMCLKs to allow for ODT signal settling. */
	pMCTData->AgesaDelay(10);

	/* 7. Program the target DIMM back to normal operation by configuring
	 * the following (See section 2.8.5.4.1.1
	 * [Phy Assisted Write Levelization] on page 97 pass 1, step #2):
	 * Configure all ranks of the target DIMM for normal operation.
	 * Enable the output drivers of all ranks of the target DIMM.
	 * For a two DIMM system, program the Rtt value for the target DIMM
	 * to the normal operating termination:
	 */
	prepareDimms(pMCTData, pDCTData,dimm,FALSE);
}