OMAP242x H4 board update
- fix for ES2 differences.
- switch to using the cfi_flash driver.
- fix SRAM build address.
- fix for GP device operation.
- unlock SRAM for GP devices.
- display more device information.
- fix potential deadlock in omap24xx_i2c driver.
- fix DLL load values to match dpllout*1 operation.
- fix 2nd chip select init for combo DDR device.
- add support for CFI Intel 28F256L18 on H4 board.
Patch by Richard Woodruff, 03 Mar 2005
diff --git a/board/omap2420h4/Makefile b/board/omap2420h4/Makefile
index deab6b6..38dec00 100644
--- a/board/omap2420h4/Makefile
+++ b/board/omap2420h4/Makefile
@@ -25,7 +25,7 @@
 
 LIB	= lib$(BOARD).a
 
-OBJS	:= omap2420h4.o flash.o mem.o sys_info.o
+OBJS	:= omap2420h4.o mem.o sys_info.o
 SOBJS	:= platform.o
 
 $(LIB):	$(OBJS) $(SOBJS)
diff --git a/board/omap2420h4/config.mk b/board/omap2420h4/config.mk
index e6aa756..3edcde0 100644
--- a/board/omap2420h4/config.mk
+++ b/board/omap2420h4/config.mk
@@ -19,4 +19,10 @@
 # Used with full SRAM boot.
 # This is either with a GP system or a signed boot image.
 # easiest, and safest way to go if you can.
-#TEXT_BASE = 0x40280000
+#TEXT_BASE = 0x40270000
+
+
+# Handy to get symbols to debug ROM version.
+#TEXT_BASE = 0x0
+#TEXT_BASE = 0x08000000
+#TEXT_BASE = 0x04000000
diff --git a/board/omap2420h4/mem.c b/board/omap2420h4/mem.c
index 9ae595b..62eb6e3 100644
--- a/board/omap2420h4/mem.c
+++ b/board/omap2420h4/mem.c
@@ -48,7 +48,7 @@
  *********************************************************************************/
 void prcm_init(void)
 {
-	u32 rev,div;
+	u32 div;
 	void (*f_lock_pll) (u32, u32, u32, u32);
 	extern void *_end_vect, *_start;
 
@@ -64,11 +64,7 @@
 	__raw_writel(DSP_DIV, CM_CLKSEL_DSP);	/* set dsp and iva dividers */
 	__raw_writel(GFX_DIV, CM_CLKSEL_GFX);	/* set gfx dividers */
 
-	rev  = get_cpu_rev();
-	if (rev == CPU_2420_ES1 || rev ==  CPU_2422_ES1)
-		div = BUS_DIV_ES1;
-	else
-		div	= BUS_DIV;
+	div = BUS_DIV;
 	__raw_writel(div, CM_CLKSEL1_CORE);/* set L3/L4/USB/Display/Vlnc/SSi dividers */
 	sdelay(1000);
 
@@ -99,6 +95,23 @@
 	sdelay(1000);
 }
 
