* Make sure Block Lock Bits get cleared in R360MPI flash driver

* MPC823 LCD driver: Fill color map backwards, to allow for steady
  display when Linux takes over

* Patch by Erwin Rol, 27 Feb 2003:
  Add support for RTEMS (this time for real).

* Add support for "bmp info" and "bmp display" commands to load
  bitmap images; this can be used (for example in a "preboot"
  command) to display a splash screen very quickly after poweron.

* Add support for 133 MHz clock on INCA-IP board
diff --git a/board/incaip/memsetup.S b/board/incaip/memsetup.S
index 0d4de5a..f1afb5c 100644
--- a/board/incaip/memsetup.S
+++ b/board/incaip/memsetup.S
@@ -49,13 +49,11 @@
 #define MC_LATENCY(value)       0x1038(value)
 #define MC_TREFRESH(value)      0x1040(value)
 
-#if CPU_CLOCK_RATE==150000000   /* 150 MHz clock for the MIPS core */
 #define CGU_MODUL_BASE          0xBF107000
 #define CGU_PLL1CR(value)       0x0008(value)
 #define CGU_DIVCR(value)        0x0010(value)
 #define CGU_MUXCR(value)        0x0014(value)
 #define CGU_PLL1SR(value)       0x000C(value)
-#endif
 
 	.globl	memsetup
 memsetup:
@@ -67,12 +65,12 @@
 	li	t1, 0xA0000041
 	sw	t1, EBU_ADDSEL0(t0)
 
-#if CPU_CLOCK_RATE==150000000   /* 150 MHz clock for the MIPS core */
-	li	t1, 0xA841417E
-	sw	t1, EBU_BUSCON0(t0)   /* value set up by magic flash word */
+#if CPU_CLOCK_RATE==100000000	/* 100 MHz clock for the MIPS core */
+	lw	t1, EBU_BUSCON0(t0)  /* value set up by magic flash word */
 	sw	t1, EBU_BUSCON2(t0)
-#else /* 100 MHz */
-	lw	t1, EBU_BUSCON0(t0)   /* value set up by magic flash word */
+#else /* 150 MHz or 133 MHz */
+	li	t1, 0x8841417E
+	sw	t1, EBU_BUSCON0(t0)
 	sw	t1, EBU_BUSCON2(t0)
 #endif
 
@@ -85,10 +83,10 @@
 	li	t1, 0xBE0000F1
  	sw	t1, EBU_ADDSEL1(t0)
 
-#if CPU_CLOCK_RATE==150000000   /* 150 MHz clock for the MIPS core */
-	li	t1, 0x684143FD
-#else /* 100 MHz */
+#if CPU_CLOCK_RATE==100000000   /* 100 MHz clock for the MIPS core */
 	li	t1, 0x684142BD
+#else /* 150 MHz or 133 MHz */
+	li	t1, 0x684143FD
 #endif
  	sw	t1, EBU_BUSCON1(t0)
 
@@ -105,6 +103,14 @@
 	beq     t1, zero, b1
 	li      t1, 0x80000001
 	sw      t1, CGU_MUXCR(t0)
+#elif CPU_CLOCK_RATE==133000000	/* 133 MHz clock for the MIPS core */
+	li	t0, CGU_MODUL_BASE
+	li	t1, 0x80000054
+	sw	t1, CGU_DIVCR(t0)
+	li	t1, 0x80000000
+	sw	t1, CGU_MUXCR(t0)
+	li	t1, 0x800B0001
+	sw	t1, CGU_PLL1CR(t0)
 #endif
 
 	/* SDRAM Initialization.
diff --git a/board/r360mpi/flash.c b/board/r360mpi/flash.c
index e38dfcc..fef483c 100644
--- a/board/r360mpi/flash.c
+++ b/board/r360mpi/flash.c
@@ -206,6 +206,12 @@
 {
 	FPW value;
 
+	/* Make sure Block Lock Bits get cleared */
+	addr[0] = (FPW) 0x00FF00FF;
+	addr[0] = (FPW) 0x00600060;
+	addr[0] = (FPW) 0x00D000D0;
+	addr[0] = (FPW) 0x00FF00FF;
+
 	/* Write auto select command: read Manufacturer ID */
 	addr[0x5555] = (FPW) 0x00AA00AA;
 	addr[0x2AAA] = (FPW) 0x00550055;
diff --git a/board/r360mpi/r360mpi.c b/board/r360mpi/r360mpi.c
index 91e3234..d7b8873 100644
--- a/board/r360mpi/r360mpi.c
+++ b/board/r360mpi/r360mpi.c
@@ -126,12 +126,12 @@
 	memctl->memc_mar = 0x00000088;
 
 	/*
-	 * Map controller bank 2 to the SDRAM bank at
+	 * Map controller bank 1 to the SDRAM bank at
 	 * preliminary address - these have to be modified after the
 	 * SDRAM size has been determined.
 	 */
