Beispiel #1
0
static inline uint32_t Get_NB32_index_wait_DCT(uint32_t dev, uint8_t dct, uint32_t index_reg, uint32_t index)
{
	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_index_wait(dev, index_reg, index);
	} else {
		return Get_NB32_index_wait(dev, (0x100 * dct) + index_reg, index);
	}
}
Beispiel #2
0
u32 Modify_D3CMP(struct DCTStatStruc *pDCTstat, u32 dct, u32 value)
{
	/* Errata#189: Reads To Phy Driver Calibration Register and Phy
	 *  Predriver Calibration Register Do Not Return Bit 27.
	 * Solution: See #41322 for details.
	 * BIOS can modify bit 27 of the Phy Driver Calibration register
	 * as follows:
	 *  1. Read F2x[1, 0]9C_x09
	 *  2. Read F2x[1, 0]9C_x0D004201
	 *  3. Set F2x[1, 0]9C_x09[27] = F2x[1, 0]9C_x0D004201[10]
	 * BIOS can modify bit 27 of the Phy Predriver Calibration register
	 * as follows:
	 *  1. Read F2x[1, 0]9C_x0A
	 *  2. Read F2x[1, 0]9C_x0D004209
	 *  3. Set F2x[1, 0]9C_x0A[27] = F2x[1, 0]9C_x0D004209[10]
	 * Silicon Status: Fixed planned for DR-B0
	 */

	u32 dev;
	u32 index_reg;
	u32 index;
	u32 val;
	uint64_t tmp;

	tmp = pDCTstat->LogicalCPUID;
	if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) {
		dev = pDCTstat->dev_dct;
		index_reg = 0x98 + 0x100 * dct;
		index = 0x0D004201;
		val = Get_NB32_index_wait(dev, index_reg, index);
		value &= ~(1<<27);
		value |= ((val>>10) & 1) << 27;
	}
Beispiel #3
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 #4
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;
}