⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 em86xx_dram.c

📁 bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************** Copyright © 2001-2005 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************/#include "config.h"#include "uart.h"#include "util.h"#include "vsprintf.h"#include "em86xxapi.h"#include "emhwlib_registers.h"/* Format for interact with this mode:    Input:	GRB address -- read byte from given address	GRW address -- read word from given address	GRD address -- read dword from given address	GWB address value -- write given byte value to given address	GWW address value -- write given word value to given address	GWD address value -- write given dword value to given address	Q -- quit to normal bootloader	address, value -- hexidecimal numeric string (max. 8 chars)	Each command string followed by '\n' or '\r'.    Output (for GRx command):	hexidecimal value -- followed by '\n'    To build this, in the configuration file, set	STAGE0_XTRA_IMAGE_SIZE = 4096	DEBUG_DRAMADJUSTMENT = y        and uncomment the line		// #define LLAD_SUPPORT    and do make.*/// #define LLAD_SUPPORT		/* For turning bootloader into a small command shell */#ifdef CONFIG_USE_SYSCLK#define uart_reinit()   do { __msleep(5); uart_init_port(DEFAULT_UART_PORT, DEFAULT_UART_BAUDRATE, 0); __msleep(5); } while (0)#else#define uart_reinit()   do { __msleep(5); } while (0)#endif/* From rmdef/rmbtypes.h */typedef unsigned char RMuint8;typedef char RMint8;typedef unsigned short RMuint16;typedef short RMint16;typedef unsigned long RMuint32;typedef long RMint32;typedef unsigned char RMbool;typedef char RMascii;typedef int RMstatus;static inline RMuint32 gbus_read_uint32(RMuint32 byte_address){    return *((volatile RMuint32 *)byte_address);}static inline RMuint16 gbus_read_uint16(RMuint32 byte_address){    return *((volatile RMuint16 *)byte_address);}static inline RMuint8 gbus_read_uint8(RMuint32 byte_address){    return *((volatile RMuint8 *)byte_address);}static inline void gbus_write_uint32(RMuint32 byte_address, RMuint32 data){    *((volatile RMuint32 *)byte_address) = data;}static inline void gbus_write_uint16(RMuint32 byte_address, RMuint16 data){    *((volatile RMuint16 *)byte_address) = data;}static inline void gbus_write_uint8(RMuint32 byte_address, RMuint8 data){    *((volatile RMuint8 *)byte_address) = data;}#ifndef LLAD_SUPPORT#ifndef DEBUG_DRAMADJUSTMENT#define uart_init()	;#define uart_putc(x)	;#define uart_puts(x)	;#define uart_printf(x,...)  ;#undef uart_reinit#define uart_reinit()   do { __msleep(1); } while (0)#endif#define MIN_GOOD_SIZE	5	/* Minimum good size to look for */#define RMsetConsecutiveBits(target,begin,end,value)		\	*(target)=(						\		   (						\		    (*(target))					\		    &						\		    (~(						\		       ( ( 1 << ((end)-(begin)+1) ) - 1 )	\		       <<					\		       (begin)					\		      )						\                    )						\		   )						\		   |						\		   ( \                    ( (value) & ( ( 1 << ((end)-(begin)+1) ) - 1 ) ) \                    << \                    (begin) \		   ) \                  )static void reset_state(int delay, unsigned long pll, unsigned long cfg);static RMuint32 test_capdelay_1freq_dram0_gfx(RMuint32 wd, RMuint32 *size);static RMuint32 test_with_fixed_wd(unsigned long wd, unsigned long *set_dunit_cfg, 				unsigned long *set_dunit_delay, unsigned long *size);#ifndef DEBUG_DRAMADJUSTMENTstatic void emergency(const char *s);#endif//static unsigned long ctable[] = { 0x06200000, 0x06300000, 0x03300000, 0x03400000, 0 };static const unsigned long ctable[] = { 0x03400000, 0x03300000, 0x06300000, 0x06200000 };void xtra_stage0(unsigned int configaddr){    register int i;    RMuint32 res, size;//    unsigned long saved_dunit_cfg = default_dram0_dunit_cfg;//    unsigned long saved_delay0_ctrl = default_dram_dunit_delay0_ctrl;    unsigned long set_dunit_cfg, set_dunit_delay;    unsigned long test_system_clock, wd, wres;//    unsigned long xtal_in1, xtal_in2;//    xtal_in1 = gbus_read_uint32(REG_BASE_SYSTEM + SYS_xtal_in_cnt);    uart_init();    uart_puts("\nDRAM Delay Adjustment\n");    if (((loaderconfig_t *)configaddr)->signature != LOADER_CONFIGSIGN) {        uart_puts("  Invalid configuration\n");        return;    }    /* Overclock for 10% */    test_system_clock = (DEFAULT_CLKGEN_PLL & 0xfffffc00) | ((DEFAULT_CLKGEN_PLL & 0x000003ff) * 11 / 10);    reset_state(0, test_system_clock, 0);    uart_putc('\n');    for (wres = 0, wd = 6; wd <= 0xf; wd++) {	res = test_with_fixed_wd(wd, &set_dunit_cfg, &set_dunit_delay, &size);//	if (res >= (sizeof(ctable) >> 3))	if (res != 0)	    wres |= (1 << wd);    }    for (i = 6, wd = 0, res = 0xf; i < res; i++) {	if (wd == 0) {	    if (((1 << i) & wres) != 0)		wd = i;	} else if (((1 << i) & (~wres)) != 0)		res = i;    }    uart_printf("\n**** Best write delay: %d,%d (0x%x) ****\n", wd, res, wres);//    if ((wd = ((res + wd) >> 1)) != 0) 	/* This is the best write delay we found */    if ((wd = (wd + ((res - wd - 1) >> 1))) != 0) 	/* This is the best write delay we found */	test_with_fixed_wd(wd, &set_dunit_cfg, &set_dunit_delay, &size);    uart_printf("\nBest dunit_cfg 0x%08lx, dunit_delay 0x%08lx, write delay: %d, size %d. => ", set_dunit_cfg, set_dunit_delay, wd, size);    if (size != 0) {	uart_puts("applied.\n");	reset_state(set_dunit_delay, 0, set_dunit_cfg);    } else {	uart_puts("not applied.\n");    	reset_state(0, 0, 0); /* Set to use new delay */#ifndef DEBUG_DRAMADJUSTMENT	emergency("DRAM parms not found.");#endif    }//    xtal_in2 = gbus_read_uint32(REG_BASE_SYSTEM + SYS_xtal_in_cnt);//    *((volatile unsigned long *)0x13000000) = xtal_in2 - xtal_in1;    return;}static RMuint32 test_with_fixed_wd(RMuint32 wd, unsigned long *set_dunit_cfg, 				unsigned long *set_dunit_delay, unsigned long *size){    register int i;    RMuint32 test_size, res, count;    for (*set_dunit_cfg = *set_dunit_delay = *size = count = i = 0; i < (sizeof(ctable) >> 2); i++) {       	gbus_write_uint32(REG_BASE_dram_controller_0 + G2L_RESET_CONTROL, 3);       	gbus_write_uint32(REG_BASE_dram_controller_0 + G2L_RESET_CONTROL, 2);    	gbus_write_uint32(REG_BASE_dram_controller_0 + DRAM_dunit_cfg, (DEFAULT_DRAM0_DUNIT_CFG & 0xf88fffff) | ctable[i]);    	gbus_write_uint32(REG_BASE_dram_controller_0 + DRAM_dunit_delay0_ctrl, 				(DEFAULT_DRAM_DUNIT_DELAY0_CTRL & 0xfff0ffff) | (wd << 16));       	gbus_write_uint32(REG_BASE_dram_controller_0 + G2L_RESET_CONTROL, 0);	if ((res = test_capdelay_1freq_dram0_gfx(wd << 16, &test_size)) != 0) {	    if (test_size >= *size) {    	        *set_dunit_cfg = gbus_read_uint32(REG_BASE_dram_controller_0 + DRAM_dunit_cfg);	        *set_dunit_delay = res;	        *size = test_size;	    }	    if (test_size >= MIN_GOOD_SIZE)		count++;        }    }    return(count);}static void __usleep(int usec){    unsigned long start, end;    start = gbus_read_uint32(REG_BASE_SYSTEM + SYS_xtal_in_cnt);    end = start + (usec * 27);    if (end <= start)        while (gbus_read_uint32(REG_BASE_SYSTEM + SYS_xtal_in_cnt) > start);    while (gbus_read_uint32(REG_BASE_SYSTEM + SYS_xtal_in_cnt) < end);}static inline void __msleep(int msec){    while (msec-- > 0)         __usleep(998);}#ifndef DEBUG_DRAMADJUSTMENT#if DEFAULT_UART_PORT == 0#define UART_BASE	(UART0_BASE)#else#define UART_BASE	(UART1_BASE)#endif#if DEFAULT_UART_STOPBITS == 2#define LCR	((DEFAULT_UART_DATABITS-5)|UART_LCR_STOP|DEFAULT_UART_PARITY)#else#define LCR	((DEFAULT_UART_DATABITS-5)|DEFAULT_UART_PARITY)#endifstatic void emergency(const char *ptr){    int clkdiv;#ifdef CONFIG_USE_SYSCLK    unsigned long speed = ((EM86XX_EXT_CLOCK/((((DEFAULT_CLKGEN_PLL&0x3f0000)>>16)+2)*2))*((DEFAULT_CLKGEN_PLL&0x3ff)+2));#endif    gbus_write_uint32(UART_BASE + UART_IER, 0x00);            // IRQ ENABL: all disabled    gbus_write_uint32(UART_BASE + UART_FCR, 0x1f);        // FIFO CTRL: depth=16, clear rec & transm. FIFO, Tx.Trig = 4bytes    gbus_write_uint32(UART_BASE + UART_LCR, LCR);             // LINE CTRL: #ifdef CONFIG_USE_SYSCLK    gbus_write_uint32(UART_BASE + UART_CLKSEL, 0x00);         // CLK  SEL : SELECT INTERNAL CLOCK    clkdiv = speed / (DEFAULT_UART_BAUDRATE << 4);#else    gbus_write_uint32(UART_BASE + UART_CLKSEL, 0x01);         // CLK  SEL : SELECT EXTERNAL CLOCK    clkdiv = EM86XX_EXT_CLOCK / (DEFAULT_UART_BAUDRATE << 4);#endif    gbus_write_uint32(UART_BASE + UART_CLKDIV, clkdiv);           while (*ptr != '\0') {    	gbus_write_uint32(UART_BASE + UART_TBR, *ptr++);    	while ((gbus_read_uint32(UART_BASE + UART_LSR) & 0x20) == 0);    }    gbus_write_uint32(UART_BASE + UART_TBR, '\r');    while ((gbus_read_uint32(UART_BASE + UART_LSR) & 0x20) == 0);}#endifstatic void reset_state(int delay, unsigned long pll, unsigned long cfg){    int i;    unsigned long rbase;    gbus_write_uint32(REG_BASE_system_block + SYS_sysclk_mux, 0);    gbus_write_uint32(REG_BASE_system_block + SYS_clkgen0_pll, pll ? pll : DEFAULT_CLKGEN_PLL);    gbus_write_uint32(REG_BASE_system_block + SYS_sysclk_mux, 1);    __msleep(1);    for (rbase = REG_BASE_dram_controller_0, i = 0; i < 1; ++i, rbase += 0x10000) {//        unsigned long rbase = 0x30000 + i * 0x10000;        gbus_write_uint32(rbase + G2L_RESET_CONTROL, 3);        gbus_write_uint32(rbase + G2L_RESET_CONTROL, 2);        gbus_write_uint32(rbase, cfg ? cfg : DEFAULT_DRAM0_DUNIT_CFG);        gbus_write_uint32(rbase + 4, delay ? delay : DEFAULT_DRAM_DUNIT_DELAY0_CTRL);        gbus_write_uint32(rbase + G2L_RESET_CONTROL, 0);    }    uart_reinit();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -