Beispiel #1
0
void mct_ForceAutoPrecharge_D(struct DCTStatStruc *pDCTstat, u32 dct)
{
	uint64_t tmp;
	u32 reg;
	u32 reg_off;
	u32 dev;
	u32 val;

	tmp = pDCTstat->LogicalCPUID;
	if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) {
		if (CheckNBCOFAutoPrechg(pDCTstat, dct)) {
			dev = pDCTstat->dev_dct;
			reg_off = 0x100 * dct;
			reg = 0x90 + reg_off;	/* Dram Configuration Lo */
			val = Get_NB32(dev, reg);
			val |= 1<<ForceAutoPchg;
			if (!pDCTstat->GangedMode)
				val |= 1<<BurstLength32;
			Set_NB32(dev, reg, val);

			reg = 0x88 + reg_off;	/* cx=Dram Timing Lo */
			val = Get_NB32(dev, reg);
			val |= 0x000F0000;	/* Trc = 0Fh */
			Set_NB32(dev, reg, val);
		}
	}
}
Beispiel #2
0
static inline uint32_t Get_NB32_DCT(uint32_t dev, uint8_t dct, uint32_t reg)
{
	if (is_fam15h()) {
		/* Obtain address of function 0x1 */
		uint32_t dev_map = (dev & (~(0x7 << 12))) | (0x1 << 12);
		fam15h_switch_dct(dev_map, dct);
		return Get_NB32(dev, reg);
	} else {
		return Get_NB32(dev, (0x100 * dct) + reg);
	}
}
Beispiel #3
0
static void mct_setMaxRdLatTrnVal_D(struct DCTStatStruc *pDCTstat,
					u8 Channel, u16 MaxRdLatVal)
{
	u8 i;
	u32 reg;
	u32 dev;
	u32 val;

	if (pDCTstat->GangedMode) {
		Channel = 0; // for safe
		for (i = 0; i < 2; i++)
			pDCTstat->CH_MaxRdLat[i] = MaxRdLatVal;
	} else {
		pDCTstat->CH_MaxRdLat[Channel] = MaxRdLatVal;
	}

	dev = pDCTstat->dev_dct;
	reg = 0x78 + Channel * 0x100;
	val = Get_NB32(dev, reg);
	val &= ~(0x3ff<<22);
	val |= MaxRdLatVal << 22;
	/* program MaxRdLatency to correspond with current delay */
	Set_NB32(dev, reg, val);

}
Beispiel #4
0
static void vErratum414(struct DCTStatStruc *pDCTstat)
{
     int dct=0;
    for(; dct < 2 ; dct++)
    {
        int dRAMConfigHi = Get_NB32(pDCTstat->dev_dct,0x94 + (0x100 * dct));
		int powerDown =  dRAMConfigHi & (1 << PowerDownEn );
		int ddr3 = dRAMConfigHi & (1 << Ddr3Mode );
        int dRAMMRS = Get_NB32(pDCTstat->dev_dct,0x84 + (0x100 * dct));
		int pchgPDModeSel = dRAMMRS & (1 << PchgPDModeSel);
	if (powerDown && ddr3 && pchgPDModeSel )
	{
	  Set_NB32(pDCTstat->dev_dct,0x84 + (0x100 * dct), dRAMMRS & ~(1 << PchgPDModeSel) );
	}
    }
}
Beispiel #5
0
void mct_BeforeDQSTrain_Samp_D(struct MCTStatStruc *pMCTstat,
				struct DCTStatStruc *pDCTstat)
{
	/* Bug#15115: Uncertainty In The Sync Chain Leads To Setup Violations
	 *  In TX FIFO
	 * Solution: BIOS should program DRAM Control Register[RdPtrInit] = 5h,
	 * (F2x[1, 0]78[3:0] = 5h).
	 *   Silicon Status: Fixed In Rev B0
	 */

	/* Bug#15880: Determine validity of reset settings for DDR PHY timing
	 *   regi..
	 * Solution: At least, set WrDqs fine delay to be 0 for DDR2 training.
	 */

	u32 dev;
	u32 reg_off;
	u32 index_reg;
	u32 index;
	u32 reg;
	u32 val;
	u32 tmp;
	u32 Channel;


