Index: arch/arm/mach-imx/generic.c
===================================================================
--- arch/arm/mach-imx/generic.c	(revision 3303)
+++ arch/arm/mach-imx/generic.c	(working copy)
@@ -30,6 +30,10 @@
 #include <asm/hardware.h>
 #include <linux/interrupt.h>
 
+//#undef VGA_SCREEN
+#define VGA_SCREEN 1
+#define NORM_SCREEN 0
+#define SVGA_SCREEN 0
 void imx_gpio_mode(int gpio_mode)
 {
 	unsigned int pin = gpio_mode & GPIO_PIN_MASK;
@@ -480,12 +484,22 @@
 	while (CSCR & CSCR_SPLL_RESTART)
 	    ;
 #endif	
-	/* Set the peripheral clock divider 3 (PERDIV3) to divide by 6 */
-//	PCDR1 &= ~PCDR1_PERDIV3_MASK;
-//	PCDR1 |= PCDR1_PERDIV3(5);
+#if VGA_SCREEN
+	/* Set the peripheral clock divider 3 (PERDIV3) to divide by 7 */
+	PCDR1 &= ~PCDR1_PERDIV3_MASK;
+	PCDR1 |= PCDR1_PERDIV3(7);  // 6 is preferred, but triggers a bug in the MX21 LCDC controller that causes the graphic overlay window to pan to the right uncontrollably.
+#endif
+#if SVGA_SCREEN
+	/* Set the peripheral clock divider 3 (PERDIV3) to divide by 2 */
+	PCDR1 &= ~PCDR1_PERDIV3_MASK;
+	PCDR1 |= PCDR1_PERDIV3(1);  // set to 176 MHz 
+#endif
+#if NORM_SCREEN
+	/* Set the peripheral clock divider 3 (PERDIV3) to divide by 8 */
         /* For 352 MHz clock - PCLCK3 = 44MHz */
 	PCDR1 &= ~PCDR1_PERDIV3_MASK;
 	PCDR1 |= PCDR1_PERDIV3(7);
+#endif
 
 	//	printk( "+++set PCLK2,4\n" );
         /* For 352 MHz clock - PCLCK2 = 33MHz */
Index: arch/arm/mach-imx/mx21ads.c
===================================================================
--- arch/arm/mach-imx/mx21ads.c	(revision 3672)
+++ arch/arm/mach-imx/mx21ads.c	(working copy)
@@ -75,12 +75,26 @@
 unsigned int chumby_hwversion;
 EXPORT_SYMBOL(chumby_hwversion);
 
+#define HIRES_SCREEN 1
+#define SVGA_SCREEN 0
+#define NORM_SCREEN 0
+
 static struct imxfb_mach_info mx21ads_fb_info __initdata = {
   // PERDIV3 = 7, 44 MHz clock rate
     .pixclock     = 62500,
     .bpp          = 16,
+#if HIRES_SCREEN
+    .xres         = 640,
+    .yres         = 480,
+#endif
+#if SVGA_SCREEN
+    .xres         = 800,
+    .yres         = 600,
+#endif
+#if NORM_SCREEN
     .xres         = 320,
     .yres         = 240,
+#endif
     .hsync_len    = 0x1,
     .vsync_len    = 0x1,
     .left_margin  = 0xf,
@@ -411,7 +425,8 @@
     // A11 USBH1_FS    PB26
     // A12 USBH1_OE    PB27
     // G11 USBH_ON     PB25
-    
+
+#if 1 // make 0 to turn off internal usb port    
     imx_gpio_mode(29 | GPIO_PORTB | GPIO_PF | GPIO_OUT | GPIO_PUEN  );   // USBH1_TXDP
     imx_gpio_mode(28 | GPIO_PORTB | GPIO_PF | GPIO_OUT | GPIO_PUEN  );   // USBH1_TXDM
     imx_gpio_mode(31 | GPIO_PORTB | GPIO_PF | GPIO_IN | GPIO_PUEN  );   // USBH1_RXDP
@@ -419,6 +434,13 @@
     imx_gpio_mode(26 | GPIO_PORTB | GPIO_PF | GPIO_OUT );   /* USBH1 FS */
     imx_gpio_mode(27 | GPIO_PORTB | GPIO_PF | GPIO_OUT | GPIO_PUEN );   // USBH1_OE
     imx_gpio_mode(25 | GPIO_PORTB | GPIO_PF | GPIO_OUT | GPIO_PUEN  );   // USBH_ON
+#else
+    DDIR(1) |= 0xFC000000;
+    OCR2(1) |= 0xFFF00000;
+    ICONFA2(1) &= 0x000FFFFF;
+    GIUS(1) |= 0xFC000000;
+    DR(1)   |= 0xFC000000;
+#endif
     PUEN(1) |= 0x08000000; // enable pull-up on OE line -- may want to consider this also on the other 2 ports
 
     printk( "DDIR(1): %08X\n", DDIR(1));
Index: drivers/video/imxfb.c
===================================================================
--- drivers/video/imxfb.c	(revision 3304)
+++ drivers/video/imxfb.c	(working copy)
@@ -17,6 +17,10 @@
  */
 
 #define DEBUG 1
+#undef EMU_HIRES_SCREEN
+#define VGA_SCREEN 1
+#define SVGA_SCREEN 0
+#define NORM_SCREEN 0
 
 // pr_debug was replaced with printk
 
@@ -72,6 +76,8 @@
 	.transp = { .offset = 0,  .length = 0, },
 };
 
+static unsigned long global_a = 0;
+
 static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info);
 static int imxfbov_activate_var(struct fb_var_screeninfo *var, struct fb_info *info);
 
