Example #1
0
static uint8_t rc_word_chip_select_lower_bit(void) {
	if (is_fam15h()) {
		return 21;
	} else {
		return 20;
	}
}
Example #2
0
static u32 mct_MR3(struct MCTStatStruc *pMCTstat,
				struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel)
{
	u32 dev = pDCTstat->dev_dct;
	u32 dword, ret;

	/* The formula for chip select number is: CS = dimm*2+rank */
	uint8_t dimm = MrsChipSel / 2;
	uint8_t rank = MrsChipSel % 2;

	if (is_fam15h()) {
		ret = 0xc0000;
		ret |= (MrsChipSel << 21);

		/* Program MPR and MPRLoc to 0 */
		// ret |= 0x0;		/* MPR */
		// ret |= (0x0 << 2);	/* MPRLoc */
	} else {
		ret = 0x30000;
		ret |= (MrsChipSel << 20);

		/* program MrsAddress[1:0]=multi purpose register address location
		 * (MPR Location):based on F2x[1,0]84[MprLoc]
		 * program MrsAddress[2]=multi purpose register
		 * (MPR):based on F2x[1,0]84[MprEn]
		 */
		dword = Get_NB32_DCT(dev, dct, 0x84);
		ret |= (dword >> 24) & 7;
	}

	printk(BIOS_SPEW, "Going to send DCT %d DIMM %d rank %d MR3 control word %08x\n", dct, dimm, rank, ret);

	return ret;
}
Example #3
0
static inline void Set_NB32_DCT(uint32_t dev, uint8_t dct, uint32_t reg, uint32_t val)
{
	if (is_fam15h()) {
		/* Obtain address of function 0x1 */
		uint32_t dev_map = (dev & (~(0x7 << 12))) | (0x1 << 12);
		fam15h_switch_dct(dev_map, dct);
		Set_NB32(dev, reg, val);
	} else {
		Set_NB32(dev, (0x100 * dct) + reg, val);
	}
}
Example #4
0
static inline void Set_NB32_index_wait_DCT(uint32_t dev, uint8_t dct, uint32_t index_reg, uint32_t index, uint32_t data)
{
	if (is_fam15h()) {
		/* Obtain address of function 0x1 */
		uint32_t dev_map = (dev & (~(0x7 << 12))) | (0x1 << 12);
		fam15h_switch_dct(dev_map, dct);
		Set_NB32_index_wait(dev, index_reg, index, data);
	} else {
		Set_NB32_index_wait(dev, (0x100 * dct) + index_reg, index, data);
	}
}
Example #5
0
static inline uint32_t Get_NB32_DCT_NBPstate(uint32_t dev, uint8_t dct, uint8_t nb_pstate, 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);
		fam15h_switch_nb_pstate_config_reg(dev_map, nb_pstate);
		return Get_NB32(dev, reg);
	} else {
		return Get_NB32(dev, (0x100 * dct) + reg);
	}
}
Example #6
0
static u32 get_core_num_in_bsp(u32 nodeid)
{
	u32 dword;
	if (is_fam15h()) {
		/* Family 15h moved CmpCap to F5x84 [7:0] */
		dword = pci_read_config32(NODE_PCI(nodeid, 5), 0x84);
		dword &= 0xff;
	} else {
		dword = pci_read_config32(NODE_PCI(nodeid, 3), 0xe8);
		dword >>= 12;
		/* Bit 15 is CmpCap[2] since Revision D. */
		if ((cpuid_ecx(0x80000008) & 0xff) > 3)
	    	dword = ((dword & 8) >> 1) | (dword & 3);
		else
	    	dword &= 3;
	}
Example #7
0
static uint16_t memclk_to_freq(uint16_t memclk) {
	uint16_t fam10h_freq_tab[] = {0, 0, 0, 400, 533, 667, 800};
	uint16_t fam15h_freq_tab[] = {0, 0, 0, 0, 333, 0, 400, 0, 0, 0, 533, 0, 0, 0, 667, 0, 0, 0, 800, 0, 0, 0, 933};

	uint16_t mem_freq = 0;

	if (is_fam15h()) {
		if (memclk < 0x17) {
			mem_freq = fam15h_freq_tab[memclk];
		}
	} else {
		if ((memclk > 0x0) && (memclk < 0x8)) {
			mem_freq = fam10h_freq_tab[memclk - 1];
		}
	}

	return mem_freq;
}
Example #8
0
static u32 swapAddrBits(struct DCTStatStruc *pDCTstat, u32 MR_register_setting, u8 MrsChipSel, u8 dct)
{
	u16 word;
	u32 ret;

	if (!(pDCTstat->Status & (1 << SB_Registered))) {
		word = pDCTstat->MirrPresU_NumRegR;
		if (dct == 0) {
			word &= 0x55;
			word <<= 1;
		} else
			word &= 0xAA;

		if (word & (1 << MrsChipSel)) {
			/* A3<->A4,A5<->A6,A7<->A8,BA0<->BA1 */
			ret = 0;
			if (MR_register_setting & (1 << 3)) ret |= 1 << 4;
			if (MR_register_setting & (1 << 4)) ret |= 1 << 3;
			if (MR_register_setting & (1 << 5)) ret |= 1 << 6;
			if (MR_register_setting & (1 << 6)) ret |= 1 << 5;
			if (MR_register_setting & (1 << 7)) ret |= 1 << 8;
			if (MR_register_setting & (1 << 8)) ret |= 1 << 7;
			if (is_fam15h()) {
				if (MR_register_setting & (1 << 18)) ret |= 1 << 19;
				if (MR_register_setting & (1 << 19)) ret |= 1 << 18;
				MR_register_setting &= ~0x000c01f8;
			} else {
				if (MR_register_setting & (1 << 16)) ret |= 1 << 17;
				if (MR_register_setting & (1 << 17)) ret |= 1 << 16;
				MR_register_setting &= ~0x000301f8;
			}
			MR_register_setting |= ret;
		}
	}
	return MR_register_setting;
}
Example #9
0
static uint16_t mct_MaxLoadFreq(uint8_t count, uint8_t highest_rank_count, uint8_t registered, uint8_t voltage, uint16_t freq)
{
	/* FIXME
	 * Mainboards need to be able to specify the maximum number of DIMMs installable per channel
	 * For now assume a maximum of 2 DIMMs per channel can be installed
	 */
	uint8_t MaxDimmsInstallable = 2;

	/* Return limited maximum RAM frequency */
	if (IS_ENABLED(CONFIG_DIMM_DDR2)) {
		if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) {
			/* K10 BKDG Rev. 3.62 Table 53 */
			if (count > 2) {
				/* Limit to DDR2-533 */
				if (freq > 266) {
					freq = 266;
					print_tf(__func__, ": More than 2 registered DIMMs on channel; limiting to DDR2-533\n");
				}
			}
		} else {
			/* K10 BKDG Rev. 3.62 Table 52 */
			if (count > 1) {
				/* Limit to DDR2-800 */
				if (freq > 400) {
					freq = 400;
					print_tf(__func__, ": More than 1 unbuffered DIMM on channel; limiting to DDR2-800\n");
				}
			}
		}
	} else if (IS_ENABLED(CONFIG_DIMM_DDR3)) {
		if (voltage == 0) {
			printk(BIOS_DEBUG, "%s: WARNING: Mainboard DDR3 voltage unknown, assuming 1.5V!\n", __func__);
			voltage = 0x1;
		}

		if (is_fam15h()) {
			if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) {
				/* Fam15h BKDG Rev. 3.14 Table 27 */
				if (voltage & 0x4) {
					/* 1.25V */
					if (count > 1) {
						if (highest_rank_count > 1) {
							/* Limit to DDR3-1066 */
							if (freq > 533) {
								freq = 533;
								printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
							}
						} else {
							/* Limit to DDR3-1333 */
							if (freq > 666) {
								freq = 666;
								printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
							}
						}
					} else {
						/* Limit to DDR3-1333 */
						if (freq > 666) {
							freq = 666;
							printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
						}
					}
				} else if (voltage & 0x2) {
					/* 1.35V */
					if (count > 1) {
						/* Limit to DDR3-1333 */
						if (freq > 666) {
							freq = 666;
							printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
						}
					} else {
						/* Limit to DDR3-1600 */
						if (freq > 800) {
							freq = 800;
							printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
						}
					}
				} else if (voltage & 0x1) {
					/* 1.50V */
					if (count > 1) {
						/* Limit to DDR3-1600 */
						if (freq > 800) {
							freq = 800;
							printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
						}
					} else {
						/* Limit to DDR3-1866 */
						if (freq > 933) {
							freq = 933;
							printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage));
						}
					}
				}
			} else {
				/* Fam15h BKDG Rev. 3.14 Table 26 */
				if (voltage & 0x4) {
					/* 1.25V */
					if (count > 1) {
						if (highest_rank_count > 1) {
							/* Limit to DDR3-1066 */
							if (freq > 533) {
								freq = 533;
								printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
							}
						} else {
							/* Limit to DDR3-1333 */
							if (freq > 666) {
								freq = 666;
								printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
							}
						}
					} else {
						/* Limit to DDR3-1333 */
						if (freq > 666) {
							freq = 666;
							printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
						}
					}
				} else if (voltage & 0x2) {
					/* 1.35V */
					if (MaxDimmsInstallable > 1) {
						/* Limit to DDR3-1333 */
						if (freq > 666) {
							freq = 666;
							printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
						}
					} else {
						/* Limit to DDR3-1600 */
						if (freq > 800) {
							freq = 800;
							printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
						}
					}
				} else if (voltage & 0x1) {
					if (MaxDimmsInstallable == 1) {
						if (count > 1) {
							/* Limit to DDR3-1600 */
							if (freq > 800) {
								freq = 800;
								printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
							}
						} else {
							/* Limit to DDR3-1866 */
							if (freq > 933) {
								freq = 933;
								printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage));
							}
						}
					} else {
						if (count > 1) {
							if (highest_rank_count > 1) {
								/* Limit to DDR3-1333 */
								if (freq > 666) {
									freq = 666;
									printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
								}
							} else {
								/* Limit to DDR3-1600 */
								if (freq > 800) {
									freq = 800;
									printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
								}
							}
						} else {
							/* Limit to DDR3-1600 */
							if (freq > 800) {
								freq = 800;
								printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
							}
						}
					}
				}
			}
		} else {
			if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) {
				/* K10 BKDG Rev. 3.62 Table 34 */
				if (count > 2) {
					/* Limit to DDR3-800 */
					if (freq > 400) {
						freq = 400;
						printk(BIOS_DEBUG, "%s: More than 2 registered DIMMs on %dmV channel; limiting to DDR3-800\n", __func__, voltage_index_to_mv(voltage));
					}
				} else if (count == 2) {
					/* Limit to DDR3-1066 */
					if (freq > 533) {
						freq = 533;
						printk(BIOS_DEBUG, "%s: 2 registered DIMMs on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
					}
				} else {
					/* Limit to DDR3-1333 */
					if (freq > 666) {
						freq = 666;
						printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
					}
				}
			} else {
				/* K10 BKDG Rev. 3.62 Table 33 */
				/* Limit to DDR3-1333 */
				if (freq > 666) {
					freq = 666;
					printk(BIOS_DEBUG, "%s: unbuffered DIMMs on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
				}
			}
		}
	}

	return freq;
}
Example #10
0
static u32 mct_MR2(struct MCTStatStruc *pMCTstat,
				struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel)
{
	u32 dev = pDCTstat->dev_dct;
	u32 dword, ret;

	/* The formula for chip select number is: CS = dimm*2+rank */
	uint8_t dimm = MrsChipSel / 2;
	uint8_t rank = MrsChipSel % 2;

	if (is_fam15h()) {
		uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);

		/* FIXME: These parameters should be configurable
		 * For now, err on the side of caution and enable automatic 2x refresh
		 * when the DDR temperature rises above the internal limits
		 */
		uint8_t force_2x_self_refresh = 0;	/* ASR */
		uint8_t auto_2x_self_refresh = 1;	/* SRT */

		ret = 0x80000;
		ret |= (MrsChipSel << 21);

		/* Set self refresh parameters */
		ret |= (force_2x_self_refresh << 6);
		ret |= (auto_2x_self_refresh << 7);

		/* Obtain Tcwl, adjust, and set CWL with the adjusted value */
		dword = Get_NB32_DCT(dev, dct, 0x20c) & 0x1f;
		ret |= ((dword - 5) << 3);

		/* Obtain and set RttWr */
		ret |= (fam15_rttwr(pDCTstat, dct, dimm, rank, package_type) << 9);
	} else {
		ret = 0x20000;
		ret |= (MrsChipSel << 20);

		/* program MrsAddress[5:3]=CAS write latency (CWL):
		 * based on F2x[1,0]84[Tcwl] */
		dword = Get_NB32_DCT(dev, dct, 0x84);
		dword = mct_AdjustSPDTimings(pMCTstat, pDCTstat, dword);

		ret |= ((dword >> 20) & 7) << 3;

		/* program MrsAddress[6]=auto self refresh method (ASR):
		 * based on F2x[1,0]84[ASR]
		 * program MrsAddress[7]=self refresh temperature range (SRT):
		 * based on F2x[1,0]84[ASR and SRT]
		 */
		ret |= ((dword >> 18) & 3) << 6;

		/* program MrsAddress[10:9]=dynamic termination during writes (RTT_WR)
		 * based on F2x[1,0]84[DramTermDyn]
		 */
		ret |= ((dword >> 10) & 3) << 9;
	}

	printk(BIOS_SPEW, "Going to send DCT %d DIMM %d rank %d MR2 control word %08x\n", dct, dimm, rank, ret);

	return ret;
}
Example #11
0
static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type)
{
	uint8_t term = 0;
	uint8_t number_of_dimms = pDCTstat->MAdimms[dct];
	uint8_t frequency_index;
	uint8_t rank_count = pDCTstat->DimmRanks[(dimm * 2) + dct];

	uint8_t rank_count_dimm0;
	uint8_t rank_count_dimm1;
	uint8_t rank_count_dimm2;

	if (is_fam15h())
		frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f;
	else
		frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x7;

	uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);

	if (is_fam15h()) {
		if (pDCTstat->Status & (1 << SB_LoadReduced)) {
			/* TODO
			 * LRDIMM unimplemented
			 */
		} else if (pDCTstat->Status & (1 << SB_Registered)) {
			/* RDIMM */
			if (package_type == PT_GR) {
				/* Socket G34: Fam15h BKDG v3.14 Table 57 */
				if (MaxDimmsInstallable == 1) {
					if ((frequency_index == 0x4) || (frequency_index == 0x6)
						|| (frequency_index == 0xa) || (frequency_index == 0xe)) {
						/* DDR3-667 - DDR3-1333 */
						if (rank_count < 3)
							term = 0x0;
						else
							term = 0x2;
					} else {
						/* DDR3-1600 */
						term = 0x0;
					}
				} else if (MaxDimmsInstallable == 2) {
					rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
					rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];

					if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
						/* DDR3-667 - DDR3-800 */
						if ((number_of_dimms == 1) && ((rank_count_dimm0 < 4)
							&& (rank_count_dimm1 < 4)))
							term = 0x0;
						else
							term = 0x2;
					} else if (frequency_index == 0xa) {
						/* DDR3-1066 */
						if (number_of_dimms == 1) {
							if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
								term = 0x0;
							else
								term = 0x2;
						} else {
							term = 0x1;
						}
					} else if (frequency_index == 0xe) {
						/* DDR3-1333 */
						term = 0x2;
					} else {
						/* DDR3-1600 */
						if (number_of_dimms == 1)
							term = 0x0;
						else
							term = 0x1;
					}
				} else if (MaxDimmsInstallable == 3) {
					rank_count_dimm2 = pDCTstat->DimmRanks[(2 * 2) + dct];

					if ((frequency_index == 0xa) || (frequency_index == 0xe)) {
						/* DDR3-1066 - DDR3-1333 */
						if (rank_count_dimm2 < 4)
							term = 0x1;
						else
							term = 0x2;
					} else if (frequency_index == 0x12) {
						/* DDR3-1600 */
						term = 0x1;
					} else {
						term = 0x2;
					}
				}
			} else {
				/* TODO
				 * Other sockets unimplemented
				 */
			}
		} else {
			/* UDIMM */
			if (package_type == PT_GR) {
				/* Socket G34: Fam15h BKDG v3.14 Table 56 */
				if (MaxDimmsInstallable == 1) {
					term = 0x0;
				} else if (MaxDimmsInstallable == 2) {
					if ((number_of_dimms == 2) && (frequency_index == 0x12)) {
						term = 0x1;
					} else if (number_of_dimms == 1) {
						term = 0x0;
					} else {
						term = 0x2;
					}
				} else if (MaxDimmsInstallable == 3) {
					if (number_of_dimms == 1) {
						if (frequency_index <= 0xa) {
							term = 0x2;
						} else {
							if (rank_count < 3) {
								term = 0x1;
							} else {
								term = 0x2;
							}
						}
					} else if (number_of_dimms == 2) {
						term = 0x2;
					}
				}
			} else {
				/* TODO
				* Other sockets unimplemented
				*/
			}
		}
	}

	return term;
}