	tmp = pDCTstat->LogicalCPUID;
	if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) {

		dev = pDCTstat->dev_dct;
		index = 0;

		for(Channel = 0; Channel<2; Channel++) {
			index_reg = 0x98 + 0x100 * Channel;
			val = Get_NB32_index_wait(dev, index_reg, 0x0d004007);
			val |= 0x3ff;
			Set_NB32_index_wait(dev, index_reg, 0x0d0f4f07, val);
		}

		for(Channel = 0; Channel<2; Channel++) {
			if(pDCTstat->GangedMode && Channel)
				break;
			reg_off = 0x100 * Channel;
			reg = 0x78 + reg_off;
			val = Get_NB32(dev, reg);
			val &= ~(0x07);
			val |= 5;
			Set_NB32(dev, reg, val);
		}

		for(Channel = 0; Channel<2; Channel++) {
			reg_off = 0x100 * Channel;
			val = 0;
			index_reg = 0x98 + reg_off;
			for( index = 0x30; index < (0x45 + 1); index++) {
				Set_NB32_index_wait(dev, index_reg, index, val);
			}
		}

	}
}
Beispiel #6
0
static inline void fam15h_switch_nb_pstate_config_reg(uint32_t dev, uint8_t nb_pstate)
{
	uint32_t dword;

	dword = Get_NB32(dev, 0x10c);
	dword &= ~(0x3 << 4);
	dword |= (nb_pstate & 0x3) << 4;
	Set_NB32(dev, 0x10c, dword);
}
Beispiel #7
0
static inline void fam15h_switch_dct(uint32_t dev, uint8_t dct)
{
	uint32_t dword;

	dword = Get_NB32(dev, 0x10c);
	dword &= ~0x1;
	dword |= (dct & 0x1);
	Set_NB32(dev, 0x10c, dword);
}
Beispiel #8
0
void mct_BeforeDQSTrainSamp(struct DCTStatStruc *pDCTstat)
{
	u32 val;

	if (pDCTstat->LogicalCPUID & AMD_DR_Bx) {
		Set_NB32(pDCTstat->dev_dct, 0x98, 0x0D004007);
		val = Get_NB32(pDCTstat->dev_dct, 0x9C);
		val |= 0x3FF;
		Set_NB32(pDCTstat->dev_dct, 0x9C, val);
		Set_NB32(pDCTstat->dev_dct, 0x98, 0x4D0F4F07);

		Set_NB32(pDCTstat->dev_dct, 0x198, 0x0D004007);
		val = Get_NB32(pDCTstat->dev_dct, 0x19C);
		val |= 0x3FF;
		Set_NB32(pDCTstat->dev_dct, 0x19C, val);
		Set_NB32(pDCTstat->dev_dct, 0x198, 0x4D0F4F07);
	}
}
Beispiel #9
0
static void set_fam10_ext_cfg_enable_bits(pci_devfn_t fam10_dev, u32 reg_pos,
		u32 mask, u32 val)
{
	u32 reg_old, reg;
	reg = reg_old = Get_NB32(fam10_dev, reg_pos);
	reg &= ~mask;
	reg |= val;
	if (reg != reg_old) {
		Set_NB32(fam10_dev, reg_pos, reg);
	}
}
Beispiel #10
0
void mct_DramInit_Hw_D(struct MCTStatStruc *pMCTstat,
			struct DCTStatStruc *pDCTstat, u8 dct)
{
	u32 val;
	u32 reg;
	u32 dev = pDCTstat->dev_dct;

	/*flag for selecting HW/SW DRAM Init HW DRAM Init */
	reg = 0x90 + 0x100 * dct; /*DRAM Configuration Low */
	val = Get_NB32(dev, reg);
	val |= (1<<InitDram);
	Set_NB32(dev, reg, val);
}
Beispiel #11
0
void mct_ExtMCTConfig_Dx(struct DCTStatStruc *pDCTstat)
{
	uint32_t dword;

	if (pDCTstat->LogicalCPUID & AMD_DR_Dx) {
		dword = 0x0ce00f00 | 0x1 << 29;	/* FlushWrOnStpGnt */
		if (!(pDCTstat->GangedMode))
			dword |= 0x18 << 2;	/* MctWrLimit = 0x18 for unganged mode */
		else
			dword |= 0x10 << 2;	/* MctWrLimit = 0x10 for ganged mode */
		Set_NB32(pDCTstat->dev_dct, 0x11c, dword);

		dword = Get_NB32(pDCTstat->dev_dct, 0x1b0);
		dword &= ~0x3;			/* AdapPrefMissRatio = 0x1 */
		dword |= 0x1;
		dword &= ~(0x3 << 2);		/* AdapPrefPositiveStep = 0x0 */
		dword &= ~(0x3 << 4);		/* AdapPrefNegativeStep = 0x0 */
		dword &= ~(0x7 << 8);		/* CohPrefPrbLmt = 0x1 */
		dword |= (0x1 << 8);
		dword |= (0x7 << 22);		/* PrefFourConf = 0x7 */
		dword |= (0x7 << 25);		/* PrefFiveConf = 0x7 */

		if (!(pDCTstat->GangedMode))
			dword |= (0x1 << 12);	/* EnSplitDctLimits = 0x1 */
		else
			dword &= ~(0x1 << 12);	/* EnSplitDctLimits = 0x0 */

		dword &= ~(0xf << 28);		/* DcqBwThrotWm = ... */
		switch (pDCTstat->Speed) {
		case 4:
			dword |= (0x5 << 28);	/* ...5 for DDR800 */
			break;
		case 5:
			dword |= (0x6 << 28);	/* ...6 for DDR1066 */
			break;
		case 6:
			dword |= (0x8 << 28);	/* ...8 for DDR800 */
			break;
		default:
			dword |= (0x9 << 28);	/* ...9 for DDR1600 */
			break;
		}
		Set_NB32(pDCTstat->dev_dct, 0x1b0, dword);
	}
}
Beispiel #12
0
void mct_EndDQSTraining_D(struct MCTStatStruc *pMCTstat,
				struct DCTStatStruc *pDCTstatA)
{
	/* Bug#13341: Prefetch is getting killed when the limit is reached in
	 * PrefDramTrainMode
	 * Solution: Explicitly clear the PrefDramTrainMode bit after training
	 * sequence in order to ensure resumption of normal HW prefetch
	 * behavior.
	 * NOTE -- this has been documented with a note at the end of this
	 * section in the  BKDG (although, admittedly, the note does not really
	 * stand out).
	 * Silicon Status: Fixed in Rev B ( confirm)
	 * FIXME: check this.
	 */

