diff options
Diffstat (limited to 'board/bf537-stamp/post-memory.c')
| -rw-r--r-- | board/bf537-stamp/post-memory.c | 322 | 
1 files changed, 322 insertions, 0 deletions
| diff --git a/board/bf537-stamp/post-memory.c b/board/bf537-stamp/post-memory.c new file mode 100644 index 000000000..60393505a --- /dev/null +++ b/board/bf537-stamp/post-memory.c @@ -0,0 +1,322 @@ +#include <common.h> +#include <asm/io.h> + +#ifdef CONFIG_POST + +#include <post.h> +#include <watchdog.h> + +#if CONFIG_POST & CFG_POST_MEMORY +#define CLKIN 25000000 +#define PATTERN1 0x5A5A5A5A +#define PATTERN2 0xAAAAAAAA + +#define CCLK_NUM	4 +#define SCLK_NUM	3 + +void post_out_buff(char *buff); +int post_key_pressed(void); +void post_init_pll(int mult, int div); +int post_init_sdram(int sclk); +void post_init_uart(int sclk); + +const int pll[CCLK_NUM][SCLK_NUM][2] = { +	{{20, 4}, {20, 5}, {20, 10}},	/* CCLK = 500M */ +	{{16, 4}, {16, 5}, {16, 8}},	/* CCLK = 400M */ +	{{8, 2}, {8, 4}, {8, 5}},	/* CCLK = 200M */ +	{{4, 1}, {4, 2}, {4, 4}}	/* CCLK = 100M */ +}; +const char *const log[CCLK_NUM][SCLK_NUM] = { +	{"CCLK-500Mhz SCLK-125Mhz:    Writing...\0", +	 "CCLK-500Mhz SCLK-100Mhz:    Writing...\0", +	 "CCLK-500Mhz SCLK- 50Mhz:    Writing...\0",}, +	{"CCLK-400Mhz SCLK-100Mhz:    Writing...\0", +	 "CCLK-400Mhz SCLK- 80Mhz:    Writing...\0", +	 "CCLK-400Mhz SCLK- 50Mhz:    Writing...\0",}, +	{"CCLK-200Mhz SCLK-100Mhz:    Writing...\0", +	 "CCLK-200Mhz SCLK- 50Mhz:    Writing...\0", +	 "CCLK-200Mhz SCLK- 40Mhz:    Writing...\0",}, +	{"CCLK-100Mhz SCLK-100Mhz:    Writing...\0", +	 "CCLK-100Mhz SCLK- 50Mhz:    Writing...\0", +	 "CCLK-100Mhz SCLK- 25Mhz:    Writing...\0",}, +}; + +int memory_post_test(int flags) +{ +	int addr; +	int m, n; +	int sclk, sclk_temp; +	int ret = 1; + +	sclk_temp = CLKIN / 1000000; +	sclk_temp = sclk_temp * CONFIG_VCO_MULT; +	for (sclk = 0; sclk_temp > 0; sclk++) +		sclk_temp -= CONFIG_SCLK_DIV; +	sclk = sclk * 1000000; +	post_init_uart(sclk); +	if (post_key_pressed() == 0) +		return 0; + +	for (m = 0; m < CCLK_NUM; m++) { +		for (n = 0; n < SCLK_NUM; n++) { +			/* Calculate the sclk */ +			sclk_temp = CLKIN / 1000000; +			sclk_temp = sclk_temp * pll[m][n][0]; +			for (sclk = 0; sclk_temp > 0; sclk++) +				sclk_temp -= pll[m][n][1]; +			sclk = sclk * 1000000; + +			post_init_pll(pll[m][n][0], pll[m][n][1]); +			post_init_sdram(sclk); +			post_init_uart(sclk); +			post_out_buff("\n\r\0"); +			post_out_buff(log[m][n]); +			for (addr = 0x0; addr < CFG_MAX_RAM_SIZE; addr += 4) +				*(unsigned long *)addr = PATTERN1; +			post_out_buff("Reading...\0"); +			for (addr = 0x0; addr < CFG_MAX_RAM_SIZE; addr += 4) { +				if ((*(unsigned long *)addr) != PATTERN1) { +					post_out_buff("Error\n\r\0"); +					ret = 0; +				} +			} +			post_out_buff("OK\n\r\0"); +		} +	} +	if (ret) +		post_out_buff("memory POST passed\n\r\0"); +	else +		post_out_buff("memory POST failed\n\r\0"); + +	post_out_buff("\n\r\n\r\0"); +	return 1; +} + +void post_init_uart(int sclk) +{ +	int divisor; + +	for (divisor = 0; sclk > 0; divisor++) +		sclk -= 57600 * 16; + +	*pPORTF_FER = 0x000F; +	*pPORTH_FER = 0xFFFF; + +	*pUART_GCTL = 0x00; +	*pUART_LCR = 0x83; +	sync(); +	*pUART_DLL = (divisor & 0xFF); +	sync(); +	*pUART_DLH = ((divisor >> 8) & 0xFF); +	sync(); +	*pUART_LCR = 0x03; +	sync(); +	*pUART_GCTL = 0x01; +	sync(); +} + +void post_out_buff(char *buff) +{ + +	int i = 0; +	for (i = 0; i < 0x80000; i++) ; +	i = 0; +	while ((buff[i] != '\0') && (i != 100)) { +		while (!(*pUART_LSR & 0x20)) ; +		*pUART_THR = buff[i]; +		sync(); +		i++; +	} +	for (i = 0; i < 0x80000; i++) ; +} + +/* Using sw10-PF5 as the hotkey */ +#define KEY_LOOP 0x80000 +#define KEY_DELAY 0x80 +int post_key_pressed(void) +{ +	int i, n; +	unsigned short value; + +	*pPORTF_FER &= ~PF5; +	*pPORTFIO_DIR &= ~PF5; +	*pPORTFIO_INEN |= PF5; +	sync(); + +	post_out_buff("########Press SW10 to enter Memory POST########: 3\0"); +	for (i = 0; i < KEY_LOOP; i++) { +		value = *pPORTFIO & PF5; +		if (*pUART0_RBR == 0x0D) { +			value = 0; +			goto key_pressed; +		} +		if (value != 0) { +			goto key_pressed; +		} +		for (n = 0; n < KEY_DELAY; n++) +			asm("nop"); +	} +	post_out_buff("\b2\0"); + +	for (i = 0; i < KEY_LOOP; i++) { +		value = *pPORTFIO & PF5; +		if (*pUART0_RBR == 0x0D) { +			value = 0; +			goto key_pressed; +		} +		if (value != 0) { +			goto key_pressed; +		} +		for (n = 0; n < KEY_DELAY; n++) +			asm("nop"); +	} +	post_out_buff("\b1\0"); + +	for (i = 0; i < KEY_LOOP; i++) { +		value = *pPORTFIO & PF5; +		if (*pUART0_RBR == 0x0D) { +			value = 0; +			goto key_pressed; +		} +		if (value != 0) { +			goto key_pressed; +		} +		for (n = 0; n < KEY_DELAY; n++) +			asm("nop"); +	} +      key_pressed: +	post_out_buff("\b0"); +	post_out_buff("\n\r\0"); +	if (value == 0) +		return 0; +	post_out_buff("Hotkey has been pressed, Enter POST . . . . . .\n\r\0"); +	return 1; +} + +void post_init_pll(int mult, int div) +{ + +	*pSIC_IWR = 0x01; +	*pPLL_CTL = (mult << 9); +	*pPLL_DIV = div; +	asm("CLI R2;"); +	asm("IDLE;"); +	asm("STI R2;"); +	while (!(*pPLL_STAT & 0x20)) ; +} + +int post_init_sdram(int sclk) +{ +	int SDRAM_tRP, SDRAM_tRP_num, SDRAM_tRAS, SDRAM_tRAS_num, SDRAM_tRCD, +	    SDRAM_tWR; +	int SDRAM_Tref, SDRAM_NRA, SDRAM_CL, SDRAM_SIZE, SDRAM_WIDTH, +	    mem_SDGCTL, mem_SDBCTL, mem_SDRRC; + +	if ((sclk > 119402985)) { +		SDRAM_tRP = TRP_2; +		SDRAM_tRP_num = 2; +		SDRAM_tRAS = TRAS_7; +		SDRAM_tRAS_num = 7; +		SDRAM_tRCD = TRCD_2; +		SDRAM_tWR = TWR_2; +	} else if ((sclk > 104477612) && (sclk <= 119402985)) { +		SDRAM_tRP = TRP_2; +		SDRAM_tRP_num = 2; +		SDRAM_tRAS = TRAS_6; +		SDRAM_tRAS_num = 6; +		SDRAM_tRCD = TRCD_2; +		SDRAM_tWR = TWR_2; +	} else if ((sclk > 89552239) && (sclk <= 104477612)) { +		SDRAM_tRP = TRP_2; +		SDRAM_tRP_num = 2; +		SDRAM_tRAS = TRAS_5; +		SDRAM_tRAS_num = 5; +		SDRAM_tRCD = TRCD_2; +		SDRAM_tWR = TWR_2; +	} else if ((sclk > 74626866) && (sclk <= 89552239)) { +		SDRAM_tRP = TRP_2; +		SDRAM_tRP_num = 2; +		SDRAM_tRAS = TRAS_4; +		SDRAM_tRAS_num = 4; +		SDRAM_tRCD = TRCD_2; +		SDRAM_tWR = TWR_2; +	} else if ((sclk > 66666667) && (sclk <= 74626866)) { +		SDRAM_tRP = TRP_2; +		SDRAM_tRP_num = 2; +		SDRAM_tRAS = TRAS_3; +		SDRAM_tRAS_num = 3; +		SDRAM_tRCD = TRCD_2; +		SDRAM_tWR = TWR_2; +	} else if ((sclk > 59701493) && (sclk <= 66666667)) { +		SDRAM_tRP = TRP_1; +		SDRAM_tRP_num = 1; +		SDRAM_tRAS = TRAS_4; +		SDRAM_tRAS_num = 4; +		SDRAM_tRCD = TRCD_1; +		SDRAM_tWR = TWR_2; +	} else if ((sclk > 44776119) && (sclk <= 59701493)) { +		SDRAM_tRP = TRP_1; +		SDRAM_tRP_num = 1; +		SDRAM_tRAS = TRAS_3; +		SDRAM_tRAS_num = 3; +		SDRAM_tRCD = TRCD_1; +		SDRAM_tWR = TWR_2; +	} else if ((sclk > 29850746) && (sclk <= 44776119)) { +		SDRAM_tRP = TRP_1; +		SDRAM_tRP_num = 1; +		SDRAM_tRAS = TRAS_2; +		SDRAM_tRAS_num = 2; +		SDRAM_tRCD = TRCD_1; +		SDRAM_tWR = TWR_2; +	} else if (sclk <= 29850746) { +		SDRAM_tRP = TRP_1; +		SDRAM_tRP_num = 1; +		SDRAM_tRAS = TRAS_1; +		SDRAM_tRAS_num = 1; +		SDRAM_tRCD = TRCD_1; +		SDRAM_tWR = TWR_2; +	} else { +		SDRAM_tRP = TRP_1; +		SDRAM_tRP_num = 1; +		SDRAM_tRAS = TRAS_1; +		SDRAM_tRAS_num = 1; +		SDRAM_tRCD = TRCD_1; +		SDRAM_tWR = TWR_2; +	} +	/*SDRAM INFORMATION: */ +	SDRAM_Tref = 64;	/* Refresh period in milliseconds */ +	SDRAM_NRA = 4096;	/* Number of row addresses in SDRAM */ +	SDRAM_CL = CL_3;	/* 2 */ + +	SDRAM_SIZE = EBSZ_64; +	SDRAM_WIDTH = EBCAW_10; + +	mem_SDBCTL = SDRAM_WIDTH | SDRAM_SIZE | EBE; + +	/* Equation from section 17 (p17-46) of BF533 HRM */ +	mem_SDRRC = +	    (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - +	    (SDRAM_tRAS_num + SDRAM_tRP_num); + +	/* Enable SCLK Out */ +	mem_SDGCTL = +	    (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR +	     | PSS); + +	sync(); + +	*pEBIU_SDGCTL |= 0x1000000; +	/* Set the SDRAM Refresh Rate control register based on SSCLK value */ +	*pEBIU_SDRRC = mem_SDRRC; + +	/* SDRAM Memory Bank Control Register */ +	*pEBIU_SDBCTL = mem_SDBCTL; + +	/* SDRAM Memory Global Control Register */ +	*pEBIU_SDGCTL = mem_SDGCTL; +	sync(); +	return mem_SDRRC; +} + +#endif				/* CONFIG_POST & CFG_POST_MEMORY */ +#endif				/* CONFIG_POST */ |