예제 #1
0
static void program_ddr0_06(unsigned long dimm_ranks[],
			    unsigned char const iic0_dimm_addr[],
			    unsigned long num_dimm_banks,
			    unsigned long sdram_freq)
{
	unsigned long dimm_num;
	unsigned char spd_40;
	unsigned long t_wtr_ps = 0;
	unsigned long t_rfc_ps = 0;
	unsigned long t_wtr_clk;
	unsigned long t_rfc_clk;
	u32 ddr0_06 =
	    DDR0_06_WRITEINTERP_ENCODE(0x1) | DDR0_06_TDLL_ENCODE(200);

	/*------------------------------------------------------------------
	 * Handle the timing.  We need to find the worst case timing of all
	 * the dimm modules installed.
	 *-----------------------------------------------------------------*/
	/* loop through all the DIMM slots on the board */
	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
		/* If a dimm is installed in a particular slot ... */
		if (dimm_ranks[dimm_num]) {
			unsigned long ps;

			/* tWTR */
			ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 37);
			t_wtr_ps = max(t_wtr_ps, ps);
			/* tRFC */
			ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 42);
			spd_40 = spd_read(iic0_dimm_addr[dimm_num], 40);
			ps += 256000 * (spd_40 & 0x01);
			switch ((spd_40 & 0x0E) >> 1) {
			case 0x1:
				ps += 250;
				break;
			case 0x2:
				ps += 333;
				break;
			case 0x3:
				ps += 500;
				break;
			case 0x4:
				ps += 667;
				break;
			case 0x5:
				ps += 750;
				break;
			}
			t_rfc_ps = max(t_rfc_ps, ps);
		}
	}
	debug("t_wtr_ps = %d\n", t_wtr_ps);
	t_wtr_clk = (MULDIV64(sdram_freq, t_wtr_ps, ONE_BILLION) + 999) / 1000;
	debug("t_rfc_ps = %d\n", t_rfc_ps);
	t_rfc_clk = (MULDIV64(sdram_freq, t_rfc_ps, ONE_BILLION) + 999) / 1000;
	mtsdram(DDR0_06, ddr0_06 | DDR0_06_TWTR_ENCODE(t_wtr_clk) |
		DDR0_06_TRFC_ENCODE(t_rfc_clk));
}
예제 #2
0
static void program_ddr0_44(unsigned long dimm_ranks[],
			    unsigned char const iic0_dimm_addr[],
			    unsigned long num_dimm_banks,
			    unsigned long sdram_freq)
{
	unsigned long dimm_num;
	unsigned long t_rcd_ps = 0;
	unsigned long t_rcd_clk;

	/*------------------------------------------------------------------
	 * Handle the timing.  We need to find the worst case timing of all
	 * the dimm modules installed.
	 *-----------------------------------------------------------------*/
	/* loop through all the DIMM slots on the board */
	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
		/* If a dimm is installed in a particular slot ... */
		if (dimm_ranks[dimm_num]) {
			unsigned long ps;

			ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 29);
			t_rcd_ps = max(t_rcd_ps, ps);
		}
	}
	debug("t_rcd_ps = %d\n", t_rcd_ps);
	t_rcd_clk = (MULDIV64(sdram_freq, t_rcd_ps, ONE_BILLION) + 999) / 1000;
	mtsdram(DDR0_44, DDR0_44_TRCD_ENCODE(t_rcd_clk));
}
예제 #3
0
static void program_ddr0_43(unsigned long dimm_ranks[],
			    unsigned char const iic0_dimm_addr[],
			    unsigned long num_dimm_banks,
			    unsigned long sdram_freq,
			    unsigned long cols, unsigned long banks)
{
	unsigned long dimm_num;
	unsigned long t_wr_ps = 0;
	unsigned long t_wr_clk;
	u32 ddr0_43 = DDR0_43_APREBIT_ENCODE(10) |
	    DDR0_43_COLUMN_SIZE_ENCODE(12 - cols) |
	    DDR0_43_EIGHT_BANK_MODE_ENCODE(8 == banks ? 1 : 0);

	/*------------------------------------------------------------------
	 * Handle the timing.  We need to find the worst case timing of all
	 * the dimm modules installed.
	 *-----------------------------------------------------------------*/
	/* loop through all the DIMM slots on the board */
	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
		/* If a dimm is installed in a particular slot ... */
		if (dimm_ranks[dimm_num]) {
			unsigned long ps;

			ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 36);
			t_wr_ps = max(t_wr_ps, ps);
		}
	}
	debug("t_wr_ps = %d\n", t_wr_ps);
	t_wr_clk = (MULDIV64(sdram_freq, t_wr_ps, ONE_BILLION) + 999) / 1000;
	mtsdram(DDR0_43, ddr0_43 | DDR0_43_TWR_ENCODE(t_wr_clk));
}
예제 #4
0
static void program_ddr0_26(unsigned long sdram_freq)
{
	unsigned long const t_ref_ps = 7800000;	/* 7.8 us. refresh */
	/* TODO: check definition of tRAS_MAX */
	unsigned long const t_ras_max_ps = 9 * t_ref_ps;
	unsigned long t_ras_max_clk;
	unsigned long t_ref_clk;

	/* Round down t_ras_max_clk and t_ref_clk */
	debug("t_ras_max_ps = %d\n", t_ras_max_ps);
	t_ras_max_clk = MULDIV64(sdram_freq, t_ras_max_ps, ONE_BILLION) / 1000;
	debug("t_ref_ps     = %d\n", t_ref_ps);
	t_ref_clk = MULDIV64(sdram_freq, t_ref_ps, ONE_BILLION) / 1000;
	mtsdram(DDR0_26, DDR0_26_TRAS_MAX_ENCODE(t_ras_max_clk) |
		DDR0_26_TREF_ENCODE(t_ref_clk));
}
예제 #5
0
static void program_ddr0_27(unsigned long sdram_freq)
{
	unsigned long const t_init_ps = 200000000;	/* 200 us. init */
	unsigned long t_init_clk;

	debug("t_init_ps = %d\n", t_init_ps);
	t_init_clk =
	    (MULDIV64(sdram_freq, t_init_ps, ONE_BILLION) + 999) / 1000;
	mtsdram(DDR0_27, DDR0_27_EMRS_DATA_ENCODE(0x0000) |
		DDR0_27_TINIT_ENCODE(t_init_clk));
}
예제 #6
0
static void program_ddr0_11(unsigned long sdram_freq)
{
	unsigned long const t_xsnr_ps = 200000;	/* 200 ns */
	unsigned long t_xsnr_clk;

	debug("t_xsnr_ps = %d\n", t_xsnr_ps);
	t_xsnr_clk =
	    (MULDIV64(sdram_freq, t_xsnr_ps, ONE_BILLION) + 999) / 1000;
	mtsdram(DDR0_11, DDR0_11_SREFRESH_ENCODE(0) |
		DDR0_11_TXSNR_ENCODE(t_xsnr_clk) | DDR0_11_TXSR_ENCODE(200));
}
예제 #7
0
static void program_ddr0_05(unsigned long dimm_ranks[],
			    unsigned char const iic0_dimm_addr[],
			    unsigned long num_dimm_banks,
			    unsigned long sdram_freq)
{
	unsigned long dimm_num;
	unsigned long t_rp_ps = 0;
	unsigned long t_ras_ps = 0;
	unsigned long t_rp_clk;
	unsigned long t_ras_clk;
	u32 ddr0_05 = DDR0_05_TMRD_ENCODE(0x2) | DDR0_05_TEMRS_ENCODE(0x2);

	/*------------------------------------------------------------------
	 * Handle the timing.  We need to find the worst case timing of all
	 * the dimm modules installed.
	 *-----------------------------------------------------------------*/
	/* loop through all the DIMM slots on the board */
	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
		/* If a dimm is installed in a particular slot ... */
		if (dimm_ranks[dimm_num]) {
			unsigned long ps;

			/* tRP */
			ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 27);
			t_rp_ps = max(t_rp_ps, ps);
			/* tRAS */
			ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 30);
			t_ras_ps = max(t_ras_ps, ps);
		}
	}
	debug("t_rp_ps  = %d\n", t_rp_ps);
	t_rp_clk = (MULDIV64(sdram_freq, t_rp_ps, ONE_BILLION) + 999) / 1000;
	debug("t_ras_ps = %d\n", t_ras_ps);
	t_ras_clk = (MULDIV64(sdram_freq, t_ras_ps, ONE_BILLION) + 999) / 1000;
	mtsdram(DDR0_05, ddr0_05 | DDR0_05_TRP_ENCODE(t_rp_clk) |
		DDR0_05_TRAS_MIN_ENCODE(t_ras_clk));
}
예제 #8
0
/*------------------------------------------------------------------
 * For the memory DIMMs installed, this routine verifies that
 * frequency previously calculated is supported.
 *-----------------------------------------------------------------*/