+/**************************************************************************
+ * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow
+ *  command line mem=xyz use all memory with out discontigious support
+ *  compiled in.  Could do it at the ATAG, but there really is two banks...
+ * Called as part of 2nd phase DDR init.
+ **************************************************************************/
+void make_cs1_contiguous(void)
+{
+	u32 size, a_add_low, a_add_high;
+
+	size = get_sdr_cs_size(SDRC_CS0_OSET);
+	size /= SZ_32M;  /* find size to offset CS1 */
+	a_add_high = (size & 3) << 8;   /* set up low field */
+	a_add_low = (size & 0x3C) >> 2; /* set up high field */
+	__raw_writel((a_add_high|a_add_low),SDRC_CS_CFG);
+
+}
 
 /********************************************************
  *  mem_ok() - test used to see if timings are correct
@@ -122,6 +135,7 @@
 		return(1);
 }
 
+
 /********************************************************
  *  sdrc_init() - init the sdrc chip selects CS0 and CS1
  *  - early init routines, called from flash or
@@ -148,28 +162,29 @@
  **************************************************************************/
 void do_sdrc_init(u32 offset, u32 early)
 {
-	u32 cpu, bug=0, rev, common=0, cs0=0, pmask=0, pass_type;
+	u32 cpu, dllen=0, rev, common=0, cs0=0, pmask=0, pass_type, mtype;
 	sdrc_data_t *sdata;	 /* do not change type */
 	u32 a, b, r;
 
 	static const sdrc_data_t sdrc_2422 =
 	{
 		H4_2422_SDRC_SHARING, H4_2422_SDRC_MDCFG_0_DDR, 0 , H4_2422_SDRC_ACTIM_CTRLA_0,
-		H4_2422_SDRC_ACTIM_CTRLB_0, H4_2422_SDRC_RFR_CTRL_ES1, H4_2422_SDRC_MR_0_DDR,
-		0, H4_2422_SDRC_DLLA_CTRL, H4_2422_SDRC_DLLB_CTRL
+		H4_2422_SDRC_ACTIM_CTRLB_0, H4_2422_SDRC_RFR_CTRL, H4_2422_SDRC_MR_0_DDR,
+		0, H4_2422_SDRC_DLLAB_CTRL
 	};
 	static const sdrc_data_t sdrc_2420 =
 	{
 		H4_2420_SDRC_SHARING, H4_2420_SDRC_MDCFG_0_DDR, H4_2420_SDRC_MDCFG_0_SDR,
 		H4_2420_SDRC_ACTIM_CTRLA_0, H4_2420_SDRC_ACTIM_CTRLB_0,
-		H4_2420_SDRC_RFR_CTRL_ES1, H4_2420_SDRC_MR_0_DDR, H4_2420_SDRC_MR_0_SDR,
-		H4_2420_SDRC_DLLA_CTRL, H4_2420_SDRC_DLLB_CTRL
+		H4_2420_SDRC_RFR_CTRL, H4_2420_SDRC_MR_0_DDR, H4_2420_SDRC_MR_0_SDR,
+		H4_2420_SDRC_DLLAB_CTRL
 	};
 
 	if (offset == SDRC_CS0_OSET)
 		cs0 = common = 1;  /* int regs shared between both chip select */
 
 	cpu = get_cpu_type();
+	rev = get_cpu_rev();
 
 	/* warning generated, though code generation is correct. this may bite later,
 	 * but is ok for now. there is only so much C code you can do on stack only
@@ -197,9 +212,15 @@
 		if(running_from_internal_boot())
 			sdata = (sdrc_data_t *)((u32)sdata + 0x4000);
 	}
-	if (!early && (get_mem_type() == DDR_COMBO)) {/* combo part has a shared CKE signal, can't use feature */
-		pmask = BIT2;
-		pass_type = COMBO_DDR; /* CS1 config */
+
+	if (!early && (((mtype = get_mem_type()) == DDR_COMBO)||(mtype == DDR_STACKED))) {
+		if(mtype == DDR_COMBO){
+			pmask = BIT2;/* combo part has a shared CKE signal, can't use feature */
+			pass_type = COMBO_DDR; /* CS1 config */
+			__raw_writel((__raw_readl(SDRC_POWER)) & ~pmask, SDRC_POWER);
+		}
+		if(rev != CPU_2420_2422_ES1)	/* for es2 and above smooth things out */
+			make_cs1_contiguous();
 	}
 
 next_mem_type:
@@ -208,11 +229,10 @@
 		wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000);/* wait till reset done set */
 		__raw_writel(0, SDRC_SYSCONFIG);		/* clear soft reset */
 		__raw_writel(sdata->sdrc_sharing, SDRC_SHARING);
-		__raw_writel((__raw_readl(SDRC_POWER)) & ~pmask, SDRC_POWER);
 #ifdef POWER_SAVE
 		__raw_writel(__raw_readl(SMS_SYSCONFIG)|SMART_IDLE, SMS_SYSCONFIG);
 		__raw_writel(sdata->sdrc_sharing|SMART_IDLE, SDRC_SHARING);