@@ -366,26 +372,32 @@
 
         if (fbi->pcr & PCR_REV_VS) {
             /* Vertical scan is reversed */
+#ifdef EMU_HIRES_SCREEN
+            int xres = 320;
+            int yres = 240;
+            int bpp  = fbi->max_bpp;
+            int offset = (xres * (yres - 1) * (bpp / 8));
+#else
             int xres = fbi->max_xres;
             int yres = fbi->max_yres;
             int bpp  = fbi->max_bpp;
             int offset = (xres * (yres - 1) * (bpp / 8));
-
+#endif
 	    // LCDC frame buffer logo force setting code framebuffer -- bunnie
-	    for( i = 0; i < 0x25800; i++ ) {
+	    for( i = 0; i < 0x96000; i++ ) {
 	      *((unsigned char *)fbi->screen_dma + offset + i) = *((unsigned char *)0xC2500000 + i);
 	    }
             LCDC_SSA	= fbi->screen_dma + offset;
         } else {
 	    // LCDC frame buffer logo force setting code framebuffer -- bunnie
-	    for( i = 0; i < 0x25800; i++ ) {
+	    for( i = 0; i < 0x96000; i++ ) {
 	      *((unsigned char *)fbi->screen_dma + i) = *((unsigned char *)0xC2500000 + i);
 	    }
             LCDC_SSA	= fbi->screen_dma;
         }
 
 	/* physical screen start address */
-	LCDC_VPW	= VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4);
+	LCDC_VPW	= VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4); 
 
         /* panning offset 0 (0 pixel offset) */
 	LCDC_POS	= 0x00000000;
@@ -424,6 +436,7 @@
 
         /* panning offset 0 (0 pixel offset) */
 	LCDC_LGWPOR	= 0x00000000;
+	LCDC_LGWPR      = 0;
 
         /* fixed burst length (see erratum 11) */
         LCDC_LGWDCR =  DMACR_HM(3) | DMACR_TM(8);
@@ -545,7 +558,11 @@
 	                  VCR_V_WAIT_1(var->upper_margin) |
 			  VCR_V_WAIT_2(var->lower_margin);
 
+#ifdef EMU_HIRES_SCREEN
+	LCDC_SIZE	= SIZE_XMAX(320) | SIZE_YMAX(240);
+#else
 	LCDC_SIZE	= SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres);
+#endif
 	LCDC_PCR	= fbi->pcr;
 	LCDC_PWMR	= fbi->pwmr;
 	LCDC_LSCR1	= fbi->lscr1;
@@ -604,8 +621,8 @@
 	  //   BPIX     (LPCR[27:25]) = 101		:16pp in memory
 	  //   PIXPOL   (LPCR[24])    = 0  		:Pixels are active low
 	  
-	  //   FLMPOL   (LPCR[23])    = 0  		:VSYNC is active high
-	  //   LPPOL    (LPCR[22])    = 0  		:HSYNC is active high
+	  //   FLMPOL   (LPCR[23])    = 1  		:VSYNC is active low
+	  //   LPPOL    (LPCR[22])    = 1  		:HSYNC is active low
 	  //   CLKPOL   (LPCR[21])    = 0  		:LSCLK is active on positive edge
 	  //   OEPOL    (LPCR[20])    = 0  		:OE is active high
 	  
@@ -619,8 +636,85 @@
 
 	  //   SCLKSEL  (LPCR[7])     = 1  		:Enable OE and LSCLK when no data output
 	  //   SHARP    (LPCR[6])     = 0  		:Disable Sharp signals
