--- w100fb.c.org	2003-08-15 19:13:28.000000000 +0900
+++ w100fb.c	2003-09-18 21:06:03.000000000 +0900
@@ -54,6 +54,9 @@
 #include <video/fbcon-mfb.h>
 #include <video/fbcon.h>
 
+#include <linux/proc_fs.h>
+#include <asm/proc/pgtable.h>
+
 #include "w100fb.h"
 #include <linux/pm.h>
 
@@ -74,6 +77,7 @@
 static void w100_resume(void);
 static void w100_suspend(u32 mode);
 static void w100_init_qvga_rotation(u16 deg);
+static void w100_init_vga_rotation(u16 deg);
 static void w100_soft_reset(void);
 static void w100_clear_screen(u32 mode,void *fbuf);
 static void w100_vsync(void);
@@ -106,7 +110,7 @@
 #define REMAPPED_CFG_LEN  0x10
 #define REMAPPED_MMR_LEN  0x2000
 #define W100_PHYS_ADR_LEN 0x1000000
-#define MAX_XRES          480
+#define MAX_XRES          640
 #define MAX_YRES          640
 #define BITS_PER_PIXEL    16
 
@@ -177,6 +181,8 @@
 #define LCD_MODE_480    0
 #define LCD_MODE_320    1
 #define LCD_MODE_240    2
+#define LCD_MODE_640    3
+
 #define LCD_MODE_UNKOWN (-1)
 
 int w100fb_lcdMode = LCD_MODE_UNKOWN; //default UNKOWN
@@ -245,6 +251,63 @@
 static void w100_PwmSetup(void);
 static void w100_InitExtMem(u32 mode);
 
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *proc_w100;
+
+static ssize_t w100_read_params(struct file *file, char *buf,
+								   size_t nbytes, loff_t *ppos)
+{
+	char outputbuf[15];
+	int count;
+	if (*ppos>0) /* Assume reading completed in previous read*/
+		return 0;
+	count = sprintf(outputbuf, "Can not output.\n");
+	*ppos += count;
+	if (count>nbytes)	/* Assume output can be read at one time */
+		return -EINVAL;
+	if (copy_to_user(buf, outputbuf, count))
+		return -EFAULT;
+	return count;
+}
+
+static ssize_t w100_write_params(struct file *file, const char *buf,
+									size_t nbytes, loff_t *ppos)
+{
+	int	len;
+	unsigned long		param;
+	unsigned long		regs;
+	char			mode[20];
+
+	sscanf(buf,"%s %x %x",mode,&regs,&param);
+	
+	printk("mode %s:: regs 0x%08X :params  0x%08X\n",mode,regs,param);
+	
+	if ( strcmp(mode,"read") == 0) {
+ 
+		if (regs <= 0x2000){
+			param = readl(remapped_regs+regs);
+		}
+		printk("read regs 0x%08X  : 0x%08X\n",regs,param);
+
+	}else if ( strcmp(mode,"write") == 0) { 
+		if (regs <= 0x2000){
+			writel(param, remapped_regs+regs);
+		printk("write regs 0x%08x : 0x%08X\n",regs,param);
+		}
+
+	}
+
+	len=strlen(buf);
+
+	return len;
+}
+
+static struct file_operations proc_params_operations = {
+	read:	w100_read_params,
+	write:	w100_write_params,
+};
+#endif
+
 /* ------------------- chipset specific functions -------------------------- */
 
 //
@@ -317,8 +380,12 @@
       // remap the areas we're going to use
       remapped_base = ioremap_nocache(W100_PHYS_ADDRESS, REMAPPED_CFG_LEN);
       remapped_regs = ioremap_nocache(W100_REG_BASE, REMAPPED_MMR_LEN);
-      remapped_fbuf = ioremap_nocache(W100_FB_BASE, REMAPPED_FB_LEN);
-
+#if 0
+      remapped_fbuf = ioremap_nocache(W100_FB_BASE, REMAPPED_FB_LEN);
+#else
+      remapped_fbuf = __ioremap(W100_FB_BASE, REMAPPED_FB_LEN, L_PTE_BUFFERABLE);
+#endif
+ 
       isRemapped = 1;
   }
 
