lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 7 May 2008 19:06:48 +0800
From:	<JosephChan@....com.tw>
To:	<JosephChan@....com.tw>, <akpm@...ux-foundation.org>,
	<geert@...ux-m68k.org>
Cc:	<linux-fbdev-devel@...ts.sourceforge.net>,
	<linux-kernel@...r.kernel.org>
Subject: [Linux-fbdev-devel] [PATCH 1/9] viafb: VIA Frame Buffer Device Driver - Resend


Signed-off-by: Joseph Chan <josephchan@....com.tw>

diff -Nur a/Documentation/fb/viafb.txt b/Documentation/fb/viafb.txt
--- a/Documentation/fb/viafb.txt	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/fb/viafb.txt	2008-05-06 06:46:26.000000000 -0400
@@ -0,0 +1,197 @@
+
+        VIA Integration Graphic Chip Console Framebuffer Driver
+
+[Platform]
+-----------------------
+    The console framebuffer driver is for Graphics chips of
+    VIA UniChrome (Pro) Family:
+ 	CLE266, PM800 / CN400,P4M800CE / P4M800Pro / CN700 / VN800, 
+	CX700 / VX700, P4M890 
+    VIA Chrome9 Family:
+	K8M890, CN896 / P4M900, VX800)
+
+[Driver features]
+------------------------
+    Device:CRT, LCD, DVI
+
+    Support Mode:
+        CRT:   
+	    640 x480(60, 75, 85, 100, 120 Hz), 720 x480(60 Hz),
+	    720 x576(60 Hz), 800 x600(60, 75, 85, 100, 120 Hz),
+	    848 x480(60 Hz), 856 x480(60 Hz), 1024 x512(60 Hz),
+	    1024 x768(60, 75, 85, 100 Hz), 1152 x864(75 Hz),
+	    1280 x768(60 Hz), 1280 x960(60 Hz), 1280 x1024(60, 75, 85 Hz),
+	    1440 x1050(60 Hz), 1600 x1200(60, 75 Hz), 1280 x720(60 Hz),
+	    1920 x1080(60 Hz), 1400 x1050(60 Hz), 800 x480(60 Hz)
+
+    color depth:8 bpp, 16 bpp, 32 bpp
+
+    Support 2 D hardware accelerator for kernel 2.6.xx
+
+[Using the viafb module]
+-- -- --------------------
+    Start viafb with default settings,
+        #modprobe viafb
+
+    Start viafb with with user options,
+        #modprobe viafb mode=800x600 via_fb_bpp=16 refresh=60 
+                  active_dev=CRT+DVI dvi_port = DVP1 mode1 = 1024 x768 
+                  via_fb_bpp1 = 16 refresh1 = 60 SAMM_ON = 1
+
+    mode:
+        640 x480(default)
+        720 x480 
+        800 x600 
+        1024 x768
+        ......
+
+    via_fb_bpp:
+        8, 16, 32(default:32)
+
+    refresh:
+        60, 75, 85, 100, 120(default:60)
+
+    lcd_dsp_method:
+        0 : expandsion(default)
+        1 : centering
+
+    lcd_mode:
+        0 : OPEN LDI(default)
+        1 : SPWG
+
+    lcd_panel_id:
+        0 : Resolution: 640 x480, Channel: single, Dithering: Enable 
+        1 : Resolution: 800 x600, Channel: single, Dithering: Enable 
+        2 : Resolution: 1024 x768, Channel: single, Dithering:Enable (default)
+        3 : Resolution: 1280 x768, Channel: single, Dithering: Enable 
+        4 : Resolution: 1280 x1024, Channel: dual, Dithering: Enable 
+        5 : Resolution: 1400 x1050, Channel: dual, Dithering: Enable 
+        6 : Resolution: 1600 x1200, Channel: dual, Dithering: Enable
+
+        8 : Resolution: 800 x480, Channel: single, Dithering: Enable 
+        9 : Resolution: 1024 x768, Channel: dual, Dithering: Enable 
+        10: Resolution: 1024 x768, Channel: single, Dithering: Disable 
+        11: Resolution: 1024 x768, Channel: dual, Dithering: Disable 
+        12: Resolution: 1280 x768, Channel: single, Dithering: Disable 
+        13: Resolution: 1280 x1024, Channel: dual, Dithering: Disable 
+        14: Resolution: 1400 x1050, Channel: dual, Dithering: Disable 
+        15: Resolution: 1600 x1200, Channel: dual, Dithering: Disable  
+        16: Resolution: 1366 x768, Channel: single, Dithering: Disable 
+        17: Resolution: 1024 x600, Channel: single, Dithering: Enable 
+        18: Resolution: 1280 x768, Channel: dual, Dithering: Enable 
+        19: Resolution: 1280 x800, Channel: single, Dithering: Enable
+    
+    via_fb_accel:
+        0 : No 2 D Hardware Acceleration(default)
+        1 : 2 D Hardware Acceleration
+
+    SAMM_ON:
+        0 : SAMM_ON disable(default)
+        1 : SAMM_ON enable
+
+    mode1:(secondary display device)
+        640 x480(default)
+        720 x480 
+        800 x600 
+        1024 x768 
+        ... ... 
+ 
+    via_fb_bpp1:(secondary display device) 
+        8, 16, 32(default:32)
+
+    refresh1:(secondary display device) 
+        60, 75, 85, 100, 120(default:60)
+
+    active_dev:
+        This option is used to specify active devices.(CRT, DVI, LCD, CRT + LCD, CRT + DVI,...)
+        DVI stand for DVI or HDMI, Ex.If you want to enable HDMI, set active_dev = DVI
+        In SAMM case, the previous of active_dev is primary device, and the following is secondary device.
+
+        For example:
+        To enable one device, such as DVI only, we should use:
+        modprobe viafb active_dev = DVI...To enable two devices, such as CRT + DVI:
+
+        For DuoView case, we can use:
+        modprobe viafb active_dev = CRT + DVI...OR modprobe viafb active_dev = DVI + CRT...
+
+        For SAMM case:
+        If CRT is primary and DVI is secondary, we should use:
+            modprobe viafb active_dev = CRT + DVI SAMM_ON = 1...
+        If DVI is primary and CRT is secondary, we should use:
+            modprobe viafb active_dev = DVI + CRT SAMM_ON = 1...
+
+    display_hardware_layout:
+	      This option is uesed to specify display hardware layout for CX700 chip.
+        1 : LCD only 
+        2 : DVI only 
+        3 : LCD + DVI(default)
+        4 : LCD1 + LCD2(internal + internal)
+        16: LCD1 + ExternalLCD2(internal + external)
+
+    second_size:
+        This option is used to set second device memory size(MB) in SAMM case.
+        The minimal size is 16. 
+
+    EPIA_DVI:
+        This option is used to enable DVI on EPIA - M 
+        0 : No DVI on EPIA - M(default)
+        1 : DVI on EPIA - M
+
+    BusWidth:
+        When using 24 - Bit Bus Width Digital Interface, this option should be set.
+        12: 12-Bit LVDS or 12-Bit TMDS(default)
+        24: 24-Bit LVDS or 24-Bit TMDS
+
+    LCDDualEdge:
+        When using Dual Edge Panel, this option should be set.
+        0 : No Dual Edge Panel(default)
+        1 : Dual Edge Panel
+
+    video_dev:
+        This option is used to specify video output devices(CRT, DVI, LCD) for duoview case.
+        For example:
+        To output video on DVI, we should use:
+            modprobe viafb video_dev = DVI...
+
+    lcd_port:
+	      This option is used to specify lcd output port,
+        available values are "DVP0" "DVP1" "DFP_HIGHLOW" "DFP_HIGH"
+	      "DFP_LOW", for external LCD + external DVI on CX700(External LCD is on DVP0), 
+        we should use:
+	          modprobe viafb lcd_port = DVP0...
+
+Note:
+    1. CRT may not display properly for DuoView CRT & DVI display at
+       the "640x480" PAL mode with DVI overscan enabled.
+    2. When SAMM is enable, mode and mode1, via_fb_bpp and via_fb_bpp1,
+       refresh and refresh1 can be different.
+    3. When console is depend on viafbinfo1, dynamically change resolution and bpp,
+       need call VIAFB specified ioctl interface VIAFB_SET_DEVICE.
+       Call common ioctl function FBIOPUT_VSCREENINFO will cause sreen crush.
+
+[Configure viafb with "fbset" tool]
+-----------------------------------
+    "fbset" is an inbox utility of Linux.
+    1. Inquire current viafb information, type,
+           # fbset -i
+
+    2. Set various resolutions and refresh rates,
+           # fbset <resolution-vertical_sync>
+
+       example,
+           # fbset "1024x768-75"
+       or
+           # fbset -g 1024 768 1024 768 32
+      Check the file "/etc/fb.modes" to find display modes available.
+
+    3. Set the color depth,
+           # fbset -depth <value>
+
+       example,
+           # fbset -depth 16
+
+[Bootup with viafb]:
+--------------------
+    Add the following line to your lilo.conf:
+        append =  "video=viafb:mode:1024x768,via_fb_bpp:32,refresh:85"
+
diff -Nur a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	2008-05-06 07:05:59.000000000 -0400
+++ b/drivers/video/Kconfig	2008-05-06 07:06:37.000000000 -0400
@@ -1501,6 +1501,24 @@
 	  (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
 	  as XGI V3XT, V5, V8 and Z7.
 
+config FB_VIA
+	tristate "VIA UniChrome (Pro) and Chrome9 display support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_SOFT_CURSOR
+        help
+          This is the frame buffer device driver for Graphics chips of VIA 
+          UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
+          CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
+          /P4M900,VX800)
+
+          Say Y if you have a VIA UniChrome graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called viafb.
+
 config FB_NEOMAGIC
 	tristate "NeoMagic display support"
 	depends on FB && PCI