-	  //   PCD      (LPCR[5:0])   = 000100  	:Pixel Clock = LSCLK = 33.25MHz/5 = 6.65MHz (DI demo board is @ 5.26MHz)
-	  //                          = 000111  	:V and H timing calculated with Pixel Clock = LSCLK = 33.25MHz/8 = 4.15MHz, but less noise at higher LSCLK
+	  //   PCD      (LPCR[5:0])   = 000001  	:Pixel Clock = LSCLK = 50.285 / 2 = 25.142
+	  
+	  // we want 25.175 MHz (typ)
+	  
+	  // 1100 1010 1100 1000 0000 0000 1000 0001
+	  // CAC8 0081
+#if VGA_SCREEN
+	  LCDC_PCR = 0xCAC80082;
+	  
+	  // If we're not using a Sharp panel, clear this register to be safe
+	  LCDC_LSCR1 = 0x00000000;
+	  
+	  // Configure horizontal LCD timing
+	  // 30 = H_WIDTH = 0x1E
+	  // TH - (HS + EP) = 800 - (640 + 30) = 130 = H_WAIT_1 = 0x82
+	  // HS-DEN - HS time 144 - 30 = 114 = H_WAIT_2 = 0x72
+	  LCDC_HCR = 0x78008272;
+	  
+	  // Configure vertical LCD timing
+	  // V_WIDTH = 3
+	  // V_WIDTH_1 = 525 - (480 + 35) = 10 = 0xA
+	  // V_WIDTH_2 = TSTV - TWV = 35 - 3 = 32 = 0x20
+	  LCDC_VCR = 0x0C000A20;
+
+	  LCDC_LGWPOR	= 0x00000000;
+	  LCDC_LGWPR      = 0;
+#endif
+#if SVGA_SCREEN
+	  // Setup LCDC panel configuration
+	  //   TFT      (LPCR[31])    = 1  		:TFT display
+	  //   COLOR    (LPCR[30])    = 1  		:Color display
+	  //   PBSIZ    (LPCR[29:28]) = 00 		:Active matrix fixed at 16bpp
+	  
+	  //   BPIX     (LPCR[27:25]) = 101		:16pp in memory
+	  //   PIXPOL   (LPCR[24])    = 0  		:Pixels are active low
+	  
+	  //   FLMPOL   (LPCR[23])    = 1  		:VSYNC is active low
+	  //   LPPOL    (LPCR[22])    = 1  		:HSYNC is active low
+	  //   CLKPOL   (LPCR[21])    = 1  		:LSCLK is active on negative edge
+	  //   OEPOL    (LPCR[20])    = 0  		:OE is active high
+	  
+	  //   SCLKIDLE (LPCR[19])    = 1  		:Enable LSCLK when VSYNC is idle
+	  //   END_SEL  (LPCR[18])    = 0  		:Image in memory is in little endian format
+	  //   SWAP_SEL (LPCR[17])    = 0  		:Ignored for big endian format
+	  //   REV_VS   (LPCR[16])    = 0  		:Vertical scan in normal direction
+	  
+	  //   ACDSEL   (LPCR[15])    = 0  		:Ignored for TFT display
+	  //   ACD      (LPCR[14:8])  = 0000000 	:Ignored for TFT display
+
+	  //   SCLKSEL  (LPCR[7])     = 1  		:Enable OE and LSCLK when no data output
+	  //   SHARP    (LPCR[6])     = 0  		:Disable Sharp signals
+	  //   PCD      (LPCR[5:0])   = 000100  	:Pixel Clock = LSCLK = 176 / 5 = 35.2 MHz
+	  
+	  // we want 40 MHz (typ)
+	  
+	  // 1100 1010 1110 1000 0000 0000 1000 0100
+	  // CAC8 0081
+
+	  LCDC_PCR = 0xCAE80084;
+	  
+	  // If we're not using a Sharp panel, clear this register to be safe
+	  LCDC_LSCR1 = 0x00000000;
+	  
+	  // Configure horizontal LCD timing
+	  // 128 = H_WIDTH = 0x80 - 1 = 0x7F 
+	  // TH - (HS + EP) = 1056 - (800 + 128) = 128 = H_WAIT_1 = 0x80 - 4 (cycle fudge) = 0x7C
+	  // H_WAIT_2 = 128 = 0x0
+	  LCDC_HCR = 0x7F007C00;
+	  
+	  // Configure vertical LCD timing
+	  // V_WIDTH = 4
+	  // V_WIDTH_1 = 666 - (600 + 4 + 23) = 0x27
+	  // V_WIDTH_2 = 23 = 0x17
+	  LCDC_VCR = 0x10002717;
+
+	  LCDC_LGWPOR	= 0x00000000;
+	  LCDC_LGWPR      = 0;
+#endif
+#if NORM_SCREEN
 	  LCDC_PCR = 0xCA080084;	
 	  
 	  // If we're not using a Sharp panel, clear this register to be safe