-	memctl->memc_or2 = CFG_OR2_PRELIM;
-	memctl->memc_br2 = CFG_BR2_PRELIM;
+	memctl->memc_or1 = CFG_OR1_PRELIM;
+	memctl->memc_br1 = CFG_BR1_PRELIM;
 
 	memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE));	/* no refresh yet */
 
@@ -139,9 +139,9 @@
 
 	/* perform SDRAM initializsation sequence */
 
-	memctl->memc_mcr = 0x80004105;	/* SDRAM bank 0 */
+	memctl->memc_mcr = 0x80002105;	/* SDRAM bank 0 */
 	udelay (200);
-	memctl->memc_mcr = 0x80004230;	/* SDRAM bank 0 - execute twice */
+	memctl->memc_mcr = 0x80002230;	/* SDRAM bank 0 - execute twice */
 	udelay (200);
 
 	memctl->memc_mamr |= MAMR_PTAE;	/* enable refresh */
@@ -153,7 +153,7 @@
 	 *
 	 * try 8 column mode
 	 */
-	size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE2_PRELIM,
+	size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE1_PRELIM,
 					   SDRAM_MAX_SIZE);
 
 	udelay (1000);
@@ -161,13 +161,13 @@
 	/*
 	 * try 9 column mode
 	 */
-	size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE2_PRELIM,
+	size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE1_PRELIM,
 					   SDRAM_MAX_SIZE);
 
 	if (size8 < size9) {		/* leave configuration at 9 columns */
 		size_b0 = size9;
 /*	debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);	*/
-	} else {			/* back to 8 columns            */
+	} else {					/* back to 8 columns            */
 		size_b0 = size8;
 		memctl->memc_mamr = CFG_MAMR_8COL;
 		udelay (500);
@@ -200,47 +200,6 @@
 
 	udelay (10000);
 
-#ifdef CONFIG_CAN_DRIVER
-	/* Initialize OR3 / BR3 */
-	memctl->memc_or3 = CFG_OR3_CAN;		/* switch GPLB_5 to GPLA_5 */
-	memctl->memc_br3 = CFG_BR3_CAN;
-
-	/* Initialize MBMR */
-	memctl->memc_mbmr = MAMR_GPL_B4DIS;	/* GPL_B4 works as UPWAITB */
-
-	/* Initialize UPMB for CAN: single read */
-	memctl->memc_mdr = 0xFFFFC004;
-	memctl->memc_mcr = 0x0100 | UPMB;
-
-	memctl->memc_mdr = 0x0FFFD004;
-	memctl->memc_mcr = 0x0101 | UPMB;
-
-	memctl->memc_mdr = 0x0FFFC000;
-	memctl->memc_mcr = 0x0102 | UPMB;
-
-	memctl->memc_mdr = 0x3FFFC004;
-	memctl->memc_mcr = 0x0103 | UPMB;
-
-	memctl->memc_mdr = 0xFFFFDC05;
-	memctl->memc_mcr = 0x0104 | UPMB;
-
-	/* Initialize UPMB for CAN: single write */
-	memctl->memc_mdr = 0xFFFCC004;
-	memctl->memc_mcr = 0x0118 | UPMB;
-
-	memctl->memc_mdr = 0xCFFCD004;
-	memctl->memc_mcr = 0x0119 | UPMB;
-
-	memctl->memc_mdr = 0x0FFCC000;
-	memctl->memc_mcr = 0x011A | UPMB;
-
-	memctl->memc_mdr = 0x7FFCC004;
-	memctl->memc_mcr = 0x011B | UPMB;
-
-	memctl->memc_mdr = 0xFFFDCC05;
-	memctl->memc_mcr = 0x011C | UPMB;
-#endif
-
 	return (size_b0);
 }
 
@@ -254,8 +213,8 @@
  * - short between data lines
  */
 