@@ -385,7 +452,7 @@
 
   if (w100fb_lcdMode == LCD_MODE_UNKOWN){
       w100_InitExtMem(LCD_SHARP_VGA);
-  } else if(w100fb_lcdMode == LCD_MODE_480) {
+  } else if( (w100fb_lcdMode == LCD_MODE_480) || (w100fb_lcdMode == LCD_MODE_640) ) {
       w100_InitExtMem(LCD_SHARP_VGA);
   } else {
       w100_InitExtMem(LCD_SHARP_QVGA);
@@ -400,6 +467,32 @@
   writel((u32)(wrap_top_dir.val), remapped_regs+mmWRAP_TOP_DIR);
 
   writel((u32)0x2440, remapped_regs+mmRBBM_CNTL);
+
+#ifdef CONFIG_PROC_FS
+	{
+		struct proc_dir_entry *entry;
+
+		proc_w100 = proc_mkdir("driver/w100", NULL);
+		if (proc_w100 == NULL) {
+			unregister_chrdev(228, "w100");
+			printk(KERN_ERR "w100: can't create /proc/driver/w100\n");
+			return -ENOMEM;
+		}
+		entry = create_proc_entry("w100",
+								  S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
+								  proc_w100);
+		if (entry) {
+			entry->proc_fops = &proc_params_operations;
+		} else {
+			remove_proc_entry("driver/w100", &proc_root);
+			proc_w100 = 0;
+			unregister_chrdev(228, "w100");
+			printk(KERN_ERR "w100: can't create /proc/driver/w100/\n");
+			return -ENOMEM;
+		}
+	}
+#endif
+
 }
 
 //
@@ -454,7 +547,7 @@
 
   fix->smem_start = W100_FB_BASE;
 