@@ -631,6 +725,8 @@
 	  
 	  // Configure vertical LCD timing
 	  LCDC_VCR = 0x10000F0F;
+#endif
+
 	}
 		
 	// Setup DMA for main frame buffer
@@ -651,7 +747,14 @@
 	struct imxfb_info *fbi = info->par;
 
 	printk( "imxfbov_activate_var\n" );
+#ifdef EMU_HIRES_SCREEN
+	LCDC_LGWSR	= SIZE_XMAX(320) | SIZE_YMAX(240);
+#else
 	LCDC_LGWSR	= SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres);
+
+#endif
+	LCDC_LGWPOR	= 0x00000000;
+	LCDC_LGWPR      = 0;
 	LCDC_LGWDCR	= fbi->dmacr;
 	LCDC_LGWPR      = 0;
 
@@ -1063,7 +1166,7 @@
     green = (key >>  8) & 0x3f;
     blue  = (key >>  0) & 0x3f;
 
-    lgwcr |= ((red << 12) | (green << 6) | (blue));
+    lgwcr |= (((red << 12) | (green << 6) | (blue)) & 0x3ffff);
 
     printk( "imxfb_proc_write_key %lx\n", (unsigned long) lgwcr );
     LCDC_LGWCR = lgwcr;
@@ -1071,7 +1174,94 @@
     return count;
 }
 