-static long int dram_size (long int mamr_value,
-			   long int *base, long int maxsize)
+static long int dram_size (long int mamr_value, long int *base,
+						   long int maxsize)
 {
 	volatile immap_t *immap = (immap_t *) CFG_IMMR;
 	volatile memctl8xx_t *memctl = &immap->im_memctl;
@@ -298,10 +257,10 @@
 
 /* ------------------------------------------------------------------------- */
 
-void r360_i2c_lcd_write (uchar data0, uchar data1)
+void r360_pwm_write (uchar reg, uchar val)
 {
-	if (i2c_write (CFG_I2C_LCD_ADDR, data0, 1, &data1, 1)) {
-		printf("Can't write lcd data 0x%02X 0x%02X.\n", data0, data1);
+	if (i2c_write (CFG_I2C_PWM_ADDR, reg, 1, &val, 1)) {
+		printf ("Can't write PWM register 0x%02X.\n", reg);
 	}
 }
 
@@ -312,8 +271,10 @@
  */
 
 /* Number of bytes returned from Keyboard Controller */
-#define KEYBD_KEY_MAX	16				/* maximum key number */
-#define KEYBD_DATALEN	((KEYBD_KEY_MAX + 7) / 8)	/* normal key scan data */
+#define KEYBD_KEY_MAX		20				/* maximum key number */
+#define KEYBD_DATALEN		((KEYBD_KEY_MAX + 7) / 8)	/* normal key scan data */
+
+static uchar kbd_addr = CFG_I2C_KBD_ADDR;
 
 static uchar *key_match (uchar *);
 
@@ -326,14 +287,14 @@
 
 	i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
 
-	i2c_read (CFG_I2C_KEY_ADDR, 0, 0, kbd_data, KEYBD_DATALEN);
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
 
 	for (i = 0; i < KEYBD_DATALEN; ++i) {
 		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
 	}
 	setenv ("keybd", keybd_env);
 
-	str = strdup (key_match (keybd_env));	/* decode keys */
+	str = strdup (key_match (kbd_data));	/* decode keys */
 
 #ifdef CONFIG_PREBOOT	/* automatically configure "preboot" command on key match */
 	setenv ("preboot", str);	/* set or delete definition */
@@ -363,13 +324,16 @@
 static uchar kbd_magic_prefix[] = "key_magic";
 static uchar kbd_command_prefix[] = "key_cmd";
 
-static uchar *key_match (uchar * kbd_str)
+static uchar *key_match (uchar * kbd_data)
 {
+	uchar compare[KEYBD_DATALEN];
 	uchar magic[sizeof (kbd_magic_prefix) + 1];
 	uchar cmd_name[sizeof (kbd_command_prefix) + 1];
-	uchar *str, *suffix;
+	uchar key_mask;
+	uchar *str, *nxt, *suffix;
 	uchar *kbd_magic_keys;
 	char *cmd;
+	int i;
 
 	/*
 	 * The following string defines the characters that can pe appended
@@ -379,48 +343,62 @@
 	 * "key_magic" is checked (old behaviour); the string "125" causes
 	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
 	 */
-	if ((kbd_magic_keys = getenv ("magic_keys")) != NULL) {
-		/* loop over all magic keys;
-		 * use '\0' suffix in case of empty string
-		 */
-		for (suffix = kbd_magic_keys;
-		     *suffix || suffix == kbd_magic_keys;
-		     ++suffix) {
-			sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+	if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+		kbd_magic_keys = "";
 
+	/* loop over all magic keys;
+	 * use '\0' suffix in case of empty string
+	 */
+	for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix) {
+		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
 #if 0
-			printf ("### Check magic \"%s\"\n", magic);
+		printf ("### Check magic \"%s\"\n", magic);
 #endif
 
-			if ((str = getenv (magic)) != 0) {
+		memcpy(compare, kbd_data, KEYBD_DATALEN);
 
-#if 0
-				printf ("### Compare \"%s\" \"%s\"\n",
-					kbd_str, str);
-#endif
-				if (strcmp (kbd_str, str) == 0) {
-					sprintf (cmd_name, "%s%c",
-						 kbd_command_prefix,
-						 *suffix);
+		for (str = getenv(magic); str != NULL; str = (*nxt) ? nxt+1 : nxt) {
+			uchar c;
+
+			c = (uchar) simple_strtoul (str, (char **) (&nxt), 16);
+
+			if (str == nxt)				/* invalid character */
+				break;
+
+			if (c >= KEYBD_KEY_MAX)			/* bad key number */
+				goto next_magic;
+
+			key_mask = 0x80 >> (c % 8);
 
-					if ((cmd = getenv (cmd_name)) != 0) {
+			if (!(compare[c / 8] & key_mask))	/* key not pressed */
+				goto next_magic;
+
+			compare[c / 8] &= ~key_mask;
+		}
+
+		for (i=0; i<KEYBD_DATALEN; i++)
+			if (compare[i])			/* key(s) not released */
+				goto next_magic;
+
+		sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+
+		cmd = getenv (cmd_name);
 #if 0
-						printf ("### Set PREBOOT to $(%s): \"%s\"\n",
-							cmd_name, cmd);
+		printf ("### Set PREBOOT to $(%s): \"%s\"\n",
+			cmd_name, cmd ? cmd : "<<NULL>>");
 #endif
-						return (cmd);
-					}
-				}
-			}
-		}
+		*kbd_data = *suffix;
+		return (cmd);
+
+	next_magic:;
 	}
 #if 0
 	printf ("### Delete PREBOOT\n");
 #endif
-	*kbd_str = '\0';
+	*kbd_data = '\0';
 	return (NULL);
 }
-#endif	/* CONFIG_PREBOOT */
+#endif							/* CONFIG_PREBOOT */
 
 /* Read Keyboard status */
 int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
@@ -432,7 +410,7 @@
 	i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
 
 	/* Read keys */
-	i2c_read (CFG_I2C_KEY_ADDR, 0, 0, kbd_data, KEYBD_DATALEN);
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
 
 	puts ("Keys:");
 	for (i = 0; i < KEYBD_DATALEN; ++i) {