-  if(w100fb_lcdMode == LCD_MODE_UNKOWN || w100fb_lcdMode == LCD_MODE_480){
+  if(w100fb_lcdMode == LCD_MODE_UNKOWN || w100fb_lcdMode == LCD_MODE_480 ){
 
       fix->line_length = (480 * BITS_PER_PIXEL) / 8;
       fix->smem_len = 0x200000;
@@ -469,6 +562,11 @@
       fix->line_length = (240 * BITS_PER_PIXEL) / 8;
       fix->smem_len = 0x60000;
 
+  } else if(w100fb_lcdMode == LCD_MODE_640){
+
+      fix->line_length = (640 * BITS_PER_PIXEL) / 8;
+      fix->smem_len = 0x200000;
+
   }
 
   fix->mmio_start = W100_REG_BASE;
@@ -494,13 +592,14 @@
     BUG();
 
   if((par->xres == 480 && par->yres == 640)||
+     (par->xres == 640 && par->yres == 480)||
      (par->xres == 320 && par->yres == 240)||
      (par->xres == 240 && par->yres == 320)){
       par->xres = var->xres;
       par->yres = var->yres;
   }else{
-      par->xres = MAX_XRES;
-      par->yres = MAX_YRES;
+      par->xres = 480;
+      par->yres = 640;
   }
 
   par->xres_virtual =
@@ -547,13 +646,14 @@
 
   // set up screen coordinates
   if((par->xres == 480 && par->yres == 640)||
+     (par->xres == 640 && par->yres == 480)||
      (par->xres == 320 && par->yres == 240)||
      (par->xres == 240 && par->yres == 320)){
       var->xres = par->xres;
       var->yres = par->yres;
   }else{
-      var->xres = MAX_XRES;
-      var->yres = MAX_YRES;
+      var->xres = 480;
+      var->yres = 640;
   }
 
   var->xres_virtual = var->xres;
@@ -873,6 +973,70 @@
 
 	  w100fb_lcdMode = LCD_MODE_240;
 
+      }else if(current_par.xres == 640 && current_par.yres == 480){
+
+	  printk("change resolution 480x640 => 640x480\n");
+
+	  w100_PwmSetup();
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
+	  w100_InitExtMem(LCD_SHARP_VGA);
+	  w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
+	  w100_vsync();
+	  w100_init_sharp_lcd(LCD_SHARP_VGA);
+	  w100_init_vga_rotation( (u16)270 );
+	  lcdtg_lcd_change(LCD_SHARP_VGA);
+
+	  w100fb_lcdMode = LCD_MODE_640;
+
+      }
+      break;
+  case LCD_MODE_640:
+      if(current_par.xres == 320 && current_par.yres == 240){
+
+	  printk("change resolution 640x480 => 320x240\n");
+
+	  w100_PwmSetup();
+	  w100_vsync();
+	  w100_suspend(W100_SUSPEND_EXTMEM);
+	  w100_init_sharp_lcd(LCD_SHARP_QVGA);
+	  w100_init_qvga_rotation( (u16)270 );
+	  w100_InitExtMem(LCD_SHARP_QVGA);
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  lcdtg_lcd_change(LCD_SHARP_QVGA);
+
+	  w100fb_lcdMode = LCD_MODE_320;
+
+      }else if(current_par.xres == 240 && current_par.yres == 320){
+
+	  printk("change resolution 640x480 => 240x320\n");
+
+	  w100_PwmSetup();
+	  w100_vsync();
+	  w100_suspend(W100_SUSPEND_EXTMEM);
+	  w100_init_sharp_lcd(LCD_SHARP_QVGA);
+	  w100_init_qvga_rotation( (u16)0 );
+	  w100_InitExtMem(LCD_SHARP_QVGA);
+  	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  lcdtg_lcd_change(LCD_SHARP_QVGA);
+
+	  w100fb_lcdMode = LCD_MODE_240;
+
+      }else if(current_par.xres == 480 && current_par.yres == 640){
+
+	  printk("change resolution 640x480 => 480x640\n");
+
+	  w100_PwmSetup();
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
+	  w100_InitExtMem(LCD_SHARP_VGA);
+	  w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
+	  w100_vsync();
+	  w100_init_sharp_lcd(LCD_SHARP_VGA);
+	  lcdtg_lcd_change(LCD_SHARP_VGA);
+
+	  w100fb_lcdMode = LCD_MODE_480;
+
       }
       break;
   case LCD_MODE_240:
@@ -891,6 +1055,22 @@
 
 	  w100fb_lcdMode = LCD_MODE_480;
 