static void check_frequency(unsigned long *dimm_ranks,
			    unsigned char const iic0_dimm_addr[],
			    unsigned long num_dimm_banks,
			    unsigned long sdram_freq)
{
	unsigned long dimm_num;
	unsigned long cycle_time;
	unsigned long calc_cycle_time;

	/*
	 * calc_cycle_time is calculated from DDR frequency set by board/chip
	 * and is expressed in picoseconds to match the way DIMM cycle time is
	 * calculated below.
	 */
	calc_cycle_time = MULDIV64(ONE_BILLION, 1000, sdram_freq);

	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
		if (dimm_ranks[dimm_num]) {
			cycle_time =
			    get_tcyc(spd_read(iic0_dimm_addr[dimm_num], 9));
			debug("cycle_time=%d ps\n", cycle_time);

			if (cycle_time > (calc_cycle_time + 10)) {
				/*
				 * the provided sdram cycle_time is too small
				 * for the available DIMM cycle_time. The
				 * additionnal 10ps is here to accept a small
				 * incertainty.
				 */
				printf
				    ("ERROR: DRAM DIMM detected with cycle_time %d ps in "
				     "slot %d \n while calculated cycle time is %d ps.\n",
				     (unsigned int)cycle_time,
				     (unsigned int)dimm_num,
				     (unsigned int)calc_cycle_time);
				printf
				    ("Replace the DIMM, or change DDR frequency via "
				     "strapping bits.\n\n");
				spd_ddr_init_hang();
			}
		}
	}
}
예제 #9
0
파일: clock.c 프로젝트: 8l/inferno
int
tmr2us(ulong t)
{
	return MULDIV64(t, 1000000, CLOCKFREQ, 24);
}
예제 #10
0
파일: clock.c 프로젝트: 8l/inferno
ulong
us2tmr(int us)
{
	return MULDIV64(us, CLOCKFREQ, 1000000, 24);
}
예제 #11
0
파일: clock.c 프로젝트: 8l/inferno
int
tmr2us(ulong t)
{
	return MULDIV64(t, 1000000, TIMER_HZ, 24);
}
예제 #12
0
static void program_ddr0_04(unsigned long dimm_ranks[],
			    unsigned char const iic0_dimm_addr[],
			    unsigned long num_dimm_banks,
			    unsigned long sdram_freq)
{
	unsigned long dimm_num;
	unsigned long t_rc_ps = 0;
	unsigned long t_rrd_ps = 0;
	unsigned long t_rtp_ps = 0;
	unsigned long t_rc_clk;
	unsigned long t_rrd_clk;
	unsigned long t_rtp_clk;

	/*------------------------------------------------------------------
	 * Handle the timing.  We need to find the worst case timing of all
	 * the dimm modules installed.
	 *-----------------------------------------------------------------*/
	/* loop through all the DIMM slots on the board */
	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
		/* If a dimm is installed in a particular slot ... */
		if (dimm_ranks[dimm_num]) {
			unsigned long ps;

			/* tRC */
			ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 41);
			switch (spd_read(iic0_dimm_addr[dimm_num], 40) >> 4) {
			case 0x1:
				ps += 250;
				break;
			case 0x2:
				ps += 333;
				break;
			case 0x3:
				ps += 500;
				break;
			case 0x4:
				ps += 667;
				break;
			case 0x5:
				ps += 750;
				break;
			}
			t_rc_ps = max(t_rc_ps, ps);
			/* tRRD */
			ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 28);
			t_rrd_ps = max(t_rrd_ps, ps);
			/* tRTP */
			ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 38);
			t_rtp_ps = max(t_rtp_ps, ps);
		}
	}
	debug("t_rc_ps  = %d\n", t_rc_ps);
	t_rc_clk = (MULDIV64(sdram_freq, t_rc_ps, ONE_BILLION) + 999) / 1000;
	debug("t_rrd_ps = %d\n", t_rrd_ps);
	t_rrd_clk = (MULDIV64(sdram_freq, t_rrd_ps, ONE_BILLION) + 999) / 1000;
	debug("t_rtp_ps = %d\n", t_rtp_ps);
	t_rtp_clk = (MULDIV64(sdram_freq, t_rtp_ps, ONE_BILLION) + 999) / 1000;
	mtsdram(DDR0_04, DDR0_04_TRC_ENCODE(t_rc_clk) |
		DDR0_04_TRRD_ENCODE(t_rrd_clk) |
		DDR0_04_TRTP_ENCODE(t_rtp_clk));
}
예제 #13
0
static void program_ddr0_03(unsigned long dimm_ranks[],
			    unsigned char const iic0_dimm_addr[],
			    unsigned long num_dimm_banks,
			    unsigned long sdram_freq,
			    unsigned long rows, unsigned long *cas_latency)
{
	unsigned long dimm_num;
	unsigned long cas_index;
	unsigned long cycle_2_0_clk;
	unsigned long cycle_3_0_clk;
	unsigned long cycle_4_0_clk;
	unsigned long cycle_5_0_clk;
	unsigned long max_2_0_tcyc_ps = 100;
	unsigned long max_3_0_tcyc_ps = 100;
	unsigned long max_4_0_tcyc_ps = 100;
	unsigned long max_5_0_tcyc_ps = 100;
	unsigned char cas_available = 0x3C;	/* value for DDR2 */
	u32 ddr0_03 = DDR0_03_BSTLEN_ENCODE(0x2) | DDR0_03_INITAREF_ENCODE(0x2);
	unsigned int const tcyc_addr[3] = { 9, 23, 25 };

	/*------------------------------------------------------------------
	 * Get the board configuration info.
	 *-----------------------------------------------------------------*/
	debug("sdram_freq = %d\n", sdram_freq);

	/*------------------------------------------------------------------
	 * Handle the timing.  We need to find the worst case timing of all
	 * the dimm modules installed.
	 *-----------------------------------------------------------------*/
	/* loop through all the DIMM slots on the board */
	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
		/* If a dimm is installed in a particular slot ... */
		if (dimm_ranks[dimm_num]) {
			unsigned char const cas_bit =
			    spd_read(iic0_dimm_addr[dimm_num], 18);
			unsigned char cas_mask;

			cas_available &= cas_bit;
			for (cas_mask = 0x80; cas_mask; cas_mask >>= 1) {
				if (cas_bit & cas_mask)
					break;
			}
			debug("cas_bit (SPD byte 18) = %02X, cas_mask = %02X\n",
			      cas_bit, cas_mask);

			for (cas_index = 0; cas_index < 3;
			     cas_mask >>= 1, cas_index++) {
				unsigned long cycle_time_ps;

				if (!(cas_available & cas_mask)) {
					continue;
				}
				cycle_time_ps =
				    get_tcyc(spd_read(iic0_dimm_addr[dimm_num],
						      tcyc_addr[cas_index]));

				debug("cas_index = %d: cycle_time_ps = %d\n",
				      cas_index, cycle_time_ps);
				/*
				 * DDR2 devices use the following bitmask for CAS latency:
				 *  Bit   7    6    5    4    3    2    1    0
				 *       TBD  6.0  5.0  4.0  3.0  2.0  TBD  TBD
				 */
				switch (cas_mask) {
				case 0x20:
					max_5_0_tcyc_ps =
					    max(max_5_0_tcyc_ps, cycle_time_ps);
					break;
				case 0x10:
					max_4_0_tcyc_ps =
					    max(max_4_0_tcyc_ps, cycle_time_ps);
					break;
				case 0x08:
					max_3_0_tcyc_ps =
					    max(max_3_0_tcyc_ps, cycle_time_ps);
					break;
				case 0x04:
					max_2_0_tcyc_ps =
					    max(max_2_0_tcyc_ps, cycle_time_ps);
					break;
				}
			}
		}
	}
	debug("cas_available (bit map) = 0x%02X\n", cas_available);

	/*------------------------------------------------------------------
	 * Set the SDRAM mode, SDRAM_MMODE
	 *-----------------------------------------------------------------*/

	/* add 10 here because of rounding problems */
	cycle_2_0_clk = MULDIV64(ONE_BILLION, 1000, max_2_0_tcyc_ps) + 10;
	cycle_3_0_clk = MULDIV64(ONE_BILLION, 1000, max_3_0_tcyc_ps) + 10;
	cycle_4_0_clk = MULDIV64(ONE_BILLION, 1000, max_4_0_tcyc_ps) + 10;
	cycle_5_0_clk = MULDIV64(ONE_BILLION, 1000, max_5_0_tcyc_ps) + 10;
	debug("cycle_2_0_clk = %d\n", cycle_2_0_clk);
	debug("cycle_3_0_clk = %d\n", cycle_3_0_clk);
	debug("cycle_4_0_clk = %d\n", cycle_4_0_clk);
	debug("cycle_5_0_clk = %d\n", cycle_5_0_clk);

	if ((cas_available & 0x04) && (sdram_freq <= cycle_2_0_clk)) {
		*cas_latency = 2;
		ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x2) |
		    DDR0_03_CASLAT_LIN_ENCODE(0x4);
	} else if ((cas_available & 0x08) && (sdram_freq <= cycle_3_0_clk)) {
		*cas_latency = 3;
		ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x3) |
		    DDR0_03_CASLAT_LIN_ENCODE(0x6);
	} else if ((cas_available & 0x10) && (sdram_freq <= cycle_4_0_clk)) {
		*cas_latency = 4;
		ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x4) |
		    DDR0_03_CASLAT_LIN_ENCODE(0x8);
	} else if ((cas_available & 0x20) && (sdram_freq <= cycle_5_0_clk)) {
		*cas_latency = 5;
		ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x5) |
		    DDR0_03_CASLAT_LIN_ENCODE(0xA);
	} else {
		printf("ERROR: Cannot find a supported CAS latency with the "
		       "installed DIMMs.\n");
		printf("Only DDR2 DIMMs with CAS latencies of 2.0, 3.0, 4.0, "
		       "and 5.0 are supported.\n");
		printf("Make sure the PLB speed is within the supported range "
		       "of the DIMMs.\n");
		printf("sdram_freq=%ld cycle2=%ld cycle3=%ld cycle4=%ld "
		       "cycle5=%ld\n\n", sdram_freq, cycle_2_0_clk,
		       cycle_3_0_clk, cycle_4_0_clk, cycle_5_0_clk);
		spd_ddr_init_hang();
	}
	debug("CAS latency = %d\n", *cas_latency);
	mtsdram(DDR0_03, ddr0_03);
}
예제 #14
0
파일: clock.c 프로젝트: 8l/inferno
int
tmr2ms(ulong t)
{
	return MULDIV64(t, 1000, TIMER_HZ, 32);
}
예제 #15
0
파일: clock.c 프로젝트: 8l/inferno
ulong
ms2tmr(int ms)
{
	return MULDIV64(ms, TIMER_HZ, 1000, 20);
}
예제 #16
0
파일: clock.c 프로젝트: 8l/inferno
ulong
ms2tmr(int ms)
{
	return MULDIV64(ms, CLOCKFREQ, 1000, 20);
}
예제 #17
0
파일: clock.c 프로젝트: 8l/inferno
int
tmr2ms(ulong t)
{
	return MULDIV64(t, 1000, CLOCKFREQ, 32);
}
예제 #18
0
파일: clock.c 프로젝트: 8l/inferno
ulong
us2tmr(int us)
{
	return MULDIV64(us, TIMER_HZ, 1000000, 24);
}