-		__raw_writel((__raw_readl(SDRC_POWER)|BIT6) & ~pmask, SDRC_POWER);
+		__raw_writel((__raw_readl(SDRC_POWER)|BIT6), SDRC_POWER);
 #endif
 	}
 
@@ -224,15 +244,16 @@
 		__raw_writel(sdata->sdrc_mdcfg_0_sdr, SDRC_MCFG_0+offset);
 	}
 
-	if(pass_type == IP_SDR){  /* SDRAM can run full speed only rated for 105MHz*/
-		a = H4_242X_SDRC_ACTIM_CTRLA_0_100MHz;
-		b = H4_242X_SDRC_ACTIM_CTRLB_0_100MHz;
-		r = H4_2420_SDRC_RFR_CTRL;
-	} else {
-		a = sdata->sdrc_actim_ctrla_0;
-		b = sdata->sdrc_actim_ctrlb_0;
-		r = sdata->sdrc_rfr_ctrl;
-	}
+	a = sdata->sdrc_actim_ctrla_0;
+	b = sdata->sdrc_actim_ctrlb_0;
+	r = sdata->sdrc_dllab_ctrl;
+
+	/* work around ES1 DDR issues */
+	if((pass_type != IP_SDR) && (rev == CPU_2420_2422_ES1)){
+		a = H4_242x_SDRC_ACTIM_CTRLA_0_ES1;
+		b = H4_242x_SDRC_ACTIM_CTRLB_0_ES1;
+		r = H4_242x_SDRC_RFR_CTRL_ES1;
+ 	}
 
 	if (cs0) {
 		__raw_writel(a, SDRC_ACTIM_CTRLA_0);
@@ -241,7 +262,6 @@
 		__raw_writel(a, SDRC_ACTIM_CTRLA_1);
 		__raw_writel(b, SDRC_ACTIM_CTRLB_1);
 	}
-
 	__raw_writel(r, SDRC_RFR_CTRL+offset);
 
 	/* init sequence for mDDR/mSDR using manual commands (DDR is a bit different) */
@@ -263,18 +283,22 @@
 		__raw_writel(sdata->sdrc_mr_0_ddr, SDRC_MR_0+offset);
 
 	/* NOTE: ES1 242x _BUG_ DLL + External Bandwidth fix*/