+      }else if(current_par.xres == 640 && current_par.yres == 480){
+
+	  printk("change resolution 240x320 => 640x480\n");
+
+	  w100_PwmSetup();
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
+	  w100_InitExtMem(LCD_SHARP_VGA);
+	  w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
+	  w100_vsync();
+	  w100_init_sharp_lcd(LCD_SHARP_VGA);
+	  w100_init_vga_rotation( (u16)270 );
+	  lcdtg_lcd_change(LCD_SHARP_VGA);
+
+	  w100fb_lcdMode = LCD_MODE_640;
+
       }else if(current_par.xres == 320 && current_par.yres == 240){
 
 	  printk("change resolution 240x320 => 320x240\n");
@@ -917,6 +1097,22 @@
 
 	  w100fb_lcdMode = LCD_MODE_480;
 
+      }else if(current_par.xres == 640 && current_par.yres == 480){
+
+	  printk("change resolution 240x320 => 640x480\n");
+
+	  w100_PwmSetup();
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
+	  w100_InitExtMem(LCD_SHARP_VGA);
+	  w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
+	  w100_vsync();
+	  w100_init_sharp_lcd(LCD_SHARP_VGA);
+	  w100_init_vga_rotation( (u16)270 );
+	  lcdtg_lcd_change(LCD_SHARP_VGA);
+
+	  w100fb_lcdMode = LCD_MODE_640;
+
       }else if(current_par.xres == 240 && current_par.yres == 320){
 
 	  printk("change resolution 320x240 => 240x320\n");
@@ -1004,6 +1200,7 @@
 
   switch(w100fb_lcdMode){
   case LCD_MODE_480:
+  case LCD_MODE_640:
       if(isInitTG != 0)
 	  lcdtg_hw_init(LCD_SHARP_VGA);
       break;
@@ -2840,6 +3037,46 @@
     writel((u32)(disp_db_buf_wr_cntl.val), remapped_regs+mmDISP_DB_BUF_CNTL);
 } // w100_init_sharp_lcd
 
+static void w100_init_vga_rotation(u16 deg)
+{
+    // for resolution change and rotation
+    // GRAPHIC_CTRL
+    // GRAPHIC_OFFSET
+    // GRAPHIC_PITCH
+
+    switch(deg){
+    case 0:
+	gPowerState.pclk_cntl.f.pclk_src_sel  = 0x1;
+	gPowerState.pclk_cntl.f.pclk_post_div = 0x2;
+	writel((u32)(gPowerState.pclk_cntl.val), remapped_regs+mmPCLK_CNTL);
+
+	writel(0x00DE1D66, remapped_regs+mmGRAPHIC_CTRL);
+	writel(0x00800000, remapped_regs+mmGRAPHIC_OFFSET);
+	writel(0x000003c0, remapped_regs+mmGRAPHIC_PITCH);
+ 
+	// Re-enable display updates
+	writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
+
+	break;
+    case 270:
+	gPowerState.pclk_cntl.f.pclk_src_sel  = 0x1;
+	gPowerState.pclk_cntl.f.pclk_post_div = 0x6;
+	writel((u32)(gPowerState.pclk_cntl.val), remapped_regs+mmPCLK_CNTL);
+
+	writel(0x00DE1D0e, remapped_regs+mmGRAPHIC_CTRL);
+	writel(0x00895b00, remapped_regs+mmGRAPHIC_OFFSET);
+	writel(0x00000500, remapped_regs+mmGRAPHIC_PITCH);
+
+	// Re-enable display updates
+	writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
+
+	break;
+    default:
+	// not-support
+	break;
+    }
+}
+
 static void w100_init_qvga_rotation(u16 deg)
 {
     // for resolution change and rotation
@@ -2852,12 +3089,20 @@
 	writel(0x00d41c06, remapped_regs+mmGRAPHIC_CTRL);
 	writel(0x00800000, remapped_regs+mmGRAPHIC_OFFSET);
 	writel(0x000001e0, remapped_regs+mmGRAPHIC_PITCH);
+
+	// Re-enable display updates
+	writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
+
 	break;
     case 270:
-	writel(0x00d41c16, remapped_regs+mmGRAPHIC_CTRL);
+	writel(0x00d41c0E, remapped_regs+mmGRAPHIC_CTRL);
 	//writel(0x0080027e, remapped_regs+mmGRAPHIC_OFFSET);
-	writel(0x0080027c, remapped_regs+mmGRAPHIC_OFFSET);
+	writel(0x00825580, remapped_regs+mmGRAPHIC_OFFSET);
 	writel(0x00000280, remapped_regs+mmGRAPHIC_PITCH);
+
+	// Re-enable display updates
+	writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
+
 	break;
     default:
 	// not-support
@@ -2932,8 +3181,11 @@
     temp32 |= 0x00800000;
     writel(temp32, remapped_regs+mmDISP_DEBUG2);
 
-	if (w100fb_lcdMode == LCD_MODE_480) {
+	if (w100fb_lcdMode == LCD_MODE_480 || w100fb_lcdMode == LCD_MODE_640) {
 		w100_init_sharp_lcd(LCD_SHARP_VGA);
+		if (w100fb_lcdMode == LCD_MODE_640) {
+			w100_init_vga_rotation( (u16)270 );
+		}
 	}
 	else {
 		w100_init_sharp_lcd(LCD_SHARP_QVGA);
@@ -3273,7 +3521,7 @@
 
 static void lcdtg_resume()
 {
-  if (w100fb_lcdMode == LCD_MODE_480) {
+  if (w100fb_lcdMode == LCD_MODE_480 || w100fb_lcdMode == LCD_MODE_640) {
 	  lcdtg_hw_init(LCD_SHARP_VGA);
   }
   else {