diff -Nur a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	2008-05-06 07:05:49.000000000 -0400
+++ b/drivers/video/Makefile	2008-05-06 07:06:44.000000000 -0400
@@ -43,6 +43,7 @@
 obj-$(CONFIG_FB_ATY128)		  += aty/ macmodes.o
 obj-$(CONFIG_FB_RADEON)		  += aty/
 obj-$(CONFIG_FB_SIS)		  += sis/
+obj-$(CONFIG_FB_VIA)		  += via/
 obj-$(CONFIG_FB_KYRO)             += kyro/
 obj-$(CONFIG_FB_SAVAGE)		  += savage/
 obj-$(CONFIG_FB_GEODE)		  += geode/
diff -Nur a/drivers/video/via/accel.c b/drivers/video/via/accel.c
--- a/drivers/video/via/accel.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/video/via/accel.c	2008-04-29 02:51:13.000000000 -0400
@@ -0,0 +1,245 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under  the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ option)
+ * any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include "global.h"
+
+void init_accel(void)
+{
+	parinfo.cursor_start = parinfo.fbmem_free - CURSOR_SIZE;
+	parinfo.fbmem_free -= CURSOR_SIZE;
+	parinfo.fbmem_used += CURSOR_SIZE;
+
+	/* Reverse 8*1024 memory space for cursor image of the XServer */
+	parinfo.VQ_start = parinfo.fbmem_free - CURSOR_SIZE - VQ_SIZE;
+	parinfo.VQ_end = parinfo.VQ_start + VQ_SIZE - 1;
+	parinfo.fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
+	parinfo.fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
+
+void init_2d_engine(void)
+{
+	u32 dwVQStartAddr, dwVQEndAddr;
+	u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
+
+	/* init 2D engine regs to reset 2D engine */
+	MMIO_OUT32(VIA_REG_GEMODE, 0x0);
+	MMIO_OUT32(VIA_REG_SRCPOS, 0x0);
+	MMIO_OUT32(VIA_REG_DSTPOS, 0x0);
+	MMIO_OUT32(VIA_REG_DIMENSION, 0x0);
+	MMIO_OUT32(VIA_REG_PATADDR, 0x0);
+	MMIO_OUT32(VIA_REG_FGCOLOR, 0x0);
+	MMIO_OUT32(VIA_REG_BGCOLOR, 0x0);
+	MMIO_OUT32(VIA_REG_CLIPTL, 0x0);
+	MMIO_OUT32(VIA_REG_CLIPBR, 0x0);
+	MMIO_OUT32(VIA_REG_OFFSET, 0x0);
+	MMIO_OUT32(VIA_REG_KEYCONTROL, 0x0);
+	MMIO_OUT32(VIA_REG_SRCBASE, 0x0);
+	MMIO_OUT32(VIA_REG_DSTBASE, 0x0);
+	MMIO_OUT32(VIA_REG_PITCH, 0x0);
+	MMIO_OUT32(VIA_REG_MONOPAT1, 0x0);
+
+	/* Init AGP and VQ regs */
+	switch (chip_info.gfx_chip_name) {
+	case UNICHROME_K8M890:
+	case UNICHROME_P4M900:
+		MMIO_OUT32(0x41c, 0x00100000);
+		MMIO_OUT32(0x420, 0x680A0000);
+		MMIO_OUT32(0x420, 0x02000000);
+		break;
+
+	default:
+		MMIO_OUT32(VIA_REG_TRANSET, 0x00100000);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x00000000);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x00333004);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x60000000);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x61000000);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x62000000);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x63000000);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x64000000);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x7D000000);
+
+		MMIO_OUT32(VIA_REG_TRANSET, 0xFE020000);
+		MMIO_OUT32(VIA_REG_TRANSPACE, 0x00000000);
+		break;
+	}
+	if (parinfo.VQ_start != 0) {
+		/* Enable VQ */
+		dwVQStartAddr = parinfo.VQ_start;
+		dwVQEndAddr = parinfo.VQ_end;
+		switch (chip_info.gfx_chip_name) {
+		case UNICHROME_K8M890:
+		case UNICHROME_P4M900:
+			dwVQStartL = 0x70000000 | (dwVQStartAddr & 0xFFFFFF);
+			dwVQEndL = 0x71000000 | (dwVQEndAddr & 0xFFFFFF);
+			dwVQStartEndH =
+			    0x72000000 | ((dwVQStartAddr & 0xFF000000) >>
+					  24) | ((dwVQEndAddr & 0xFF000000)
+						 >> 16);
+			dwVQLen = 0x73000000 | (VQ_SIZE >> 3);
+			break;
+		default:
+			dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
+			dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
+			dwVQStartEndH =
+			    0x52000000 | ((dwVQStartAddr & 0xFF000000) >>
+					  24) | ((dwVQEndAddr & 0xFF000000)
+						 >> 16);
+			dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
+			break;
+		}
+
+		switch (chip_info.gfx_chip_name) {
+		case UNICHROME_K8M890:
+		case UNICHROME_P4M900:
+			MMIO_OUT32(0x41c, 0x00100000);
+			MMIO_OUT32(0x420, dwVQStartEndH);
+			MMIO_OUT32(0x420, dwVQStartL);
+			MMIO_OUT32(0x420, dwVQEndL);
+			MMIO_OUT32(0x420, dwVQLen);
+			MMIO_OUT32(0x420, 0x74301001);
+			MMIO_OUT32(0x420, 0x00000000);
+			break;
+		default:
+			MMIO_OUT32(VIA_REG_TRANSET, 0x00FE0000);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x080003FE);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x0A00027C);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x0B000260);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x0C000274);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x0D000264);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x0E000000);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x0F000020);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x1000027E);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x110002FE);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x200F0060);
+
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x00000006);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x40008C0F);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x44000000);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x45080C04);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x46800408);
+
+			MMIO_OUT32(VIA_REG_TRANSPACE, dwVQStartEndH);
+			MMIO_OUT32(VIA_REG_TRANSPACE, dwVQStartL);
+			MMIO_OUT32(VIA_REG_TRANSPACE, dwVQEndL);
+			MMIO_OUT32(VIA_REG_TRANSPACE, dwVQLen);
+			break;
+		}
+	} else {
+		/* Diable VQ */
+		switch (chip_info.gfx_chip_name) {
+		case UNICHROME_K8M890:
+		case UNICHROME_P4M900:
+			MMIO_OUT32(0x41c, 0x00100000);
+			MMIO_OUT32(0x420, 0x74301000);
+			break;
+		default:
+			MMIO_OUT32(VIA_REG_TRANSET, 0x00FE0000);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x00000004);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x40008C0F);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x44000000);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x45080C04);
+			MMIO_OUT32(VIA_REG_TRANSPACE, 0x46800408);
+			break;
+		}
+	}
+
+	set_2d_color_depth(parinfo.bpp);
+
+	MMIO_OUT32(VIA_REG_SRCBASE, 0x0);
+	MMIO_OUT32(VIA_REG_DSTBASE, 0x0);
+
+	MMIO_OUT32(VIA_REG_PITCH,
+		   VIA_PITCH_ENABLE |
+		   (((parinfo.hres *
+		      parinfo.bpp >> 3) >> 3) | (((parinfo.hres *
+						   parinfo.
+						   bpp >> 3) >> 3) << 16)));
+}
+
+void set_2d_color_depth(int bpp)
+{
+	u32 dwGEMode;
+
+	dwGEMode = MMIO_IN32(0x04) & 0xFFFFFCFF;
+
+	switch (bpp) {
+	case 16:
+		dwGEMode |= VIA_GEM_16bpp;
+		break;
+	case 32:
+		dwGEMode |= VIA_GEM_32bpp;
+		break;
+	default:
+		dwGEMode |= VIA_GEM_8bpp;
+		break;
+	}
+
+	/* Set BPP and Pitch */
+	MMIO_OUT32(VIA_REG_GEMODE, dwGEMode);
+}
+
+void hw_cursor_init(void)
+{
+	/* Set Cursor Image Base Address */
+	MMIO_OUT32(VIA_REG_CURSOR_MODE, parinfo.cursor_start);
+	MMIO_OUT32(VIA_REG_CURSOR_POS, 0x0);
+	MMIO_OUT32(VIA_REG_CURSOR_ORG, 0x0);
+	MMIO_OUT32(VIA_REG_CURSOR_BG, 0x0);
+	MMIO_OUT32(VIA_REG_CURSOR_FG, 0x0);
+}
+
+void show_hw_cursor(struct fb_info *info, int Status) {
+	u32 temp;
+	u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
+
+	temp = MMIO_IN32(VIA_REG_CURSOR_MODE);
+	switch (Status) {
+	case HW_Cursor_ON:
+		temp |= 0x1;
+		break;
+	case HW_Cursor_OFF:
+		temp &= 0xFFFFFFFE;
+		break;
+	}
+	switch (iga_path) {
+	case IGA2:
+		temp |= 0x80000000;
+		break;
+	case IGA1:
+	default:
+		temp &= 0x7FFFFFFF;
+	}
+	MMIO_OUT32(VIA_REG_CURSOR_MODE, temp); }
+
+int wait_engine_idle(void)
+{
+	int loop = 0;
+
+	while (!(MMIO_IN32(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)
+	       && (loop++ < MAXLOOP)) ;
+
+	while ((MMIO_IN32(VIA_REG_STATUS) &
+		(VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
+	       (loop++ < MAXLOOP)) ;
+
+	return loop >= MAXLOOP;
+}
diff -Nur a/drivers/video/via/accel.h b/drivers/video/via/accel.h
--- a/drivers/video/via/accel.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/video/via/accel.h	2008-04-29 02:51:14.000000000 -0400
@@ -0,0 +1,190 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under  the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ option)
+ * any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ACCEL_H__
+#define __ACCEL_H__
+
+#ifndef FB_ACCEL_VIA_UNICHROME
+#define FB_ACCEL_VIA_UNICHROME  50
+#endif
+
+/* MMIO Base Address Definition */
+#define MMIO_VGABASE                0x8000
+#define MMIO_CR_READ                MMIO_VGABASE + 0x3D4
+#define MMIO_CR_WRITE               MMIO_VGABASE + 0x3D5
+#define MMIO_SR_READ                MMIO_VGABASE + 0x3C4
+#define MMIO_SR_WRITE               MMIO_VGABASE + 0x3C5
+
+#ifndef VIA_MMIO
+#define VIA_MMIO 1
+#endif
+
+#if VIA_MMIO
+#define MMIO_OUT8(reg, val)  writeb(val, parinfo.io_virt + reg) #define 
+MMIO_OUT16(reg, val) writew(val, parinfo.io_virt + reg) #define 
+MMIO_OUT32(reg, val) writel(val, parinfo.io_virt + reg)
+#define MMIO_IN8(reg)       readb(parinfo.io_virt + reg)
+#define MMIO_IN16(reg)      readw(parinfo.io_virt + reg)
+#define MMIO_IN32(reg)      readl(parinfo.io_virt + reg)
+
+#else
+#define MMIO_OUT8(reg, val)  outb(val, reg) #define MMIO_OUT16(reg,
+val) outw(val, reg) #define MMIO_OUT32(reg, val) outl(val, reg)
+#define MMIO_IN8(reg)       inb(reg)
+#define MMIO_IN16(reg)      inw(reg)
+#define MMIO_IN32(reg)      inl(reg)
+#endif
+
+/* HW Cursor Status Define */
+#define HW_Cursor_ON    0
+#define HW_Cursor_OFF   1
+
+#define CURSOR_SIZE     (8 * 1024)
+#define VQ_SIZE         (256 * 1024)
+
+#define VIA_MMIO_BLTBASE        0x200000
+#define VIA_MMIO_BLTSIZE        0x200000
+
+/* Defines for 2D registers */
+#define VIA_REG_GECMD           0x000
+#define VIA_REG_GEMODE          0x004
+#define VIA_REG_SRCPOS          0x008
+#define VIA_REG_DSTPOS          0x00C
+/* width and height */
+#define VIA_REG_DIMENSION       0x010
+#define VIA_REG_PATADDR         0x014
+#define VIA_REG_FGCOLOR         0x018
+#define VIA_REG_BGCOLOR         0x01C
+/* top and left of clipping */
+#define VIA_REG_CLIPTL          0x020
+/* bottom and right of clipping */
+#define VIA_REG_CLIPBR          0x024
+#define VIA_REG_OFFSET          0x028
+/* color key control */
+#define VIA_REG_KEYCONTROL      0x02C
+#define VIA_REG_SRCBASE         0x030
+#define VIA_REG_DSTBASE         0x034
+/* pitch of src and dst */
+#define VIA_REG_PITCH           0x038
+#define VIA_REG_MONOPAT0        0x03C
+#define VIA_REG_MONOPAT1        0x040
+/* from 0x100 to 0x1ff */
+#define VIA_REG_COLORPAT        0x100
+
+/* VIA_REG_PITCH(0x38): Pitch Setting */
+#define VIA_PITCH_ENABLE        0x80000000
+
+/* defines for VIA HW cursor registers */
+#define VIA_REG_CURSOR_MODE     0x2D0
+#define VIA_REG_CURSOR_POS      0x2D4
+#define VIA_REG_CURSOR_ORG      0x2D8
+#define VIA_REG_CURSOR_BG       0x2DC
+#define VIA_REG_CURSOR_FG       0x2E0
+
+/* VIA_REG_GEMODE(0x04): GE mode */
+#define VIA_GEM_8bpp            0x00000000
+#define VIA_GEM_16bpp           0x00000100
+#define VIA_GEM_32bpp           0x00000300
+
+/* VIA_REG_GECMD(0x00): 2D Engine Command  */
+#define VIA_GEC_NOOP            0x00000000
+#define VIA_GEC_BLT             0x00000001
+#define VIA_GEC_LINE            0x00000005
+
+/* Rotate Command */
+#define VIA_GEC_ROT             0x00000008
+
+#define VIA_GEC_SRC_XY          0x00000000
+#define VIA_GEC_SRC_LINEAR      0x00000010
+#define VIA_GEC_DST_XY          0x00000000
+#define VIA_GEC_DST_LINRAT      0x00000020
+
+#define VIA_GEC_SRC_FB          0x00000000
+#define VIA_GEC_SRC_SYS         0x00000040
+#define VIA_GEC_DST_FB          0x00000000
+#define VIA_GEC_DST_SYS         0x00000080
+
+/* source is mono */
+#define VIA_GEC_SRC_MONO        0x00000100
+/* pattern is mono */
+#define VIA_GEC_PAT_MONO        0x00000200
+/* mono src is opaque */
+#define VIA_GEC_MSRC_OPAQUE     0x00000000
+/* mono src is transparent */
+#define VIA_GEC_MSRC_TRANS      0x00000400
+/* pattern is in frame buffer */
+#define VIA_GEC_PAT_FB          0x00000000
+/* pattern is from reg setting */
+#define VIA_GEC_PAT_REG         0x00000800
+
+#define VIA_GEC_CLIP_DISABLE    0x00000000
+#define VIA_GEC_CLIP_ENABLE     0x00001000
+
+#define VIA_GEC_FIXCOLOR_PAT    0x00002000
+
+#define VIA_GEC_INCX            0x00000000
+#define VIA_GEC_DECY            0x00004000
+#define VIA_GEC_INCY            0x00000000
+#define VIA_GEC_DECX            0x00008000
+/* mono pattern is opaque */
+#define VIA_GEC_MPAT_OPAQUE     0x00000000
+/* mono pattern is transparent */
+#define VIA_GEC_MPAT_TRANS      0x00010000
+
+#define VIA_GEC_MONO_UNPACK     0x00000000
+#define VIA_GEC_MONO_PACK       0x00020000
+#define VIA_GEC_MONO_DWORD      0x00000000
+#define VIA_GEC_MONO_WORD       0x00040000
+#define VIA_GEC_MONO_BYTE       0x00080000
+
+#define VIA_GEC_LASTPIXEL_ON    0x00000000
+#define VIA_GEC_LASTPIXEL_OFF   0x00100000
+#define VIA_GEC_X_MAJOR         0x00000000
+#define VIA_GEC_Y_MAJOR         0x00200000
+#define VIA_GEC_QUICK_START     0x00800000
+
+/* defines for VIA 3D registers */
+#define VIA_REG_STATUS          0x400
+#define VIA_REG_TRANSET         0x43C
+#define VIA_REG_TRANSPACE       0x440
+
+/* VIA_REG_STATUS(0x400): Engine Status */
+
+/* Command Regulator is busy */
+#define VIA_CMD_RGTR_BUSY       0x00000080
+/* 2D Engine is busy */
+#define VIA_2D_ENG_BUSY         0x00000002
+/* 3D Engine is busy */
+#define VIA_3D_ENG_BUSY         0x00000001
+/* Virtual Queue is busy */
+#define VIA_VR_QUEUE_BUSY       0x00020000
+
+#define MAXLOOP                 0xFFFFFF
+
+void init_accel(void);
+void init_2d_engine(void);
+void set_2d_color_depth(int);
+void hw_cursor_init(void);
+void show_hw_cursor(struct fb_info *info, int Status); int 
+wait_engine_idle(void);
+
+#endif /* __ACCEL_H__ */
diff -Nur a/drivers/video/via/chip.h b/drivers/video/via/chip.h
--- a/drivers/video/via/chip.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/video/via/chip.h	2008-04-29 02:51:15.000000000 -0400
@@ -0,0 +1,189 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under  the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ option)
+ * any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __CHIP_H__
+#define __CHIP_H__
+
+#include "global.h"
+
+/***************************************/
+/* Definition Graphic Chip Information */ 
+/***************************************/
+
+#define     PCI_VIA_VENDOR_ID       0x1106
+
+/* Define VIA Graphic Chip Name */
+#define     UNICHROME_CLE266        1
+#define     UNICHROME_CLE266_DID    0x3122
+#define     CLE266_REVISION_AX      0x0A
+#define     CLE266_REVISION_CX      0x0C
+
+#define     UNICHROME_K400          2
+#define     UNICHROME_K400_DID      0x7205
+
+#define     UNICHROME_K800          3
+#define     UNICHROME_K800_DID      0x3108
+
+#define     UNICHROME_PM800          4
+#define     UNICHROME_PM800_DID      0x3118
+
+#define     UNICHROME_CN700         5
+#define     UNICHROME_CN700_DID     0x3344
+
+#define     UNICHROME_CX700         6
+#define     UNICHROME_CX700_DID     0x3157
+#define     CX700_REVISION_700         0x0
+#define     CX700_REVISION_700M      0x1
+#define     CX700_REVISION_700M2    0x2
+
+#define     UNICHROME_CN750         7
+#define     UNICHROME_CN750_DID     0x3225
+
+#define     UNICHROME_K8M890        8
+#define     UNICHROME_K8M890_DID    0x3230
+
+#define     UNICHROME_P4M890        9
+#define     UNICHROME_P4M890_DID    0x3343
+
+#define     UNICHROME_P4M900        10
+#define     UNICHROME_P4M900_DID    0x3371
+
+#define     UNICHROME_VX800         11
+#define     UNICHROME_VX800_DID     0x1122
+/**************************************************/
+/* Definition TMDS Trasmitter Information         */
+/**************************************************/
+
+/* Definition TMDS Trasmitter Index */
+#define     NON_TMDS_TRANSMITTER    0x00
+#define     VT1632_TMDS             0x01
+#define     INTEGRATED_TMDS         0x42
+
+/* Definition TMDS Trasmitter I2C Slave Address */
+#define     VT1632_TMDS_I2C_ADDR    0x10
+
+/**************************************************/
+/* Definition LVDS Trasmitter Information         */
+/**************************************************/
+
+/* Definition LVDS Trasmitter Index */
+#define     NON_LVDS_TRANSMITTER    0x00
+#define     VT1631_LVDS             0x01
+#define     VT1636_LVDS             0x0E
+#define     INTEGRATED_LVDS         0x41
+
+/* Definition Digital Transmitter Mode */
+#define     TX_DATA_12_BITS         0x01
+#define     TX_DATA_24_BITS         0x02
+#define     TX_DATA_DDR_MODE        0x04
+#define     TX_DATA_SDR_MODE        0x08
+
+/* Definition LVDS Trasmitter I2C Slave Address */
+#define     VT1631_LVDS_I2C_ADDR    0x70
+#define     VT3271_LVDS_I2C_ADDR    0x80
+#define     VT1636_LVDS_I2C_ADDR    0x80
+
+struct tmds_chip_information {
+	int tmds_chip_name;
+	int tmds_chip_slave_addr;
+	int dvi_panel_id;
+	int data_mode;
+	int output_interface;
+	int i2c_port;
+	int device_type;
+};
+
+struct lvds_chip_information {
+	int lvds_chip_name;
+	int lvds_chip_slave_addr;
+	int data_mode;
+	int output_interface;
+	int i2c_port;
+};
+
+struct chip_information {
+	int gfx_chip_name;
+	int gfx_chip_revision;
+	int chip_on_slot;
+	struct tmds_chip_information tmds_chip_info;
+	struct lvds_chip_information lvds_chip_info;
+	struct lvds_chip_information lvds_chip_info2; };
+
+struct crt_setting_information {
+	int iga_path;
+	int h_active;
+	int v_active;
+	int bpp;
+	int refresh_rate;
+};
+
+struct tmds_setting_information {
+	int iga_path;
+	int h_active;
+	int v_active;
+	int bpp;
+	int refresh_rate;
+	int get_dvi_size_method;
+	int max_pixel_clock;
+	int dvi_panel_size;
+	int dvi_panel_hres;
+	int dvi_panel_vres;
+	int native_size;
+};
+
+struct lvds_setting_information {
+	int iga_path;
+	int h_active;
+	int v_active;
+	int bpp;
+	int refresh_rate;
+	int get_lcd_size_method;
+	int lcd_panel_id;
+	int lcd_panel_size;
+	int lcd_panel_hres;
+	int lcd_panel_vres;
+	int display_method;
+	int device_lcd_dualedge;
+	int LCDDithering;
+	int lcd_mode;
+	u32 vclk;		/*panel mode clock value */
+};
+
+struct GFX_DPA_SETTING {
+	int ClkRangeIndex;
+	u8 DVP0;		/* CR96[3:0] */
+	u8 DVP0DataDri_S1;	/* SR2A[5]   */
+	u8 DVP0DataDri_S;	/* SR1B[1]   */
+	u8 DVP0ClockDri_S1;	/* SR2A[4]   */
+	u8 DVP0ClockDri_S;	/* SR1E[2]   */
+	u8 DVP1;		/* CR9B[3:0] */
+	u8 DVP1Driving;		/* SR65[3:0], Data and Clock driving */
+	u8 DFPHigh;		/* CR97[3:0] */
+	u8 DFPLow;		/* CR99[3:0] */
+
+};
+
+struct VT1636_DPA_SETTING {
+	int PanelSizeID;
+	u8 CLK_SEL_ST1;
+	u8 CLK_SEL_ST2;
+};
+#endif /* __CHIP_H__ */
diff -Nur a/drivers/video/via/debug.h b/drivers/video/via/debug.h
--- a/drivers/video/via/debug.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/video/via/debug.h	2008-05-04 06:42:33.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under  the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ option)
+ * any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#ifndef VIAFB_DEBUG
+#define VIAFB_DEBUG 0
+#endif
+
+#if VIAFB_DEBUG
+#define DEBUG_MSG(f, a...)   printk(f, ## a)
+#else
+#define DEBUG_MSG(f, a...)
+#endif
+
+#define VIAFB_WARN 0
+#if VIAFB_WARN
+#define WARN_MSG(f, a...)   printk(f, ## a)
+#else
+#define WARN_MSG(f, a...)
+#endif
+
+#endif /* __DEBUG_H__ */
diff -Nur a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
--- a/drivers/video/via/dvi.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/video/via/dvi.c	2008-05-04 07:28:49.000000000 -0400
@@ -0,0 +1,721 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under  the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ option)
+ * any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include "global.h"
+
+int check_tmds_chip(int device_id_subaddr, int device_id) {
+	if (tmds_register_read(device_id_subaddr) == device_id)
+		return (OK);
+	else
+		return (FAIL);
+}
+
+void init_dvi_size(void)
+{
+	DEBUG_MSG(KERN_INFO "init_dvi_size()\n");
+	DEBUG_MSG(KERN_INFO "tmds_setting_info.get_dvi_size_method %d\n",
+		  tmds_setting_info.get_dvi_size_method);
+
+	switch (tmds_setting_info.get_dvi_size_method) {
+	case GET_DVI_SIZE_BY_SYSTEM_BIOS:
+		break;
+	case GET_DVI_SZIE_BY_HW_STRAPPING:
+		break;
+	case GET_DVI_SIZE_BY_VGA_BIOS:
+	default:
+		dvi_get_panel_info();
+		break;
+	}
+	return;
+}
+
+int tmds_trasmitter_identify(void)
+{
+	unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
+
+	/* Turn on ouputting pad */
+	switch (chip_info.gfx_chip_name) {
+	case UNICHROME_K8M890:
+	    /*=* DFP Low Pad on *=*/
+		sr2a = read_reg(VIASR, SR2A);
+		write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+		break;
+
+	case UNICHROME_P4M900:
+	case UNICHROME_P4M890:
+		/* DFP Low Pad on */
+		sr2a = read_reg(VIASR, SR2A);
+		write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+		/* DVP0 Pad on */
+		sr1e = read_reg(VIASR, SR1E);
+		write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
+		break;
+
+	default:
+	    /* DVP0/DVP1 Pad on */
+		sr1e = read_reg(VIASR, SR1E);
+		write_reg_mask(SR1E, VIASR, 0xF0, BIT4 + BIT5 + BIT6 + BIT7);
+	    /* SR3E[1]Multi-function selection:
+	    0 = Emulate I2C and DDC bus by GPIO2/3/4. */
+		sr3e = read_reg(VIASR, SR3E);
+		write_reg_mask(SR3E, VIASR, 0x0, BIT5);
+		break;
+	}
+
+	/* Check for VT1632: */
+	chip_info.tmds_chip_info.tmds_chip_name = VT1632_TMDS;
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+	chip_info.tmds_chip_info.i2c_port = I2CPORTINDEX;
+	if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
+	/*Currently only support 12bits,dual edge,add 24bits mode later */
+		tmds_register_write(0x08, 0x3b);
+
+		DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
+		DEBUG_MSG(KERN_INFO "\n %2d",
+			  chip_info.tmds_chip_info.tmds_chip_name);
+		DEBUG_MSG(KERN_INFO "\n %2d",
+			  chip_info.tmds_chip_info.i2c_port);
+		return (OK);
+	} else {
+		chip_info.tmds_chip_info.i2c_port = GPIOPORTINDEX;
+		if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
+		    != FAIL) {
+			tmds_register_write(0x08, 0x3b);
+			DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
+			DEBUG_MSG(KERN_INFO "\n %2d",
+				  chip_info.tmds_chip_info.tmds_chip_name);
+			DEBUG_MSG(KERN_INFO "\n %2d",
+				  chip_info.tmds_chip_info.i2c_port);
+			return (OK);
+		}
+	}
+
+	chip_info.tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
+
+	if ((chip_info.gfx_chip_name == UNICHROME_CX700) &&
+	    ((display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
+	     (display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
+		DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
+		return (OK);
+	}
+
+	switch (chip_info.gfx_chip_name) {
+	case UNICHROME_K8M890:
+		write_reg(SR2A, VIASR, sr2a);
+		break;
+
+	case UNICHROME_P4M900:
+	case UNICHROME_P4M890:
+		write_reg(SR2A, VIASR, sr2a);
+		write_reg(SR1E, VIASR, sr1e);
+		break;
+
+	default:
+		write_reg(SR1E, VIASR, sr1e);
+		write_reg(SR3E, VIASR, sr3e);
+		break;
+	}
+
+	chip_info.tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+	return (FAIL);
+}
+
+void tmds_register_write(int index, u8 data) {
+	u8 tmp;
+
+	tmp = chip_info.chip_on_slot;
+	switch (chip_info.tmds_chip_info.i2c_port) {
+	case I2CPORTINDEX:
+		chip_info.chip_on_slot = PORT_ON_AMR;
+		break;
+
+	case GPIOPORTINDEX:
+	default:
+		chip_info.chip_on_slot = PORT_ON_AGP;
+		break;
+	}
+
+	i2cWriteByte(chip_info.tmds_chip_info.tmds_chip_slave_addr, index,
+		     data);
+
+	chip_info.chip_on_slot = tmp;
+
+}
+
+int tmds_register_read(int index)
+{
+	u8 data;
+	int status;
+	u8 tmp;
+
+	tmp = chip_info.chip_on_slot;
+	switch (chip_info.tmds_chip_info.i2c_port) {
+	case I2CPORTINDEX:
+		chip_info.chip_on_slot = PORT_ON_AMR;
+		break;
+
+	case GPIOPORTINDEX:
+	default:
+		chip_info.chip_on_slot = PORT_ON_AGP;
+		break;
+	}
+
+	status =
+	    i2cReadByte((u8) chip_info.tmds_chip_info.tmds_chip_slave_addr,
+			(u8) index, &data);
+	chip_info.chip_on_slot = tmp;
+	return (data);
+}
+
+int tmds_register_read_bytes(int index, u8 *buff, int buff_len) {
+	int status;
+	u8 tmp;
+
+	tmp = chip_info.chip_on_slot;
+	switch (chip_info.tmds_chip_info.i2c_port) {
+	case I2CPORTINDEX:
+		chip_info.chip_on_slot = PORT_ON_AMR;
+		break;
+
+	case GPIOPORTINDEX:
+	default:
+		chip_info.chip_on_slot = PORT_ON_AGP;
+		break;
+	}
+
+	status =
+	    i2cReadBytes((u8) chip_info.tmds_chip_info.
+			 tmds_chip_slave_addr, (u8) index, buff, buff_len);
+	chip_info.chip_on_slot = tmp;
+	return (status);
+}
+
+int check_reduce_blanking_mode(int mode_index, int refresh_rate) {
+	if (refresh_rate != 60)
+		return (FALSE);
+
+	switch (mode_index) {
+		/* Following modes have reduce blanking mode. */
+	case VIA_RES_1360X768:
+	case VIA_RES_1400X1050:
+	case VIA_RES_1440X900:
+	case VIA_RES_1600X900:
+	case VIA_RES_1680X1050:
+	case VIA_RES_1920X1080:
+	case VIA_RES_1920X1200:
+		break;
+
+	default:
+		DEBUG_MSG(KERN_INFO
+			  "This dvi mode %d have no reduce blanking mode!\n",
+			  mode_index);
+		return (FALSE);
+	}
+
+	return (TRUE);
+}
+
+/* DVI Set Mode */
+void dvi_set_mode(int video_index, int mode_bpp, int set_iga) {
+	struct VideoModeTable *videoMode = NULL;
+	struct crt_mode_table *pDviTiming;
+	unsigned long desirePixelClock, maxPixelClock;
+	int status = 0;
+	videoMode = get_modetbl_pointer(video_index);
+	pDviTiming = videoMode->crtc;
+	desirePixelClock = pDviTiming->clk / 1000000;
+	maxPixelClock = (unsigned long)tmds_setting_info.max_pixel_clock;
+
+	DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
+
+	if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
+		/*Check if reduce-blanking mode is exist */
+		status =
+		    check_reduce_blanking_mode(video_index,
+					       pDviTiming->refresh_rate);
+		if (status) {
+			video_index += 100;	/*Use reduce-blanking mode */
+			videoMode = get_modetbl_pointer(video_index);
+			pDviTiming = videoMode->crtc;
+			DEBUG_MSG(KERN_INFO
+				  "DVI use reduce blanking mode %d!!\n",
+				  video_index);
+		}
+	}
+	fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
+	set_output_path(DEVICE_DVI, set_iga,
+			chip_info.tmds_chip_info.output_interface);
+}
+
+/* Sense DVI Connector */
+int dvi_sense(void)
+{
+	u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0, RegCR93 =
+	    0, RegCR9B = 0, data;
+	int ret = FALSE;
+
+	DEBUG_MSG(KERN_INFO "dvi_sense!!\n");
+
+	if (chip_info.gfx_chip_name == UNICHROME_CLE266) {
+		/* DI1 Pad on */
+		RegSR1E = read_reg(VIASR, SR1E);
+		write_reg(SR1E, VIASR, RegSR1E | 0x30);
+
+		/* CR6B[0]VCK Input Selection: 1 = External clock. */
+		RegCR6B = read_reg(VIACR, CR6B);
+		write_reg(CR6B, VIACR, RegCR6B | 0x08);
+
+		/* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
+		   [0] Software Control Power Sequence */
+		RegCR91 = read_reg(VIACR, CR91);
+		write_reg(CR91, VIACR, 0x1D);
+
+		/* CR93[7] DI1 Data Source Selection: 1 = DSP2.
+		   CR93[5] DI1 Clock Source: 1 = internal.
+		   CR93[4] DI1 Clock Polarity.
+		   CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
+		RegCR93 = read_reg(VIACR, CR93);
+		write_reg(CR93, VIACR, 0x01);
+	} else {
+		/* DVP0/DVP1 Pad on */
+		RegSR1E = read_reg(VIASR, SR1E);
+		write_reg(SR1E, VIASR, RegSR1E | 0xF0);
+
+		/* SR3E[1]Multi-function selection:
+		   0 = Emulate I2C and DDC bus by GPIO2/3/4. */
+		RegSR3E = read_reg(VIASR, SR3E);
+		write_reg(SR3E, VIASR, RegSR3E & (~0x20));
+
+		/* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
+		   [0] Software Control Power Sequence */
+		RegCR91 = read_reg(VIACR, CR91);
+		write_reg(CR91, VIACR, 0x1D);
+
+		/*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
+		display.CR9B[2:0] DVP1 Clock Adjust */
+		RegCR9B = read_reg(VIACR, CR9B);
+		write_reg(CR9B, VIACR, 0x01);
+	}
+
+	data = (u8) tmds_register_read(0x09);
+	if (data & 0x04)
+		ret = TRUE;
+
+	if (ret == FALSE) {
+		if (dvi_query_EDID())
+			ret = TRUE;
+	}
+
+	/* Restore status */
+	if (chip_info.gfx_chip_name == UNICHROME_CLE266) {
+		write_reg(SR1E, VIASR, RegSR1E);
+		write_reg(CR6B, VIACR, RegCR6B);
+		write_reg(CR91, VIACR, RegCR91);
+		write_reg(CR93, VIACR, RegCR93);
+	} else {
+		write_reg(SR1E, VIASR, RegSR1E);
+		write_reg(SR3E, VIASR, RegSR3E);
+		write_reg(CR91, VIACR, RegCR91);
+		write_reg(CR9B, VIACR, RegCR9B);
+	}
+
+	return ret;
+}
+
+/* Query Flat Panel's EDID Table Version Through DVI Connector */ int
+dvi_query_EDID(void) {
+	u8 data0, data1;
+	int restore;
+
+	DEBUG_MSG(KERN_INFO "dvi_query_EDID!!\n");
+
+	restore = chip_info.tmds_chip_info.tmds_chip_slave_addr;
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+
+	data0 = (u8) tmds_register_read(0x00);
+	data1 = (u8) tmds_register_read(0x01);
+	if ((data0 == 0) && (data1 == 0xFF)) {
+		chip_info.tmds_chip_info.tmds_chip_slave_addr = restore;
+		return (EDID_VERSION_1);	/* Found EDID1 Table */
+	}
+
+	data0 = (u8) tmds_register_read(0x00);
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = restore;
+	if (data0 == 0x20)
+		return (EDID_VERSION_2);	/* Found EDID2 Table */
+	else
+		return (FALSE);
+}
+
+/*
+ *
+ * int dvi_get_panel_size_from_DDCv1(void)
+ *
+ *     - Get Panel Size Using EDID1 Table
+ *
+ * Return Type:    int
+ *
+ */
+int dvi_get_panel_size_from_DDCv1(void)
+{
+	int i, max_h = 0, max_v = 0, tmp, restore;
+	unsigned char rData;
+	unsigned char EDID_DATA[18];
+
+	DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
+
+	restore = chip_info.tmds_chip_info.tmds_chip_slave_addr;
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+
+	for (i = 0x23; i < 0x6D; i++) {
+		switch (i) {
+		case 0x23:
+			rData = tmds_register_read(0x23);
+			if (rData & 0x3C)
+				max_h = 640;
+			if (rData & 0xC0)
+				max_h = 720;
+			if (rData & 0x03)
+				max_h = 800;
+			break;
+		case 0x24:
+			rData = tmds_register_read(0x24);
+			if (rData & 0xC0)
+				max_h = 800;
+			if (rData & 0x1E)
+				max_h = 1024;
+			if (rData & 0x01)
+				max_h = 1280;
+			break;
+		case 0x26:
+		case 0x28:
+		case 0x2A:
+		case 0x2C:
+		case 0x2E:
+		case 0x30:
+		case 0x32:
+		case 0x34:
+			rData = tmds_register_read(i);
+			if (rData == 1)
+				break;
+			/* data = (data + 31) * 8 */
+			tmp = (rData + 31) << 3;
+			if (tmp > max_h)
+				max_h = tmp;
+			break;
+
+		case 0x36:
+		case 0x48:
+		case 0x5A:
+		case 0x6C:
+			tmds_register_read_bytes(i, EDID_DATA, 10);
+			if (!(EDID_DATA[0] || EDID_DATA[1])) {
+				/* The first two byte must be zero. */
+				if (EDID_DATA[3] == 0xFD) {
+					/* To get max pixel clock. */
+					tmds_setting_info.max_pixel_clock =
+					    EDID_DATA[9] * 10;
+				}
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	switch (max_h) {
+	case 640:
+		tmds_setting_info.dvi_panel_size = VIA_RES_640X480;
+		break;
+	case 800:
+		tmds_setting_info.dvi_panel_size = VIA_RES_800X600;
+		break;
+	case 1024:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1024X768;
+		break;
+	case 1280:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1280X1024;
+		break;
+	case 1400:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1400X1050;
+		break;
+	case 1440:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1440X1050;
+		break;
+	case 1600:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1600X1200;
+		break;
+	case 1920:
+		if (max_v == 1200)
+			tmds_setting_info.dvi_panel_size = VIA_RES_1920X1200;
+		else
+			tmds_setting_info.dvi_panel_size = VIA_RES_1920X1080;
+		break;
+	default:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1024X768;
+		DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
+					 set default panel size.\n", max_h);
+		break;
+	}
+
+	DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
+		  tmds_setting_info.max_pixel_clock);
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = restore;
+	return tmds_setting_info.dvi_panel_size; }
+
+/*
+ *
+ * int dvi_get_panel_size_from_DDCv2(void)
+ *
+ *     - Get Panel Size Using EDID2 Table
+ *
+ * Return Type:    int
+ *
+ */
+int dvi_get_panel_size_from_DDCv2(void)
+{
+	int HSize = 0, restore;
+	unsigned char R_Buffer[2];
+
+	DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
+
+	restore = chip_info.tmds_chip_info.tmds_chip_slave_addr;
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = 0xA2;
+
+	/* Horizontal: 0x76, 0x77 */
+	tmds_register_read_bytes(0x76, R_Buffer, 2);
+	HSize = R_Buffer[0];
+	HSize += R_Buffer[1] << 8;
+
+	switch (HSize) {
+	case 640:
+		tmds_setting_info.dvi_panel_size = VIA_RES_640X480;
+		break;
+	case 800:
+		tmds_setting_info.dvi_panel_size = VIA_RES_800X600;
+		break;
+	case 1024:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1024X768;
+		break;
+	case 1280:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1280X1024;
+		break;
+	case 1400:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1400X1050;
+		break;
+	case 1440:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1440X1050;
+		break;
+	case 1600:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1600X1200;
+		break;
+	default:
+		tmds_setting_info.dvi_panel_size = VIA_RES_1024X768;
+		DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
+					set default panel size.\n", HSize);
+		break;
+	}
+
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = restore;
+	return tmds_setting_info.dvi_panel_size; }
+
+/*
+ *
+ * unsigned char dvi_get_panel_info(void)
+ *
+ *     - Get Panel Size
+ *
+ * Return Type:    unsigned char
+ */
+unsigned char dvi_get_panel_info(void)
+{
+	DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
+
+	dvi_sense();
+	switch (dvi_query_EDID()) {
+	case 1:
+		dvi_get_panel_size_from_DDCv1();
+		break;
+	case 2:
+		dvi_get_panel_size_from_DDCv2();
+		break;
+	default:
+		break;
+	}
+
+	DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
+		  tmds_setting_info.dvi_panel_size);
+	return (unsigned char)(tmds_setting_info.dvi_panel_size);
+}
+
+/* If Disable DVI, turn off pad */
+void dvi_disable(void)
+{
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_DVP0)
+		write_reg(SR1E, VIASR, read_reg(VIASR, SR1E) & (~0xC0));
+
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_DVP1)
+		write_reg(SR1E, VIASR, read_reg(VIASR, SR1E) & (~0x30));
+
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
+		write_reg(SR2A, VIASR, read_reg(VIASR, SR2A) & (~0x0C));
+
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
+		write_reg(SR2A, VIASR, read_reg(VIASR, SR2A) & (~0x03));
+
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_TMDS)
+		/* Turn off TMDS power. */
+		write_reg(CRD2, VIACR, read_reg(VIACR, CRD2) | 0x08); }
+
+/* If Enable DVI, turn off pad */
+void dvi_enable(void)
+{
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_DVP0) {
+		write_reg(SR1E, VIASR, read_reg(VIASR, SR1E) | 0xC0);
+		if (chip_info.gfx_chip_name == UNICHROME_CLE266)
+			tmds_register_write(0x88, 0x3b);
+		else
+			/*clear CR91[5] to direct on display period
+			   in the secondary diplay path */
+			write_reg(CR91, VIACR, read_reg(VIACR, CR91) & 0xDF);
+	}
+
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_DVP1) {
+		write_reg(SR1E, VIASR, read_reg(VIASR, SR1E) | 0x30);
+
+		/*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
+		if (chip_info.gfx_chip_name == UNICHROME_CLE266) {
+			tmds_register_write(0x88, 0x3b);
+		} else {
+			/*clear CR91[5] to direct on display period
+			  in the secondary diplay path */
+			write_reg(CR91, VIACR, read_reg(VIACR, CR91) & 0xDF);
+		}
+
+		/*fix DVI cannot enable on EPIA-M board */
+		if (platform_epia_dvi == 1) {
+			write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
+			write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
+			if (via_bus_width == 24) {
+				if (device_lcd_dualedge == 1)
+					i2cWriteByte(chip_info.
+						     tmds_chip_info.
+						     tmds_chip_slave_addr,
+						     0x08, 0x3F);
+				else
+					i2cWriteByte(chip_info.
+						     tmds_chip_info.
+						     tmds_chip_slave_addr,
+						     0x08, 0x37);
+			}
+		}
+	}
+
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
+		write_reg(SR2A, VIASR, read_reg(VIASR, SR2A) | 0x0C);
+		write_reg(CR91, VIACR, read_reg(VIACR, CR91) & 0xDF);
+	}
+
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
+		write_reg(SR2A, VIASR, read_reg(VIASR, SR2A) | 0x03);
+		write_reg(CR91, VIACR, read_reg(VIACR, CR91) & 0xDF);
+	}
+	if (chip_info.tmds_chip_info.output_interface == INTERFACE_TMDS) {
+		/* Turn on Display period in the panel path. */
+		write_reg_mask(CR91, VIACR, 0, BIT7);
+
+		/* Turn on TMDS power. */
+		write_reg_mask(CRD2, VIACR, 0, BIT3);
+	}
+}
+
+int check_hdmi_connected_device(void)
+{
+	int bEdidExist = FALSE;
+	u8 byTemp = 0, byTemp1 = 0, byTemp2 = 0;
+	u8 byVendorDataBlock;
+	int restore, result = DEV_CONNECT_DVI;
+
+	restore = chip_info.tmds_chip_info.tmds_chip_slave_addr;
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+	byTemp = (u8) tmds_register_read(0x00);
+
+	if (byTemp == 0x00) {
+		byTemp = (u8) tmds_register_read(0x01);
+		if (byTemp == 0xFF)
+			bEdidExist = TRUE;
+	}
+
+	if (bEdidExist) {
+		byTemp = (u8) tmds_register_read(0x80);
+		byTemp1 = (u8) tmds_register_read(0x81);
+
+		if (byTemp == 0x02 && byTemp1 == 0x03) {
+			byTemp = (u8) tmds_register_read(0x82);
+
+			if (!(byTemp == 0 || byTemp == 4)) {
+				byVendorDataBlock = 0x82 + 2;
+
+				byTemp1 = (u8)
+				    tmds_register_read(byVendorDataBlock);
+				while ((byTemp1 & 0xE0) != 0x60
+				       && byVendorDataBlock < (byTemp + 0x82)) {
+					byTemp1 &= 0x1F;
+
+					byVendorDataBlock += (byTemp1 + 1);
+
+					byTemp1 = (u8)
+					    tmds_register_read
+					    (byVendorDataBlock);
+				}
+				if ((byTemp1 & 0xE0) == 0x60) {
+					byTemp = (u8)
+					    tmds_register_read
+					    (byVendorDataBlock + 1);
+					byTemp1 = (u8)
+					    tmds_register_read
+					    (byVendorDataBlock + 2);
+					byTemp2 = (u8)
+					    tmds_register_read
+					    (byVendorDataBlock + 3);
+
+					if (byTemp == 0x03
+					    && byTemp1 == 0x0C
+					    && byTemp2 == 0x00)
+						result = DEV_CONNECT_HDMI;
+				}
+			}
+		}
+	}
+
+	chip_info.tmds_chip_info.tmds_chip_slave_addr = restore;
+	return result;
+}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