+static int imxfb_proc_debug(char *buf, char **start, off_t offset,
+			    int count, int *eof, void *data)
+{
+  int len;
+  int i;
+  
+  len = sprintf(buf, "dumping\n" );
+  *eof = 1;
+  
+  // hack hack, but whatever, it's a lot easier and faster to write for debug purposes
+  printk("LCDC_SSA   : %08lx\n", (unsigned long) LCDC_SSA);
+  printk("LCDC_SIZE  : %08lx\n", (unsigned long) LCDC_SIZE);
+  printk("LCDC_VPW   : %08lx\n", (unsigned long) LCDC_VPW);
+  printk("LCDC_CPOS  : %08lx\n", (unsigned long) LCDC_CPOS);
+  printk("LCDC_LCWHB : %08lx\n", (unsigned long) LCDC_LCWHB);
+  printk("LCDC_LCHCC : %08lx\n", (unsigned long) LCDC_LCHCC);
+  printk("LCDC_PCR   : %08lx\n", (unsigned long) LCDC_PCR);
+  printk("LCDC_HCR   : %08lx\n", (unsigned long) LCDC_HCR);
+  printk("LCDC_VCR   : %08lx\n", (unsigned long) LCDC_VCR);
+  printk("LCDC_POS   : %08lx\n", (unsigned long) LCDC_POS);
+  printk("LCDC_LSCR1 : %08lx\n", (unsigned long) LCDC_LSCR1);
+  printk("LCDC_PWMR  : %08lx\n", (unsigned long) LCDC_PWMR);
+  printk("LCDC_DMACR : %08lx\n", (unsigned long) LCDC_DMACR);
+  printk("LCDC_RMCR  : %08lx\n", (unsigned long) LCDC_RMCR);
+  printk("LCDC_LCDICR: %08lx\n", (unsigned long) LCDC_LCDICR);
+  printk("LCDC_LCDISR: %08lx\n", (unsigned long) LCDC_LCDISR);
+  printk("LCDC_LGWSAR: %08lx\n", (unsigned long) LCDC_LGWSAR);
+  printk("LCDC_LGWSR : %08lx\n", (unsigned long) LCDC_LGWSR);
+  printk("LCDC_LGWVPWR:%08lx\n", (unsigned long) LCDC_LGWVPWR);
+  printk("LCDC_LGWPOR: %08lx\n", (unsigned long) LCDC_LGWPOR);
+  printk("LCDC_LGWPR : %08lx\n", (unsigned long) LCDC_LGWPR);
+  printk("LCDC_LGWCR : %08lx\n", (unsigned long) LCDC_LGWCR);
+  printk("LCDC_PALETTE(0): %08lx\n", (unsigned long) LCDC_PALETTE(0));
+  printk("LCDC_PALETTE(1): %08lx\n", (unsigned long) LCDC_PALETTE(1));
+  printk("LCDC_PALETTE(2): %08lx\n", (unsigned long) LCDC_PALETTE(2));
+  printk("LCDC_PALETTE(3): %08lx\n", (unsigned long) LCDC_PALETTE(3));
 
+#if 0
+  printk("WSRA: %08lx\n", (unsigned long) WSRA );
+  printk("WSRB: %08lx\n", (unsigned long) WSRB );
+  printk("XSRA: %08lx\n", (unsigned long) XSRA );
+  printk("XSRB: %08lx\n", (unsigned long) XSRB );
+  printk("YSRA: %08lx\n", (unsigned long) YSRA );
+  printk("YSRB: %08lx\n", (unsigned long) YSRB );
+  for( i = 0; i < 16; i++ ) {
+    printk("SAR(%d): %08lx\n", i, (unsigned long) SAR(i) );
+    printk("DAR(%d): %08lx\n", i, (unsigned long) DAR(i) );
+    printk("CNTR(%d): %08lx\n", i, (unsigned long) CNTR(i) );
+    printk("CCR(%d): %08lx\n", i, (unsigned long) CCR(i) );
+    printk("RSSR(%d): %08lx\n", i, (unsigned long) RSSR(i) );
+    printk("BLR(%d): %08lx\n", i, (unsigned long) BLR(i) );
+    printk("CHCNTR(%d): %08lx\n", i, (unsigned long) CHCNTR(i) );
+  }
+#endif
+
+  return len;
+}
+
+
+static int imxfb_proc_write_debug(struct file *file, const char *buf,
+                                   unsigned long count, void *data)
+{
+  unsigned long d;
+  d = simple_strtoul(buf, NULL, 0);
+
+  printk( "imxfb set register %08lx with %08lx\n", global_a, d );
+
+  if( global_a > 0x68 ) 
+    printk( "error: address out of range.\n" );
+  else
+    __REG(IMX_LCDC_BASE + global_a) = d;
+    
+  return count;
+}
+
+static int imxfb_proc_write_debugAddr(struct file *file, const char *buf,
+                                   unsigned long count, void *data)
+{
+  unsigned long a;
+  a = simple_strtoul(buf, NULL, 0);
+
+  global_a = a;
+
+  printk( "imxfb addr set to %lx\n", global_a );
+    
+  return count;
+}
+
 static int imxfb_proc_read_key_en(char *buf, char **start, off_t offset,
                                   int count, int *eof, void *data)
 {
@@ -1096,9 +1286,14 @@
     en = simple_strtoul(buf, NULL, 0);
 
     if (en) {
-        LCDC_LGWCR |= LGWCR_GWCKE;
+      uint32_t saveClock = PCCR0 & PCCR0_HCLK_LCDC_EN; // save state of HCLK
+      PCCR0 &= ~ PCCR0_HCLK_LCDC_EN; // force HCLK off
+
+      LCDC_LGWCR |= LGWCR_GWCKE;
+      
+      PCCR0 |= saveClock; // restore the state of HCLK
     } else {
-        LCDC_LGWCR &= ~LGWCR_GWCKE;
+      LCDC_LGWCR &= ~LGWCR_GWCKE;
     }
     
     return count;
@@ -1126,6 +1321,14 @@
                                  imxfb_proc_read_key_en, NULL);
     pde->write_proc = imxfb_proc_write_key_en;
 
+    pde = create_proc_read_entry("driver/imxfb/debug", 0, NULL, 
+				 imxfb_proc_debug, NULL );
+    pde->write_proc = imxfb_proc_write_debug;
+
+    pde = create_proc_read_entry("driver/imxfb/debugAddr", 0, NULL, 
+				 imxfb_proc_debug, NULL );
+    pde->write_proc = imxfb_proc_write_debugAddr;
+
 }
 
 static int __init imxfb_probe(struct platform_device *pdev)
@@ -1247,7 +1450,7 @@
 	//	for( i = 0; i < 0x40000; i++ ) {
 	//	  *((unsigned char *)LCDC_SSA + i) = *((unsigned char *)0xC1000000 + i);
 	//	}
-	for( i = 0; i < 0x25800; i++ ) {
+	for( i = 0; i < 0xA6000; i++ ) {
 	  *((unsigned char *)LCDC_SSA + i) = *((unsigned char *)0xC2500000 + i);
 	}
 	// consider hoisting above the DMA setting code in imxfb_enable_controller