-	rev  = get_cpu_rev();
-	if (rev == CPU_2420_ES1 || rev ==  CPU_2422_ES1){
-		bug = BIT0;
+	if (rev == CPU_2420_2422_ES1){
+		dllen = (BIT0|BIT3); /* es1 clear both bit0 and bit3 */
 		__raw_writel((__raw_readl(SMS_CLASS_ARB0)|BURSTCOMPLETE_GROUP7)
 			,SMS_CLASS_ARB0);/* enable bust complete for lcd */
 	}
-	/* enable & load up DLL with good value for 75MHz, and set phase to 90% */
+	else
+		dllen = BIT0|BIT1; /* es2, clear bit0, and 1 (set phase to 72) */
+
+	/* enable & load up DLL with good value for 75MHz, and set phase to 90
+	 * ES1 recommends 90 phase, ES2 recommends 72 phase.
+	 */
 	if (common && (pass_type != IP_SDR)) {
-		__raw_writel(sdata->sdrc_dlla_ctrl, SDRC_DLLA_CTRL);
-		__raw_writel(sdata->sdrc_dlla_ctrl & ~(BIT2|bug), SDRC_DLLA_CTRL);
-		__raw_writel(sdata->sdrc_dllb_ctrl, SDRC_DLLB_CTRL);
-		__raw_writel(sdata->sdrc_dllb_ctrl & ~(BIT2|bug) , SDRC_DLLB_CTRL);
+		__raw_writel(sdata->sdrc_dllab_ctrl, SDRC_DLLA_CTRL);
+		__raw_writel(sdata->sdrc_dllab_ctrl & ~(BIT2|dllen), SDRC_DLLA_CTRL);
+		__raw_writel(sdata->sdrc_dllab_ctrl, SDRC_DLLB_CTRL);
+		__raw_writel(sdata->sdrc_dllab_ctrl & ~(BIT2|dllen) , SDRC_DLLB_CTRL);
 	}
 	sdelay(90000);
 
@@ -291,12 +315,18 @@
  *****************************************************/
 void gpmc_init(void)
 {
-	u32 mux=0, mtype, mwidth;
+	u32 mux=0, mtype, mwidth, rev, tval;
+
+	rev  = get_cpu_rev();
+	if (rev == CPU_2420_2422_ES1)
+		tval = 1;
+	else
+		tval = 0;  /* disable bit switched meaning */
 
 	/* global settings */
 	__raw_writel(0x10, GPMC_SYSCONFIG);	/* smart idle */
 	__raw_writel(0x0, GPMC_IRQENABLE);	/* isr's sources masked */
-	__raw_writel(0x1, GPMC_TIMEOUT_CONTROL);/* timeout disable */
+	__raw_writel(tval, GPMC_TIMEOUT_CONTROL);/* timeout disable */
 #ifdef CFG_NAND_BOOT
 	__raw_writel(0x001, GPMC_CONFIG);	/* set nWP, disable limited addr */
 #else
diff --git a/board/omap2420h4/omap2420h4.c b/board/omap2420h4/omap2420h4.c
index 219bcf4..c729eca 100644
--- a/board/omap2420h4/omap2420h4.c
+++ b/board/omap2420h4/omap2420h4.c
@@ -36,7 +36,7 @@
 extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
 #endif
 
-static void wait_for_command_complete(unsigned int wd_base);
+ void wait_for_command_complete(unsigned int wd_base);
 
 /*******************************************************
  * Routine: delay
@@ -83,6 +83,21 @@
 }
 
 /**********************************************************
+ * Routine: try_unlock_sram()
+ * Description: If chip is GP type, unlock the SRAM for
+ *  general use.
+ ***********************************************************/
+void try_unlock_sram(void)
+{
+	/* if GP device unlock device SRAM for general use */
+	if (get_device_type() == GP_DEVICE) {
+		__raw_writel(0xFF, A_REQINFOPERM0);
+		__raw_writel(0xCFDE, A_READPERM0);
+		__raw_writel(0xCFDE, A_WRITEPERM0);
+	}
+}
+
+/**********************************************************
  * Routine: s_init
  * Description: Does early system init of muxing and clocks.
  * - Called path is with sram stack.
@@ -144,7 +159,7 @@
  * Routine: wait_for_command_complete
  * Description: Wait for posting to finish on watchdog
  ******************************************************/
-static void wait_for_command_complete(unsigned int wd_base)
+void wait_for_command_complete(unsigned int wd_base)
 {
 	int pending = 1;
 	do {
@@ -200,7 +215,7 @@
 {
 	DECLARE_GLOBAL_DATA_PTR;
 	unsigned int size0=0,size1=0;
-	u32 mtype, btype;
+	u32 mtype, btype, rev, cpu;
 	u8 chg_on = 0x5; /* enable charge of back up battery */
 	u8 vmode_on = 0x8C;
 	#define NOT_EARLY 0
@@ -209,6 +224,8 @@
 
 	btype = get_board_type();
 	mtype = get_mem_type();
+	rev = get_cpu_rev();
+	cpu = get_cpu_type();
 
 	display_board_info(btype);
 	if (btype == BOARD_H4_MENELAUS){
@@ -219,15 +236,16 @@
 
 	if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) {
 		do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY);	/* init other chip select */
-		size0 = size1 = SZ_32M;
-	} else if (mtype == SDR_DISCRETE)
-		size0 = SZ_128M;
-	else
-		size0 = SZ_64M;
+	}
+	size0 = get_sdr_cs_size(SDRC_CS0_OSET);
+	size1 = get_sdr_cs_size(SDRC_CS1_OSET);
 
 	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
 	gd->bd->bi_dram[0].size = size0;
-	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+	if(rev == CPU_2420_2422_ES1) /* ES1's 128MB remap granularity isn't worth doing */
+		gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+	else /* ES2 and above can remap at 32MB granularity */
+		gd->bd->bi_dram[1].start = PHYS_SDRAM_1+size0;
 	gd->bd->bi_dram[1].size = size1;
 
 	return 0;
diff --git a/board/omap2420h4/sys_info.c b/board/omap2420h4/sys_info.c
index 121d679..9864d3e 100644
--- a/board/omap2420h4/sys_info.c
+++ b/board/omap2420h4/sys_info.c
@@ -29,6 +29,16 @@
 #include <i2c.h>
 
 /**************************************************************************
+ * get_prod_id() - get id info from chips
+ ***************************************************************************/
+static u32 get_prod_id(void)
+{
+	u32 p;
+	p = __raw_readl(PRODUCTION_ID); /* get production ID */
+	return((p & CPU_242X_PID_MASK) >> 16);
+}
+
+/**************************************************************************
  * get_cpu_type() - low level get cpu type
  * - no C globals yet.
  * - just looking to say if this is a 2422 or 2420 or ...
@@ -40,6 +50,14 @@
 {
 	u32 v;
 
+	switch(get_prod_id()){
+		case 1:;/* 2420 */
+		case 2: return(CPU_2420); break; /* 2420 pop */
+		case 4: return(CPU_2422); break;
+		case 8: return(CPU_2423); break;
+		default: break;  /* early 2420/2422's unmarked */
+	}
+
 	v = __raw_readl(TAP_IDCODE_REG);
 	v &= CPU_24XX_ID_MASK;
 	if (v == CPU_2420_CHIPID) {	  /* currently 2420 and 2422 have same id */
@@ -61,6 +79,16 @@
 	v = v >> 28;
 	return(v+1);  /* currently 2422 and 2420 match up */
 }
+/****************************************************
+ * is_mem_sdr() - return 1 if mem type in use is SDR
+ ****************************************************/
+u32 is_mem_sdr(void)
+{
+	volatile u32 *burst = (volatile u32 *)(SDRC_MR_0+SDRC_CS0_OSET);
+	if(*burst == H4_2420_SDRC_MR_0_SDR)
+		return(1);
+	return(0);
+}
 
 /***********************************************************
  * get_mem_type() - identify type of mDDR part used.
@@ -70,24 +98,40 @@
  *************************************************************/
 u32 get_mem_type(void)
 {
-	volatile u32 *burst = (volatile u32 *)(SDRC_MR_0+SDRC_CS0_OSET);
+	u32 cpu, sdr = is_mem_sdr();
 
-	if (get_cpu_type() == CPU_2422)
+	cpu = get_cpu_type();
+	if (cpu == CPU_2422 || cpu == CPU_2423)
 		return(DDR_STACKED);
 
+	if(get_prod_id() == 0x2)
+		return(XDR_POP);
+
 	if (get_board_type() == BOARD_H4_MENELAUS)
-		if(*burst == H4_2420_SDRC_MR_0_SDR)
+		if(sdr)
 			return(SDR_DISCRETE);
 		else
 			return(DDR_COMBO);
 	else
-		if(*burst == H4_2420_SDRC_MR_0_SDR) /* SDP + SDR kit */
+		if(sdr) /* SDP + SDR kit */
 			return(SDR_DISCRETE);
 		else
 			return(DDR_DISCRETE); /* origional SDP */
 }
 
 /***********************************************************************
+ * get_cs0_size() - get size of chip select 0/1
+ ************************************************************************/
+u32 get_sdr_cs_size(u32 offset)
+{
+	u32 size;
+	size = __raw_readl(SDRC_MCFG_0+offset) >> 8; /* get ram size field */
+	size &= 0x2FF;   /* remove unwanted bits */
+	size *= SZ_2M;   /* find size in MB */
+	return(size);
+}
+
+/***********************************************************************
  * get_board_type() - get board type based on current production stats.
  *  --- NOTE: 2 I2C EEPROMs will someday be populated with proper info.
  *      when they are available we can get info from there.  This should
@@ -104,7 +148,7 @@
 /******************************************************************
  * get_sysboot_value() - get init word settings (dip switch on h4)
  ******************************************************************/
-u32 get_sysboot_value(void)
+inline u32 get_sysboot_value(void)
 {
 	return(0x00000FFF & __raw_readl(CONTROL_STATUS));
 }
@@ -193,22 +237,53 @@
  *********************************************************************/
 void display_board_info(u32 btype)
 {
-	char cpu_2420[] = "2420";
+	char cpu_2420[] = "2420";   /* cpu type */
 	char cpu_2422[] = "2422";
-	char db_men[] = "Menelaus";
-	char db_ip[]= "IP";
-	char *cpu_s, *db_s;
-	u32 cpu = get_cpu_type();
+	char cpu_2423[] = "2423";
+	char db_men[] = "Menelaus"; /* board type */
+	char db_ip[] = "IP";
+	char mem_sdr[] = "mSDR";    /* memory type */
+	char mem_ddr[] = "mDDR";
+	char t_tst[] = "TST";	    /* security level */
+	char t_emu[] = "EMU";
+	char t_hs[] = "HS";
+	char t_gp[] = "GP";
+	char unk[] = "?";
 
-	if(cpu == CPU_2420)
-		cpu_s = cpu_2420;
+	char *cpu_s, *db_s, *mem_s, *sec_s;
+	u32 cpu, rev, sec;
+
+	rev = get_cpu_rev();
+	cpu = get_cpu_type();
+	sec = get_device_type();
+
+	if(is_mem_sdr())
+		mem_s = mem_sdr;
 	else
+		mem_s = mem_ddr;
+
+	if(cpu == CPU_2423)
+		cpu_s = cpu_2423;
+	else if (cpu == CPU_2422)
 		cpu_s = cpu_2422;
+	else
+		cpu_s = cpu_2420;
+
 	if(btype ==  BOARD_H4_MENELAUS)
 		db_s = db_men;
 	else
 		db_s = db_ip;
-	printf("TI H4 SDP Base Board with OMAP%s %s Daughter Board\n",cpu_s, db_s);
+
+	switch(sec){
+		case TST_DEVICE: sec_s = t_tst; break;
+		case EMU_DEVICE: sec_s = t_emu; break;
+		case HS_DEVICE:  sec_s = t_hs; break;
+		case GP_DEVICE:  sec_s = t_gp; break;
+		default: sec_s = unk;
+	}
+
+	printf("OMAP%s-%s revision %d\n", cpu_s, sec_s, rev-1);
+	printf("TI H4 SDP Base Board + %s Daughter Board + %s \n", db_s, mem_s);
 }
 
 /*************************************************************************
@@ -230,7 +305,7 @@
 /********************************************************
  *  get_base(); get upper addr of current execution
  *******************************************************/
-static u32 get_base(void)
+u32 get_base(void)
 {
 	u32  val;
 	__asm__ __volatile__("mov %0, pc \n" : "=r" (val) : : "memory");
@@ -242,7 +317,7 @@
 /********************************************************
  *  get_base2(); get 2upper addr of current execution
  *******************************************************/
-static u32 get_base2(void)
+u32 get_base2(void)
 {
 	u32  val;
 	__asm__ __volatile__("mov %0, pc \n" : "=r" (val) : : "memory");
@@ -300,3 +375,14 @@
 	else
 		return(0);
 }
+
+/*************************************************************
+ *  get_device_type(): tell if GP/HS/EMU/TST
+ *************************************************************/
+u32 get_device_type(void)
+{
+	int mode;
+	mode = __raw_readl(CONTROL_STATUS) & (BIT10|BIT9|BIT8);
+	return(mode >>= 8);
+}
+