	uint64_t tmp;
	u32 dev;
	u32 reg;
	u32 val;
	u32 Node;

	for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
		struct DCTStatStruc *pDCTstat;
		pDCTstat = pDCTstatA + Node;

		if (!pDCTstat->NodePresent) break;

		tmp = pDCTstat->LogicalCPUID;
		if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) {
			dev = pDCTstat->dev_dct;
			reg = 0x11c;
			val = Get_NB32(dev, reg);
			val &= ~(1<<PrefDramTrainMode);
			Set_NB32(dev, reg, val);
		}
	}
}
Beispiel #13
0
u8 mct_GetStartMaxRdLat_D(struct MCTStatStruc *pMCTstat,
				struct DCTStatStruc *pDCTstat,
				u8 Channel, u8 DQSRcvEnDly, u32 *Margin)
{
	u32 SubTotal;
	u32 val;
	u32 valx;
	u32 valxx;
	u32 index_reg;
	u32 reg_off;
	u32 dev;

	if (pDCTstat->GangedMode)
		Channel =  0;

	index_reg = 0x98 + 0x100 * Channel;

	reg_off = 0x100 * Channel;
	dev = pDCTstat->dev_dct;

	/* Multiply the CAS Latency by two to get a number of 1/2 MEMCLKs units.*/
	val = Get_NB32(dev, 0x88 + reg_off);
	SubTotal = ((val & 0x0f) + 1) << 1;	/* SubTotal is 1/2 Memclk unit */

	/* If registered DIMMs are being used then add 1 MEMCLK to the sub-total*/
	val = Get_NB32(dev, 0x90 + reg_off);
	if (!(val & (1 << UnBuffDimm)))
		SubTotal += 2;

	/*If the address prelaunch is setup for 1/2 MEMCLKs then add 1,
	 *  else add 2 to the sub-total. if (AddrCmdSetup || CsOdtSetup
	 *  || CkeSetup) then K := K + 2; */
	val = Get_NB32_index_wait(dev, index_reg, 0x04);
	if (!(val & 0x00202020))
		SubTotal += 1;
	else
		SubTotal += 2;

	/* If the F2x[1, 0]78[RdPtrInit] field is 4, 5, 6 or 7 MEMCLKs,
	 *  then add 4, 3, 2, or 1 MEMCLKs, respectively to the sub-total. */
	val = Get_NB32(dev, 0x78 + reg_off);
	SubTotal += 8 - (val & 0x0f);

	/* Convert bits 7-5 (also referred to as the course delay) of the current
	 * (or worst case) DQS receiver enable delay to 1/2 MEMCLKs units,
	 * rounding up, and add this to the sub-total. */
	SubTotal += DQSRcvEnDly >> 5;	/*BOZO-no rounding up */

	SubTotal <<= 1;			/*scale 1/2 MemClk to 1/4 MemClk */

	/* Convert the sub-total (in 1/2 MEMCLKs) to northbridge clocks (NCLKs)
	 * as follows (assuming DDR400 and assuming that no P-state or link speed
	 * changes have occurred). */

	/*New formula:
	SubTotal *= 3*(Fn2xD4[NBFid]+4)/(3+Fn2x94[MemClkFreq])/2 */
	val = Get_NB32(dev, 0x94 + reg_off);
	/* SubTotal div 4 to scale 1/4 MemClk back to MemClk */
	val &= 7;
	if (val == 4) {
		val++;		/* adjust for DDR2-1066 */
	}
	valx = (val + 3) << 2;	/* SubTotal div 4 to scale 1/4 MemClk back to MemClk */


	val = Get_NB32(pDCTstat->dev_nbmisc, 0xD4);
	val = ((val & 0x1f) + 4) * 3;

	/* Calculate 1 MemClk + 1 NCLK delay in NCLKs for margin */
	valxx = val << 2;
	valxx /= valx;
	if (valxx % valx)
		valxx++;	/* round up */
	valxx++;		/* add 1NCLK */
	*Margin = valxx;	/* one MemClk delay in NCLKs and one additional NCLK */

	val *= SubTotal;

	val /= valx;
	if (val % valx)
		val++;		/* round up */



	return val;
}