diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-10-19 22:17:52 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-10-19 22:17:52 -0400 |
commit | 4cb40f795af36b3deb743f6ccf6c3fd542c61c8d (patch) | |
tree | db3d7519932549bf528f5b8e4cb8350356cd544d /drivers/video | |
parent | 79ed2a9216dd3cc35c4f2c5dbaddadb195af83ac (diff) | |
parent | 0cfd81031a26717fe14380d18275f8e217571615 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
Documentation/kernel-parameters.txt
arch/sh/include/asm/elf.h
Diffstat (limited to 'drivers/video')
94 files changed, 17942 insertions, 1752 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 70d135e0cc47..0f13448c6f79 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -76,6 +76,14 @@ config FB_DDC | |||
76 | select I2C | 76 | select I2C |
77 | default n | 77 | default n |
78 | 78 | ||
79 | config FB_BOOT_VESA_SUPPORT | ||
80 | bool | ||
81 | depends on FB | ||
82 | default n | ||
83 | ---help--- | ||
84 | If true, at least one selected framebuffer driver can take advantage | ||
85 | of VESA video modes set at an early boot stage via the vga= parameter. | ||
86 | |||
79 | config FB_CFB_FILLRECT | 87 | config FB_CFB_FILLRECT |
80 | tristate | 88 | tristate |
81 | depends on FB | 89 | depends on FB |
@@ -172,11 +180,6 @@ config FB_DEFERRED_IO | |||
172 | bool | 180 | bool |
173 | depends on FB | 181 | depends on FB |
174 | 182 | ||
175 | config FB_METRONOME | ||
176 | tristate | ||
177 | depends on FB | ||
178 | depends on FB_DEFERRED_IO | ||
179 | |||
180 | config FB_HECUBA | 183 | config FB_HECUBA |
181 | tristate | 184 | tristate |
182 | depends on FB | 185 | depends on FB |
@@ -259,16 +262,24 @@ config FB_PM2 | |||
259 | select FB_CFB_COPYAREA | 262 | select FB_CFB_COPYAREA |
260 | select FB_CFB_IMAGEBLIT | 263 | select FB_CFB_IMAGEBLIT |
261 | help | 264 | help |
262 | This is the frame buffer device driver for the Permedia2 AGP frame | 265 | This is the frame buffer device driver for cards based on |
263 | buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a | 266 | the 3D Labs Permedia, Permedia 2 and Permedia 2V chips. |
264 | product page at | 267 | The driver was tested on the following cards: |
265 | <http://www.ask.com.hk/product/Permedia%202/permedia2.htm>. | 268 | Diamond FireGL 1000 PRO AGP |
269 | ELSA Gloria Synergy PCI | ||
270 | Appian Jeronimo PRO (both heads) PCI | ||
271 | 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI | ||
272 | Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC | ||
273 | ASK Graphic Blaster Exxtreme AGP | ||
274 | |||
275 | To compile this driver as a module, choose M here: the | ||
276 | module will be called pm2fb. | ||
266 | 277 | ||
267 | config FB_PM2_FIFO_DISCONNECT | 278 | config FB_PM2_FIFO_DISCONNECT |
268 | bool "enable FIFO disconnect feature" | 279 | bool "enable FIFO disconnect feature" |
269 | depends on FB_PM2 && PCI | 280 | depends on FB_PM2 && PCI |
270 | help | 281 | help |
271 | Support the Permedia2 FIFO disconnect feature (see CONFIG_FB_PM2). | 282 | Support the Permedia2 FIFO disconnect feature. |
272 | 283 | ||
273 | config FB_ARMCLCD | 284 | config FB_ARMCLCD |
274 | tristate "ARM PrimeCell PL110 support" | 285 | tristate "ARM PrimeCell PL110 support" |
@@ -678,7 +689,7 @@ config FB_VESA | |||
678 | select FB_CFB_FILLRECT | 689 | select FB_CFB_FILLRECT |
679 | select FB_CFB_COPYAREA | 690 | select FB_CFB_COPYAREA |
680 | select FB_CFB_IMAGEBLIT | 691 | select FB_CFB_IMAGEBLIT |
681 | select VIDEO_SELECT | 692 | select FB_BOOT_VESA_SUPPORT |
682 | help | 693 | help |
683 | This is the frame buffer device driver for generic VESA 2.0 | 694 | This is the frame buffer device driver for generic VESA 2.0 |
684 | compliant graphic cards. The older VESA 1.2 cards are not supported. | 695 | compliant graphic cards. The older VESA 1.2 cards are not supported. |
@@ -687,23 +698,14 @@ config FB_VESA | |||
687 | 698 | ||
688 | config FB_EFI | 699 | config FB_EFI |
689 | bool "EFI-based Framebuffer Support" | 700 | bool "EFI-based Framebuffer Support" |
690 | depends on (FB = y) && X86 | ||
691 | select FB_CFB_FILLRECT | ||
692 | select FB_CFB_COPYAREA | ||
693 | select FB_CFB_IMAGEBLIT | ||
694 | help | ||
695 | This is the EFI frame buffer device driver. If the firmware on | ||
696 | your platform is UEFI2.0, select Y to add support for | ||
697 | Graphics Output Protocol for early console messages to appear. | ||
698 | |||
699 | config FB_IMAC | ||
700 | bool "Intel-based Macintosh Framebuffer Support" | ||
701 | depends on (FB = y) && X86 && EFI | 701 | depends on (FB = y) && X86 && EFI |
702 | select FB_CFB_FILLRECT | 702 | select FB_CFB_FILLRECT |
703 | select FB_CFB_COPYAREA | 703 | select FB_CFB_COPYAREA |
704 | select FB_CFB_IMAGEBLIT | 704 | select FB_CFB_IMAGEBLIT |
705 | help | 705 | help |
706 | This is the frame buffer device driver for the Intel-based Macintosh | 706 | This is the EFI frame buffer device driver. If the firmware on |
707 | your platform is EFI 1.10 or UEFI 2.0, select Y to add support for | ||
708 | using the EFI framebuffer as your console. | ||
707 | 709 | ||
708 | config FB_N411 | 710 | config FB_N411 |
709 | tristate "N411 Apollo/Hecuba devkit support" | 711 | tristate "N411 Apollo/Hecuba devkit support" |
@@ -1124,6 +1126,7 @@ config FB_INTEL | |||
1124 | select FB_CFB_FILLRECT | 1126 | select FB_CFB_FILLRECT |
1125 | select FB_CFB_COPYAREA | 1127 | select FB_CFB_COPYAREA |
1126 | select FB_CFB_IMAGEBLIT | 1128 | select FB_CFB_IMAGEBLIT |
1129 | select FB_BOOT_VESA_SUPPORT | ||
1127 | help | 1130 | help |
1128 | This driver supports the on-board graphics built in to the Intel | 1131 | This driver supports the on-board graphics built in to the Intel |
1129 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. | 1132 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. |
@@ -1476,6 +1479,7 @@ config FB_SIS | |||
1476 | select FB_CFB_FILLRECT | 1479 | select FB_CFB_FILLRECT |
1477 | select FB_CFB_COPYAREA | 1480 | select FB_CFB_COPYAREA |
1478 | select FB_CFB_IMAGEBLIT | 1481 | select FB_CFB_IMAGEBLIT |
1482 | select FB_BOOT_VESA_SUPPORT | ||
1479 | help | 1483 | help |
1480 | This is the frame buffer device driver for the SiS 300, 315, 330 | 1484 | This is the frame buffer device driver for the SiS 300, 315, 330 |
1481 | and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. | 1485 | and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. |
@@ -1498,6 +1502,24 @@ config FB_SIS_315 | |||
1498 | (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well | 1502 | (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well |
1499 | as XGI V3XT, V5, V8 and Z7. | 1503 | as XGI V3XT, V5, V8 and Z7. |
1500 | 1504 | ||
1505 | config FB_VIA | ||
1506 | tristate "VIA UniChrome (Pro) and Chrome9 display support" | ||
1507 | depends on FB && PCI | ||
1508 | select FB_CFB_FILLRECT | ||
1509 | select FB_CFB_COPYAREA | ||
1510 | select FB_CFB_IMAGEBLIT | ||
1511 | select FB_SOFT_CURSOR | ||
1512 | select I2C_ALGOBIT | ||
1513 | select I2C | ||
1514 | help | ||
1515 | This is the frame buffer device driver for Graphics chips of VIA | ||
1516 | UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ | ||
1517 | CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896 | ||
1518 | /P4M900,VX800) | ||
1519 | Say Y if you have a VIA UniChrome graphics board. | ||
1520 | |||
1521 | To compile this driver as a module, choose M here: the | ||
1522 | module will be called viafb. | ||
1501 | config FB_NEOMAGIC | 1523 | config FB_NEOMAGIC |
1502 | tristate "NeoMagic display support" | 1524 | tristate "NeoMagic display support" |
1503 | depends on FB && PCI | 1525 | depends on FB && PCI |
@@ -1527,25 +1549,25 @@ config FB_KYRO | |||
1527 | module will be called kyrofb. | 1549 | module will be called kyrofb. |
1528 | 1550 | ||
1529 | config FB_3DFX | 1551 | config FB_3DFX |
1530 | tristate "3Dfx Banshee/Voodoo3 display support" | 1552 | tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support" |
1531 | depends on FB && PCI | 1553 | depends on FB && PCI |
1532 | select FB_CFB_IMAGEBLIT | 1554 | select FB_CFB_IMAGEBLIT |
1533 | select FB_CFB_FILLRECT | 1555 | select FB_CFB_FILLRECT |
1534 | select FB_CFB_COPYAREA | 1556 | select FB_CFB_COPYAREA |
1535 | help | 1557 | help |
1536 | This driver supports graphics boards with the 3Dfx Banshee/Voodoo3 | 1558 | This driver supports graphics boards with the 3Dfx Banshee, |
1537 | chips. Say Y if you have such a graphics board. | 1559 | Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have |
1560 | such a graphics board. | ||
1538 | 1561 | ||
1539 | To compile this driver as a module, choose M here: the | 1562 | To compile this driver as a module, choose M here: the |
1540 | module will be called tdfxfb. | 1563 | module will be called tdfxfb. |
1541 | 1564 | ||
1542 | config FB_3DFX_ACCEL | 1565 | config FB_3DFX_ACCEL |
1543 | bool "3Dfx Banshee/Voodoo3 Acceleration functions (EXPERIMENTAL)" | 1566 | bool "3Dfx Acceleration functions (EXPERIMENTAL)" |
1544 | depends on FB_3DFX && EXPERIMENTAL | 1567 | depends on FB_3DFX && EXPERIMENTAL |
1545 | ---help--- | 1568 | ---help--- |
1546 | This will compile the 3Dfx Banshee/Voodoo3 frame buffer device | 1569 | This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer |
1547 | with acceleration functions. | 1570 | device driver with acceleration functions. |
1548 | |||
1549 | 1571 | ||
1550 | config FB_VOODOO1 | 1572 | config FB_VOODOO1 |
1551 | tristate "3Dfx Voodoo Graphics (sst1) support" | 1573 | tristate "3Dfx Voodoo Graphics (sst1) support" |
@@ -1583,7 +1605,6 @@ config FB_CYBLA | |||
1583 | tristate "Cyberblade/i1 support" | 1605 | tristate "Cyberblade/i1 support" |
1584 | depends on FB && PCI && X86_32 && !64BIT | 1606 | depends on FB && PCI && X86_32 && !64BIT |
1585 | select FB_CFB_IMAGEBLIT | 1607 | select FB_CFB_IMAGEBLIT |
1586 | select VIDEO_SELECT | ||
1587 | ---help--- | 1608 | ---help--- |
1588 | This driver is supposed to support the Trident Cyberblade/i1 | 1609 | This driver is supposed to support the Trident Cyberblade/i1 |
1589 | graphics core integrated in the VIA VT8601A North Bridge, | 1610 | graphics core integrated in the VIA VT8601A North Bridge, |
@@ -1611,17 +1632,16 @@ config FB_TRIDENT | |||
1611 | select FB_CFB_COPYAREA | 1632 | select FB_CFB_COPYAREA |
1612 | select FB_CFB_IMAGEBLIT | 1633 | select FB_CFB_IMAGEBLIT |
1613 | ---help--- | 1634 | ---help--- |
1614 | This driver is supposed to support graphics boards with the | 1635 | This is the frame buffer device driver for Trident PCI/AGP chipsets. |
1615 | Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops | 1636 | Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D |
1637 | and Blade XP. | ||
1638 | There are also integrated versions of these chips called CyberXXXX, | ||
1639 | CyberImage or CyberBlade. These chips are mostly found in laptops | ||
1616 | but also on some motherboards. For more information, read | 1640 | but also on some motherboards. For more information, read |
1617 | <file:Documentation/fb/tridentfb.txt> | 1641 | <file:Documentation/fb/tridentfb.txt> |
1618 | 1642 | ||
1619 | Cyberblade/i1 support will be removed soon, use the cyblafb driver | ||
1620 | instead. | ||
1621 | |||
1622 | Say Y if you have such a graphics board. | 1643 | Say Y if you have such a graphics board. |
1623 | 1644 | ||
1624 | |||
1625 | To compile this driver as a module, choose M here: the | 1645 | To compile this driver as a module, choose M here: the |
1626 | module will be called tridentfb. | 1646 | module will be called tridentfb. |
1627 | 1647 | ||
@@ -1876,6 +1896,28 @@ config FB_SH_MOBILE_LCDC | |||
1876 | ---help--- | 1896 | ---help--- |
1877 | Frame buffer driver for the on-chip SH-Mobile LCD controller. | 1897 | Frame buffer driver for the on-chip SH-Mobile LCD controller. |
1878 | 1898 | ||
1899 | config FB_TMIO | ||
1900 | tristate "Toshiba Mobile IO FrameBuffer support" | ||
1901 | depends on FB && MFD_CORE | ||
1902 | select FB_CFB_FILLRECT | ||
1903 | select FB_CFB_COPYAREA | ||
1904 | select FB_CFB_IMAGEBLIT | ||
1905 | ---help--- | ||
1906 | Frame buffer driver for the Toshiba Mobile IO integrated as found | ||
1907 | on the Sharp SL-6000 series | ||
1908 | |||
1909 | This driver is also available as a module ( = code which can be | ||
1910 | inserted and removed from the running kernel whenever you want). The | ||
1911 | module will be called tmiofb. If you want to compile it as a module, | ||
1912 | say M here and read <file:Documentation/kbuild/modules.txt>. | ||
1913 | |||
1914 | If unsure, say N. | ||
1915 | |||
1916 | config FB_TMIO_ACCELL | ||
1917 | bool "tmiofb acceleration" | ||
1918 | depends on FB_TMIO | ||
1919 | default y | ||
1920 | |||
1879 | config FB_S3C2410 | 1921 | config FB_S3C2410 |
1880 | tristate "S3C2410 LCD framebuffer support" | 1922 | tristate "S3C2410 LCD framebuffer support" |
1881 | depends on FB && ARCH_S3C2410 | 1923 | depends on FB && ARCH_S3C2410 |
@@ -1974,19 +2016,6 @@ config FB_XILINX | |||
1974 | framebuffer. ML300 carries a 640*480 LCD display on the board, | 2016 | framebuffer. ML300 carries a 640*480 LCD display on the board, |
1975 | ML403 uses a standard DB15 VGA connector. | 2017 | ML403 uses a standard DB15 VGA connector. |
1976 | 2018 | ||
1977 | config FB_AM200EPD | ||
1978 | tristate "AM-200 E-Ink EPD devkit support" | ||
1979 | depends on FB && ARCH_PXA && MMU | ||
1980 | select FB_SYS_FILLRECT | ||
1981 | select FB_SYS_COPYAREA | ||
1982 | select FB_SYS_IMAGEBLIT | ||
1983 | select FB_SYS_FOPS | ||
1984 | select FB_DEFERRED_IO | ||
1985 | select FB_METRONOME | ||
1986 | help | ||
1987 | This enables support for the Metronome display controller used on | ||
1988 | the E-Ink AM-200 EPD devkit. | ||
1989 | |||
1990 | config FB_COBALT | 2019 | config FB_COBALT |
1991 | tristate "Cobalt server LCD frame buffer support" | 2020 | tristate "Cobalt server LCD frame buffer support" |
1992 | depends on FB && MIPS_COBALT | 2021 | depends on FB && MIPS_COBALT |
@@ -2041,6 +2070,19 @@ config XEN_FBDEV_FRONTEND | |||
2041 | frame buffer driver. It communicates with a back-end | 2070 | frame buffer driver. It communicates with a back-end |
2042 | in another domain. | 2071 | in another domain. |
2043 | 2072 | ||
2073 | config FB_METRONOME | ||
2074 | tristate "E-Ink Metronome/8track controller support" | ||
2075 | depends on FB | ||
2076 | select FB_SYS_FILLRECT | ||
2077 | select FB_SYS_COPYAREA | ||
2078 | select FB_SYS_IMAGEBLIT | ||
2079 | select FB_SYS_FOPS | ||
2080 | select FB_DEFERRED_IO | ||
2081 | help | ||
2082 | This driver implements support for the E-Ink Metronome | ||
2083 | controller. The pre-release name for this device was 8track | ||
2084 | and could also have been called by some vendors as PVI-nnnn. | ||
2085 | |||
2044 | source "drivers/video/omap/Kconfig" | 2086 | source "drivers/video/omap/Kconfig" |
2045 | 2087 | ||
2046 | source "drivers/video/backlight/Kconfig" | 2088 | source "drivers/video/backlight/Kconfig" |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index a6b55297a7fb..248bddc8d0b0 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -29,7 +29,6 @@ obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o | |||
29 | 29 | ||
30 | # Hardware specific drivers go first | 30 | # Hardware specific drivers go first |
31 | obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o | 31 | obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o |
32 | obj-$(CONFIG_FB_AM200EPD) += am200epd.o | ||
33 | obj-$(CONFIG_FB_ARC) += arcfb.o | 32 | obj-$(CONFIG_FB_ARC) += arcfb.o |
34 | obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o | 33 | obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o |
35 | obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o | 34 | obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o |
@@ -43,6 +42,7 @@ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o | |||
43 | obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o | 42 | obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o |
44 | obj-$(CONFIG_FB_RADEON) += aty/ | 43 | obj-$(CONFIG_FB_RADEON) += aty/ |
45 | obj-$(CONFIG_FB_SIS) += sis/ | 44 | obj-$(CONFIG_FB_SIS) += sis/ |
45 | obj-$(CONFIG_FB_VIA) += via/ | ||
46 | obj-$(CONFIG_FB_KYRO) += kyro/ | 46 | obj-$(CONFIG_FB_KYRO) += kyro/ |
47 | obj-$(CONFIG_FB_SAVAGE) += savage/ | 47 | obj-$(CONFIG_FB_SAVAGE) += savage/ |
48 | obj-$(CONFIG_FB_GEODE) += geode/ | 48 | obj-$(CONFIG_FB_GEODE) += geode/ |
@@ -98,6 +98,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o | |||
98 | obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o | 98 | obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o |
99 | obj-$(CONFIG_FB_PXA) += pxafb.o | 99 | obj-$(CONFIG_FB_PXA) += pxafb.o |
100 | obj-$(CONFIG_FB_W100) += w100fb.o | 100 | obj-$(CONFIG_FB_W100) += w100fb.o |
101 | obj-$(CONFIG_FB_TMIO) += tmiofb.o | ||
101 | obj-$(CONFIG_FB_AU1100) += au1100fb.o | 102 | obj-$(CONFIG_FB_AU1100) += au1100fb.o |
102 | obj-$(CONFIG_FB_AU1200) += au1200fb.o | 103 | obj-$(CONFIG_FB_AU1200) += au1200fb.o |
103 | obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o | 104 | obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o |
@@ -125,7 +126,6 @@ obj-$(CONFIG_FB_CARMINE) += carminefb.o | |||
125 | # Platform or fallback drivers go here | 126 | # Platform or fallback drivers go here |
126 | obj-$(CONFIG_FB_UVESA) += uvesafb.o | 127 | obj-$(CONFIG_FB_UVESA) += uvesafb.o |
127 | obj-$(CONFIG_FB_VESA) += vesafb.o | 128 | obj-$(CONFIG_FB_VESA) += vesafb.o |
128 | obj-$(CONFIG_FB_IMAC) += imacfb.o | ||
129 | obj-$(CONFIG_FB_EFI) += efifb.o | 129 | obj-$(CONFIG_FB_EFI) += efifb.o |
130 | obj-$(CONFIG_FB_VGA16) += vga16fb.o | 130 | obj-$(CONFIG_FB_VGA16) += vga16fb.o |
131 | obj-$(CONFIG_FB_OF) += offb.o | 131 | obj-$(CONFIG_FB_OF) += offb.o |
diff --git a/drivers/video/am200epd.c b/drivers/video/am200epd.c deleted file mode 100644 index 0c35b8b0160e..000000000000 --- a/drivers/video/am200epd.c +++ /dev/null | |||
@@ -1,295 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/am200epd.c -- Platform device for AM200 EPD kit | ||
3 | * | ||
4 | * Copyright (C) 2008, Jaya Kumar | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive for | ||
8 | * more details. | ||
9 | * | ||
10 | * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. | ||
11 | * | ||
12 | * This work was made possible by help and equipment support from E-Ink | ||
13 | * Corporation. http://support.eink.com/community | ||
14 | * | ||
15 | * This driver is written to be used with the Metronome display controller. | ||
16 | * on the AM200 EPD prototype kit/development kit with an E-Ink 800x600 | ||
17 | * Vizplex EPD on a Gumstix board using the Lyre interface board. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/fb.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/list.h> | ||
31 | #include <linux/uaccess.h> | ||
32 | #include <linux/irq.h> | ||
33 | |||
34 | #include <video/metronomefb.h> | ||
35 | |||
36 | #include <mach/pxa-regs.h> | ||
37 | |||
38 | /* register offsets for gpio control */ | ||
39 | #define LED_GPIO_PIN 51 | ||
40 | #define STDBY_GPIO_PIN 48 | ||
41 | #define RST_GPIO_PIN 49 | ||
42 | #define RDY_GPIO_PIN 32 | ||
43 | #define ERR_GPIO_PIN 17 | ||
44 | #define PCBPWR_GPIO_PIN 16 | ||
45 | |||
46 | #define AF_SEL_GPIO_N 0x3 | ||
47 | #define GAFR0_U_OFFSET(pin) ((pin - 16) * 2) | ||
48 | #define GAFR1_L_OFFSET(pin) ((pin - 32) * 2) | ||
49 | #define GAFR1_U_OFFSET(pin) ((pin - 48) * 2) | ||
50 | #define GPDR1_OFFSET(pin) (pin - 32) | ||
51 | #define GPCR1_OFFSET(pin) (pin - 32) | ||
52 | #define GPSR1_OFFSET(pin) (pin - 32) | ||
53 | #define GPCR0_OFFSET(pin) (pin) | ||
54 | #define GPSR0_OFFSET(pin) (pin) | ||
55 | |||
56 | static void am200_set_gpio_output(int pin, int val) | ||
57 | { | ||
58 | u8 index; | ||
59 | |||
60 | index = pin >> 4; | ||
61 | |||
62 | switch (index) { | ||
63 | case 1: | ||
64 | if (val) | ||
65 | GPSR0 |= (1 << GPSR0_OFFSET(pin)); | ||
66 | else | ||
67 | GPCR0 |= (1 << GPCR0_OFFSET(pin)); | ||
68 | break; | ||
69 | case 2: | ||
70 | break; | ||
71 | case 3: | ||
72 | if (val) | ||
73 | GPSR1 |= (1 << GPSR1_OFFSET(pin)); | ||
74 | else | ||
75 | GPCR1 |= (1 << GPCR1_OFFSET(pin)); | ||
76 | break; | ||
77 | default: | ||
78 | printk(KERN_ERR "unimplemented\n"); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static void __devinit am200_init_gpio_pin(int pin, int dir) | ||
83 | { | ||
84 | u8 index; | ||
85 | /* dir 0 is output, 1 is input | ||
86 | - do 2 things here: | ||
87 | - set gpio alternate function to standard gpio | ||
88 | - set gpio direction to input or output */ | ||
89 | |||
90 | index = pin >> 4; | ||
91 | switch (index) { | ||
92 | case 1: | ||
93 | GAFR0_U &= ~(AF_SEL_GPIO_N << GAFR0_U_OFFSET(pin)); | ||
94 | |||
95 | if (dir) | ||
96 | GPDR0 &= ~(1 << pin); | ||
97 | else | ||
98 | GPDR0 |= (1 << pin); | ||
99 | break; | ||
100 | case 2: | ||
101 | GAFR1_L &= ~(AF_SEL_GPIO_N << GAFR1_L_OFFSET(pin)); | ||
102 | |||
103 | if (dir) | ||
104 | GPDR1 &= ~(1 << GPDR1_OFFSET(pin)); | ||
105 | else | ||
106 | GPDR1 |= (1 << GPDR1_OFFSET(pin)); | ||
107 | break; | ||
108 | case 3: | ||
109 | GAFR1_U &= ~(AF_SEL_GPIO_N << GAFR1_U_OFFSET(pin)); | ||
110 | |||
111 | if (dir) | ||
112 | GPDR1 &= ~(1 << GPDR1_OFFSET(pin)); | ||
113 | else | ||
114 | GPDR1 |= (1 << GPDR1_OFFSET(pin)); | ||
115 | break; | ||
116 | default: | ||
117 | printk(KERN_ERR "unimplemented\n"); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static void am200_init_gpio_regs(struct metronomefb_par *par) | ||
122 | { | ||
123 | am200_init_gpio_pin(LED_GPIO_PIN, 0); | ||
124 | am200_set_gpio_output(LED_GPIO_PIN, 0); | ||
125 | |||
126 | am200_init_gpio_pin(STDBY_GPIO_PIN, 0); | ||
127 | am200_set_gpio_output(STDBY_GPIO_PIN, 0); | ||
128 | |||
129 | am200_init_gpio_pin(RST_GPIO_PIN, 0); | ||
130 | am200_set_gpio_output(RST_GPIO_PIN, 0); | ||
131 | |||
132 | am200_init_gpio_pin(RDY_GPIO_PIN, 1); | ||
133 | |||
134 | am200_init_gpio_pin(ERR_GPIO_PIN, 1); | ||
135 | |||
136 | am200_init_gpio_pin(PCBPWR_GPIO_PIN, 0); | ||
137 | am200_set_gpio_output(PCBPWR_GPIO_PIN, 0); | ||
138 | } | ||
139 | |||
140 | static void am200_disable_lcd_controller(struct metronomefb_par *par) | ||
141 | { | ||
142 | LCSR = 0xffffffff; /* Clear LCD Status Register */ | ||
143 | LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */ | ||
144 | |||
145 | /* we reset and just wait for things to settle */ | ||
146 | msleep(200); | ||
147 | } | ||
148 | |||
149 | static void am200_enable_lcd_controller(struct metronomefb_par *par) | ||
150 | { | ||
151 | LCSR = 0xffffffff; | ||
152 | FDADR0 = par->metromem_desc_dma; | ||
153 | LCCR0 |= LCCR0_ENB; | ||
154 | } | ||
155 | |||
156 | static void am200_init_lcdc_regs(struct metronomefb_par *par) | ||
157 | { | ||
158 | /* here we do: | ||
159 | - disable the lcd controller | ||
160 | - setup lcd control registers | ||
161 | - setup dma descriptor | ||
162 | - reenable lcd controller | ||
163 | */ | ||
164 | |||
165 | /* disable the lcd controller */ | ||
166 | am200_disable_lcd_controller(par); | ||
167 | |||
168 | /* setup lcd control registers */ | ||
169 | LCCR0 = LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_PAS | ||
170 | | LCCR0_QDM | LCCR0_BM | LCCR0_OUM; | ||
171 | |||
172 | LCCR1 = (par->info->var.xres/2 - 1) /* pixels per line */ | ||
173 | | (27 << 10) /* hsync pulse width - 1 */ | ||
174 | | (33 << 16) /* eol pixel count */ | ||
175 | | (33 << 24); /* bol pixel count */ | ||
176 | |||
177 | LCCR2 = (par->info->var.yres - 1) /* lines per panel */ | ||
178 | | (24 << 10) /* vsync pulse width - 1 */ | ||
179 | | (2 << 16) /* eof pixel count */ | ||
180 | | (0 << 24); /* bof pixel count */ | ||
181 | |||
182 | LCCR3 = 2 /* pixel clock divisor */ | ||
183 | | (24 << 8) /* AC Bias pin freq */ | ||
184 | | LCCR3_16BPP /* BPP */ | ||
185 | | LCCR3_PCP; /* PCP falling edge */ | ||
186 | |||
187 | } | ||
188 | |||
189 | static void am200_post_dma_setup(struct metronomefb_par *par) | ||
190 | { | ||
191 | par->metromem_desc->mFDADR0 = par->metromem_desc_dma; | ||
192 | par->metromem_desc->mFSADR0 = par->metromem_dma; | ||
193 | par->metromem_desc->mFIDR0 = 0; | ||
194 | par->metromem_desc->mLDCMD0 = par->info->var.xres | ||
195 | * par->info->var.yres; | ||
196 | am200_enable_lcd_controller(par); | ||
197 | } | ||
198 | |||
199 | static void am200_free_irq(struct fb_info *info) | ||
200 | { | ||
201 | free_irq(IRQ_GPIO(RDY_GPIO_PIN), info); | ||
202 | } | ||
203 | |||
204 | static irqreturn_t am200_handle_irq(int irq, void *dev_id) | ||
205 | { | ||
206 | struct fb_info *info = dev_id; | ||
207 | struct metronomefb_par *par = info->par; | ||
208 | |||
209 | wake_up_interruptible(&par->waitq); | ||
210 | return IRQ_HANDLED; | ||
211 | } | ||
212 | |||
213 | static int am200_setup_irq(struct fb_info *info) | ||
214 | { | ||
215 | int retval; | ||
216 | |||
217 | retval = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq, | ||
218 | IRQF_DISABLED, "AM200", info); | ||
219 | if (retval) { | ||
220 | printk(KERN_ERR "am200epd: request_irq failed: %d\n", retval); | ||
221 | return retval; | ||
222 | } | ||
223 | |||
224 | return set_irq_type(IRQ_GPIO(RDY_GPIO_PIN), IRQ_TYPE_EDGE_FALLING); | ||
225 | } | ||
226 | |||
227 | static void am200_set_rst(struct metronomefb_par *par, int state) | ||
228 | { | ||
229 | am200_set_gpio_output(RST_GPIO_PIN, state); | ||
230 | } | ||
231 | |||
232 | static void am200_set_stdby(struct metronomefb_par *par, int state) | ||
233 | { | ||
234 | am200_set_gpio_output(STDBY_GPIO_PIN, state); | ||
235 | } | ||
236 | |||
237 | static int am200_wait_event(struct metronomefb_par *par) | ||
238 | { | ||
239 | return wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ); | ||
240 | } | ||
241 | |||
242 | static int am200_wait_event_intr(struct metronomefb_par *par) | ||
243 | { | ||
244 | return wait_event_interruptible_timeout(par->waitq, (GPLR1 & 0x01), HZ); | ||
245 | } | ||
246 | |||
247 | static struct metronome_board am200_board = { | ||
248 | .owner = THIS_MODULE, | ||
249 | .free_irq = am200_free_irq, | ||
250 | .setup_irq = am200_setup_irq, | ||
251 | .init_gpio_regs = am200_init_gpio_regs, | ||
252 | .init_lcdc_regs = am200_init_lcdc_regs, | ||
253 | .post_dma_setup = am200_post_dma_setup, | ||
254 | .set_rst = am200_set_rst, | ||
255 | .set_stdby = am200_set_stdby, | ||
256 | .met_wait_event = am200_wait_event, | ||
257 | .met_wait_event_intr = am200_wait_event_intr, | ||
258 | }; | ||
259 | |||
260 | static struct platform_device *am200_device; | ||
261 | |||
262 | static int __init am200_init(void) | ||
263 | { | ||
264 | int ret; | ||
265 | |||
266 | /* request our platform independent driver */ | ||
267 | request_module("metronomefb"); | ||
268 | |||
269 | am200_device = platform_device_alloc("metronomefb", -1); | ||
270 | if (!am200_device) | ||
271 | return -ENOMEM; | ||
272 | |||
273 | platform_device_add_data(am200_device, &am200_board, | ||
274 | sizeof(am200_board)); | ||
275 | |||
276 | /* this _add binds metronomefb to am200. metronomefb refcounts am200 */ | ||
277 | ret = platform_device_add(am200_device); | ||
278 | |||
279 | if (ret) | ||
280 | platform_device_put(am200_device); | ||
281 | |||
282 | return ret; | ||
283 | } | ||
284 | |||
285 | static void __exit am200_exit(void) | ||
286 | { | ||
287 | platform_device_unregister(am200_device); | ||
288 | } | ||
289 | |||
290 | module_init(am200_init); | ||
291 | module_exit(am200_exit); | ||
292 | |||
293 | MODULE_DESCRIPTION("board driver for am200 metronome epd kit"); | ||
294 | MODULE_AUTHOR("Jaya Kumar"); | ||
295 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 5a24c6411d34..f8d0a57a07cb 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -208,6 +208,36 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) | |||
208 | return value; | 208 | return value; |
209 | } | 209 | } |
210 | 210 | ||
211 | static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo) | ||
212 | { | ||
213 | /* Turn off the LCD controller and the DMA controller */ | ||
214 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, | ||
215 | sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); | ||
216 | |||
217 | /* Wait for the LCDC core to become idle */ | ||
218 | while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) | ||
219 | msleep(10); | ||
220 | |||
221 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); | ||
222 | } | ||
223 | |||
224 | static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo) | ||
225 | { | ||
226 | atmel_lcdfb_stop_nowait(sinfo); | ||
227 | |||
228 | /* Wait for DMA engine to become idle... */ | ||
229 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) | ||
230 | msleep(10); | ||
231 | } | ||
232 | |||
233 | static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo) | ||
234 | { | ||
235 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); | ||
236 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, | ||
237 | (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ||
238 | | ATMEL_LCDC_PWR); | ||
239 | } | ||
240 | |||
211 | static void atmel_lcdfb_update_dma(struct fb_info *info, | 241 | static void atmel_lcdfb_update_dma(struct fb_info *info, |
212 | struct fb_var_screeninfo *var) | 242 | struct fb_var_screeninfo *var) |
213 | { | 243 | { |
@@ -342,6 +372,13 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, | |||
342 | var->transp.offset = var->transp.length = 0; | 372 | var->transp.offset = var->transp.length = 0; |
343 | var->xoffset = var->yoffset = 0; | 373 | var->xoffset = var->yoffset = 0; |
344 | 374 | ||
375 | if (info->fix.smem_len) { | ||
376 | unsigned int smem_len = (var->xres_virtual * var->yres_virtual | ||
377 | * ((var->bits_per_pixel + 7) / 8)); | ||
378 | if (smem_len > info->fix.smem_len) | ||
379 | return -EINVAL; | ||
380 | } | ||
381 | |||
345 | /* Saturate vertical and horizontal timings at maximum values */ | 382 | /* Saturate vertical and horizontal timings at maximum values */ |
346 | var->vsync_len = min_t(u32, var->vsync_len, | 383 | var->vsync_len = min_t(u32, var->vsync_len, |
347 | (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); | 384 | (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); |
@@ -378,6 +415,10 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, | |||
378 | var->red.offset = 11; | 415 | var->red.offset = 11; |
379 | var->blue.offset = 0; | 416 | var->blue.offset = 0; |
380 | var->green.length = 6; | 417 | var->green.length = 6; |
418 | } else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) { | ||
419 | var->red.offset = 10; | ||
420 | var->blue.offset = 0; | ||
421 | var->green.length = 5; | ||
381 | } else { | 422 | } else { |
382 | /* BGR:555 mode */ | 423 | /* BGR:555 mode */ |
383 | var->red.offset = 0; | 424 | var->red.offset = 0; |
@@ -420,26 +461,8 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo) | |||
420 | { | 461 | { |
421 | might_sleep(); | 462 | might_sleep(); |
422 | 463 | ||
423 | /* LCD power off */ | 464 | atmel_lcdfb_stop(sinfo); |
424 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); | 465 | atmel_lcdfb_start(sinfo); |
425 | |||
426 | /* wait for the LCDC core to become idle */ | ||
427 | while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) | ||
428 | msleep(10); | ||
429 | |||
430 | /* DMA disable */ | ||
431 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); | ||
432 | |||
433 | /* wait for DMA engine to become idle */ | ||
434 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) | ||
435 | msleep(10); | ||
436 | |||
437 | /* LCD power on */ | ||
438 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, | ||
439 | (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); | ||
440 | |||
441 | /* DMA enable */ | ||
442 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); | ||
443 | } | 466 | } |
444 | 467 | ||
445 | /** | 468 | /** |
@@ -471,14 +494,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) | |||
471 | info->var.xres, info->var.yres, | 494 | info->var.xres, info->var.yres, |
472 | info->var.xres_virtual, info->var.yres_virtual); | 495 | info->var.xres_virtual, info->var.yres_virtual); |
473 | 496 | ||
474 | /* Turn off the LCD controller and the DMA controller */ | 497 | atmel_lcdfb_stop_nowait(sinfo); |
475 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); | ||
476 | |||
477 | /* Wait for the LCDC core to become idle */ | ||
478 | while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) | ||
479 | msleep(10); | ||
480 | |||
481 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); | ||
482 | 498 | ||
483 | if (info->var.bits_per_pixel == 1) | 499 | if (info->var.bits_per_pixel == 1) |
484 | info->fix.visual = FB_VISUAL_MONO01; | 500 | info->fix.visual = FB_VISUAL_MONO01; |
@@ -583,13 +599,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) | |||
583 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) | 599 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) |
584 | msleep(10); | 600 | msleep(10); |
585 | 601 | ||
586 | dev_dbg(info->device, " * re-enable DMA engine\n"); | 602 | atmel_lcdfb_start(sinfo); |
587 | /* ...and enable it with updated configuration */ | ||
588 | lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); | ||
589 | |||
590 | dev_dbg(info->device, " * re-enable LCDC core\n"); | ||
591 | lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, | ||
592 | (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); | ||
593 | 603 | ||
594 | dev_dbg(info->device, " * DONE\n"); | 604 | dev_dbg(info->device, " * DONE\n"); |
595 | 605 | ||
@@ -1032,11 +1042,20 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
1032 | struct fb_info *info = platform_get_drvdata(pdev); | 1042 | struct fb_info *info = platform_get_drvdata(pdev); |
1033 | struct atmel_lcdfb_info *sinfo = info->par; | 1043 | struct atmel_lcdfb_info *sinfo = info->par; |
1034 | 1044 | ||
1045 | /* | ||
1046 | * We don't want to handle interrupts while the clock is | ||
1047 | * stopped. It may take forever. | ||
1048 | */ | ||
1049 | lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); | ||
1050 | |||
1035 | sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); | 1051 | sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); |
1036 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); | 1052 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); |
1037 | if (sinfo->atmel_lcdfb_power_control) | 1053 | if (sinfo->atmel_lcdfb_power_control) |
1038 | sinfo->atmel_lcdfb_power_control(0); | 1054 | sinfo->atmel_lcdfb_power_control(0); |
1055 | |||
1056 | atmel_lcdfb_stop(sinfo); | ||
1039 | atmel_lcdfb_stop_clock(sinfo); | 1057 | atmel_lcdfb_stop_clock(sinfo); |
1058 | |||
1040 | return 0; | 1059 | return 0; |
1041 | } | 1060 | } |
1042 | 1061 | ||
@@ -1046,9 +1065,15 @@ static int atmel_lcdfb_resume(struct platform_device *pdev) | |||
1046 | struct atmel_lcdfb_info *sinfo = info->par; | 1065 | struct atmel_lcdfb_info *sinfo = info->par; |
1047 | 1066 | ||
1048 | atmel_lcdfb_start_clock(sinfo); | 1067 | atmel_lcdfb_start_clock(sinfo); |
1068 | atmel_lcdfb_start(sinfo); | ||
1049 | if (sinfo->atmel_lcdfb_power_control) | 1069 | if (sinfo->atmel_lcdfb_power_control) |
1050 | sinfo->atmel_lcdfb_power_control(1); | 1070 | sinfo->atmel_lcdfb_power_control(1); |
1051 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon); | 1071 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon); |
1072 | |||
1073 | /* Enable FIFO & DMA errors */ | ||
1074 | lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ||
1075 | | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI); | ||
1076 | |||
1052 | return 0; | 1077 | return 0; |
1053 | } | 1078 | } |
1054 | 1079 | ||
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c index aa95f8350242..8718f7349d6b 100644 --- a/drivers/video/aty/radeon_accel.c +++ b/drivers/video/aty/radeon_accel.c | |||
@@ -5,61 +5,61 @@ | |||
5 | * --dte | 5 | * --dte |
6 | */ | 6 | */ |
7 | 7 | ||
8 | static void radeon_fixup_offset(struct radeonfb_info *rinfo) | 8 | #define FLUSH_CACHE_WORKAROUND 1 |
9 | |||
10 | void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries) | ||
9 | { | 11 | { |
10 | u32 local_base; | 12 | int i; |
11 | |||
12 | /* *** Ugly workaround *** */ | ||
13 | /* | ||
14 | * On some platforms, the video memory is mapped at 0 in radeon chip space | ||
15 | * (like PPCs) by the firmware. X will always move it up so that it's seen | ||
16 | * by the chip to be at the same address as the PCI BAR. | ||
17 | * That means that when switching back from X, there is a mismatch between | ||
18 | * the offsets programmed into the engine. This means that potentially, | ||
19 | * accel operations done before radeonfb has a chance to re-init the engine | ||
20 | * will have incorrect offsets, and potentially trash system memory ! | ||
21 | * | ||
22 | * The correct fix is for fbcon to never call any accel op before the engine | ||
23 | * has properly been re-initialized (by a call to set_var), but this is a | ||
24 | * complex fix. This workaround in the meantime, called before every accel | ||
25 | * operation, makes sure the offsets are in sync. | ||
26 | */ | ||
27 | 13 | ||
28 | radeon_fifo_wait (1); | 14 | for (i=0; i<2000000; i++) { |
29 | local_base = INREG(MC_FB_LOCATION) << 16; | 15 | rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f; |
30 | if (local_base == rinfo->fb_local_base) | 16 | if (rinfo->fifo_free >= entries) |
31 | return; | 17 | return; |
18 | udelay(10); | ||
19 | } | ||
20 | printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); | ||
21 | /* XXX Todo: attempt to reset the engine */ | ||
22 | } | ||
32 | 23 | ||
33 | rinfo->fb_local_base = local_base; | 24 | static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) |
25 | { | ||
26 | if (entries <= rinfo->fifo_free) | ||
27 | rinfo->fifo_free -= entries; | ||
28 | else | ||
29 | radeon_fifo_update_and_wait(rinfo, entries); | ||
30 | } | ||
34 | 31 | ||
35 | radeon_fifo_wait (3); | 32 | static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg, |
36 | OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) | | 33 | u32 *cache, u32 new_val) |
37 | (rinfo->fb_local_base >> 10)); | 34 | { |
38 | OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); | 35 | if (new_val == *cache) |
39 | OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); | 36 | return; |
37 | *cache = new_val; | ||
38 | radeon_fifo_wait(rinfo, 1); | ||
39 | OUTREG(reg, new_val); | ||
40 | } | 40 | } |
41 | 41 | ||
42 | static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, | 42 | static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, |
43 | const struct fb_fillrect *region) | 43 | const struct fb_fillrect *region) |
44 | { | 44 | { |
45 | radeon_fifo_wait(4); | 45 | radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, |
46 | 46 | rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P); | |
47 | OUTREG(DP_GUI_MASTER_CNTL, | 47 | radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, |
48 | rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */ | 48 | DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); |
49 | | GMC_BRUSH_SOLID_COLOR | 49 | radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache, |
50 | | ROP3_P); | 50 | region->color); |
51 | if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP) | 51 | |
52 | OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]); | 52 | /* Ensure the dst cache is flushed and the engine idle before |
53 | else | 53 | * issuing the operation. |
54 | OUTREG(DP_BRUSH_FRGD_CLR, region->color); | 54 | * |
55 | OUTREG(DP_WRITE_MSK, 0xffffffff); | 55 | * This works around engine lockups on some cards |
56 | OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); | 56 | */ |
57 | 57 | #if FLUSH_CACHE_WORKAROUND | |
58 | radeon_fifo_wait(2); | 58 | radeon_fifo_wait(rinfo, 2); |
59 | OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); | 59 | OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); |
60 | OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); | 60 | OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); |
61 | 61 | #endif | |
62 | radeon_fifo_wait(2); | 62 | radeon_fifo_wait(rinfo, 2); |
63 | OUTREG(DST_Y_X, (region->dy << 16) | region->dx); | 63 | OUTREG(DST_Y_X, (region->dy << 16) | region->dx); |
64 | OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); | 64 | OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); |
65 | } | 65 | } |
@@ -70,15 +70,14 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) | |||
70 | struct fb_fillrect modded; | 70 | struct fb_fillrect modded; |
71 | int vxres, vyres; | 71 | int vxres, vyres; |
72 | 72 | ||
73 | if (info->state != FBINFO_STATE_RUNNING) | 73 | WARN_ON(rinfo->gfx_mode); |
74 | if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) | ||
74 | return; | 75 | return; |
75 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 76 | if (info->flags & FBINFO_HWACCEL_DISABLED) { |
76 | cfb_fillrect(info, region); | 77 | cfb_fillrect(info, region); |
77 | return; | 78 | return; |
78 | } | 79 | } |
79 | 80 | ||
80 | radeon_fixup_offset(rinfo); | ||
81 | |||
82 | vxres = info->var.xres_virtual; | 81 | vxres = info->var.xres_virtual; |
83 | vyres = info->var.yres_virtual; | 82 | vyres = info->var.yres_virtual; |
84 | 83 | ||
@@ -91,6 +90,10 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) | |||
91 | if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; | 90 | if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; |
92 | if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; | 91 | if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; |
93 | 92 | ||
93 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
94 | info->fix.visual == FB_VISUAL_DIRECTCOLOR ) | ||
95 | modded.color = ((u32 *) (info->pseudo_palette))[region->color]; | ||
96 | |||
94 | radeonfb_prim_fillrect(rinfo, &modded); | 97 | radeonfb_prim_fillrect(rinfo, &modded); |
95 | } | 98 | } |
96 | 99 | ||
@@ -109,22 +112,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo, | |||
109 | if ( xdir < 0 ) { sx += w-1; dx += w-1; } | 112 | if ( xdir < 0 ) { sx += w-1; dx += w-1; } |
110 | if ( ydir < 0 ) { sy += h-1; dy += h-1; } | 113 | if ( ydir < 0 ) { sy += h-1; dy += h-1; } |
111 | 114 | ||
112 | radeon_fifo_wait(3); | 115 | radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, |
113 | OUTREG(DP_GUI_MASTER_CNTL, | 116 | rinfo->dp_gui_mc_base | |
114 | rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */ | 117 | GMC_BRUSH_NONE | |
115 | | GMC_BRUSH_NONE | 118 | GMC_SRC_DATATYPE_COLOR | |
116 | | GMC_SRC_DSTCOLOR | 119 | ROP3_S | |
117 | | ROP3_S | 120 | DP_SRC_SOURCE_MEMORY); |
118 | | DP_SRC_SOURCE_MEMORY ); | 121 | radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, |
119 | OUTREG(DP_WRITE_MSK, 0xffffffff); | 122 | (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) | |
120 | OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) | 123 | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); |
121 | | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); | 124 | |
122 | 125 | #if FLUSH_CACHE_WORKAROUND | |
123 | radeon_fifo_wait(2); | 126 | radeon_fifo_wait(rinfo, 2); |
124 | OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); | 127 | OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); |
125 | OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); | 128 | OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); |
126 | 129 | #endif | |
127 | radeon_fifo_wait(3); | 130 | radeon_fifo_wait(rinfo, 3); |
128 | OUTREG(SRC_Y_X, (sy << 16) | sx); | 131 | OUTREG(SRC_Y_X, (sy << 16) | sx); |
129 | OUTREG(DST_Y_X, (dy << 16) | dx); | 132 | OUTREG(DST_Y_X, (dy << 16) | dx); |
130 | OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w); | 133 | OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w); |
@@ -143,15 +146,14 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
143 | modded.width = area->width; | 146 | modded.width = area->width; |
144 | modded.height = area->height; | 147 | modded.height = area->height; |
145 | 148 | ||
146 | if (info->state != FBINFO_STATE_RUNNING) | 149 | WARN_ON(rinfo->gfx_mode); |
150 | if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) | ||
147 | return; | 151 | return; |
148 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 152 | if (info->flags & FBINFO_HWACCEL_DISABLED) { |
149 | cfb_copyarea(info, area); | 153 | cfb_copyarea(info, area); |
150 | return; | 154 | return; |
151 | } | 155 | } |
152 | 156 | ||
153 | radeon_fixup_offset(rinfo); | ||
154 | |||
155 | vxres = info->var.xres_virtual; | 157 | vxres = info->var.xres_virtual; |
156 | vyres = info->var.yres_virtual; | 158 | vyres = info->var.yres_virtual; |
157 | 159 | ||
@@ -168,13 +170,112 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
168 | radeonfb_prim_copyarea(rinfo, &modded); | 170 | radeonfb_prim_copyarea(rinfo, &modded); |
169 | } | 171 | } |
170 | 172 | ||
173 | static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, | ||
174 | const struct fb_image *image, | ||
175 | u32 fg, u32 bg) | ||
176 | { | ||
177 | unsigned int src_bytes, dwords; | ||
178 | u32 *bits; | ||
179 | |||
180 | radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, | ||
181 | rinfo->dp_gui_mc_base | | ||
182 | GMC_BRUSH_NONE | | ||
183 | GMC_SRC_DATATYPE_MONO_FG_BG | | ||
184 | ROP3_S | | ||
185 | GMC_BYTE_ORDER_MSB_TO_LSB | | ||
186 | DP_SRC_SOURCE_HOST_DATA); | ||
187 | radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, | ||
188 | DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); | ||
189 | radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg); | ||
190 | radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg); | ||
191 | |||
192 | radeon_fifo_wait(rinfo, 1); | ||
193 | OUTREG(DST_Y_X, (image->dy << 16) | image->dx); | ||
194 | |||
195 | /* Ensure the dst cache is flushed and the engine idle before | ||
196 | * issuing the operation. | ||
197 | * | ||
198 | * This works around engine lockups on some cards | ||
199 | */ | ||
200 | #if FLUSH_CACHE_WORKAROUND | ||
201 | radeon_fifo_wait(rinfo, 2); | ||
202 | OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); | ||
203 | OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); | ||
204 | #endif | ||
205 | |||
206 | /* X here pads width to a multiple of 32 and uses the clipper to | ||
207 | * adjust the result. Is that really necessary ? Things seem to | ||
208 | * work ok for me without that and the doco doesn't seem to imply | ||
209 | * there is such a restriction. | ||
210 | */ | ||
211 | OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height); | ||
212 | |||
213 | src_bytes = (((image->width * image->depth) + 7) / 8) * image->height; | ||
214 | dwords = (src_bytes + 3) / 4; | ||
215 | bits = (u32*)(image->data); | ||
216 | |||
217 | while(dwords >= 8) { | ||
218 | radeon_fifo_wait(rinfo, 8); | ||
219 | #if BITS_PER_LONG == 64 | ||
220 | __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0); | ||
221 | __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2); | ||
222 | __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4); | ||
223 | __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6); | ||
224 | bits += 8; | ||
225 | #else | ||
226 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0); | ||
227 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1); | ||
228 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2); | ||
229 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3); | ||
230 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4); | ||
231 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5); | ||
232 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6); | ||
233 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7); | ||
234 | #endif | ||
235 | dwords -= 8; | ||
236 | } | ||
237 | while(dwords--) { | ||
238 | radeon_fifo_wait(rinfo, 1); | ||
239 | __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0); | ||
240 | } | ||
241 | } | ||
242 | |||
171 | void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) | 243 | void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) |
172 | { | 244 | { |
173 | struct radeonfb_info *rinfo = info->par; | 245 | struct radeonfb_info *rinfo = info->par; |
246 | u32 fg, bg; | ||
174 | 247 | ||
175 | if (info->state != FBINFO_STATE_RUNNING) | 248 | WARN_ON(rinfo->gfx_mode); |
249 | if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) | ||
250 | return; | ||
251 | |||
252 | if (!image->width || !image->height) | ||
176 | return; | 253 | return; |
177 | radeon_engine_idle(); | 254 | |
255 | /* We only do 1 bpp color expansion for now */ | ||
256 | if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) | ||
257 | goto fallback; | ||
258 | |||
259 | /* Fallback if running out of the screen. We may do clipping | ||
260 | * in the future */ | ||
261 | if ((image->dx + image->width) > info->var.xres_virtual || | ||
262 | (image->dy + image->height) > info->var.yres_virtual) | ||
263 | goto fallback; | ||
264 | |||
265 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
266 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
267 | fg = ((u32*)(info->pseudo_palette))[image->fg_color]; | ||
268 | bg = ((u32*)(info->pseudo_palette))[image->bg_color]; | ||
269 | } else { | ||
270 | fg = image->fg_color; | ||
271 | bg = image->bg_color; | ||
272 | } | ||
273 | |||
274 | radeonfb_prim_imageblit(rinfo, image, fg, bg); | ||
275 | return; | ||
276 | |||
277 | fallback: | ||
278 | radeon_engine_idle(rinfo); | ||
178 | 279 | ||
179 | cfb_imageblit(info, image); | 280 | cfb_imageblit(info, image); |
180 | } | 281 | } |
@@ -185,7 +286,8 @@ int radeonfb_sync(struct fb_info *info) | |||
185 | 286 | ||
186 | if (info->state != FBINFO_STATE_RUNNING) | 287 | if (info->state != FBINFO_STATE_RUNNING) |
187 | return 0; | 288 | return 0; |
188 | radeon_engine_idle(); | 289 | |
290 | radeon_engine_idle(rinfo); | ||
189 | 291 | ||
190 | return 0; | 292 | return 0; |
191 | } | 293 | } |
@@ -211,9 +313,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo) | |||
211 | host_path_cntl = INREG(HOST_PATH_CNTL); | 313 | host_path_cntl = INREG(HOST_PATH_CNTL); |
212 | rbbm_soft_reset = INREG(RBBM_SOFT_RESET); | 314 | rbbm_soft_reset = INREG(RBBM_SOFT_RESET); |
213 | 315 | ||
214 | if (rinfo->family == CHIP_FAMILY_R300 || | 316 | if (IS_R300_VARIANT(rinfo)) { |
215 | rinfo->family == CHIP_FAMILY_R350 || | ||
216 | rinfo->family == CHIP_FAMILY_RV350) { | ||
217 | u32 tmp; | 317 | u32 tmp; |
218 | 318 | ||
219 | OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset | | 319 | OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset | |
@@ -249,9 +349,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo) | |||
249 | INREG(HOST_PATH_CNTL); | 349 | INREG(HOST_PATH_CNTL); |
250 | OUTREG(HOST_PATH_CNTL, host_path_cntl); | 350 | OUTREG(HOST_PATH_CNTL, host_path_cntl); |
251 | 351 | ||
252 | if (rinfo->family != CHIP_FAMILY_R300 && | 352 | if (!IS_R300_VARIANT(rinfo)) |
253 | rinfo->family != CHIP_FAMILY_R350 && | ||
254 | rinfo->family != CHIP_FAMILY_RV350) | ||
255 | OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); | 353 | OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); |
256 | 354 | ||
257 | OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); | 355 | OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); |
@@ -265,15 +363,24 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) | |||
265 | /* disable 3D engine */ | 363 | /* disable 3D engine */ |
266 | OUTREG(RB3D_CNTL, 0); | 364 | OUTREG(RB3D_CNTL, 0); |
267 | 365 | ||
366 | rinfo->fifo_free = 0; | ||
268 | radeonfb_engine_reset(rinfo); | 367 | radeonfb_engine_reset(rinfo); |
269 | 368 | ||
270 | radeon_fifo_wait (1); | 369 | radeon_fifo_wait(rinfo, 1); |
271 | if ((rinfo->family != CHIP_FAMILY_R300) && | 370 | if (IS_R300_VARIANT(rinfo)) { |
272 | (rinfo->family != CHIP_FAMILY_R350) && | 371 | OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) | |
273 | (rinfo->family != CHIP_FAMILY_RV350)) | 372 | RB2D_DC_AUTOFLUSH_ENABLE | |
373 | RB2D_DC_DC_DISABLE_IGNORE_PE); | ||
374 | } else { | ||
375 | /* This needs to be double checked with ATI. Latest X driver | ||
376 | * completely "forgets" to set this register on < r3xx, and | ||
377 | * we used to just write 0 there... I'll keep the 0 and update | ||
378 | * that when we have sorted things out on X side. | ||
379 | */ | ||
274 | OUTREG(RB2D_DSTCACHE_MODE, 0); | 380 | OUTREG(RB2D_DSTCACHE_MODE, 0); |
381 | } | ||
275 | 382 | ||
276 | radeon_fifo_wait (3); | 383 | radeon_fifo_wait(rinfo, 3); |
277 | /* We re-read MC_FB_LOCATION from card as it can have been | 384 | /* We re-read MC_FB_LOCATION from card as it can have been |
278 | * modified by XFree drivers (ouch !) | 385 | * modified by XFree drivers (ouch !) |
279 | */ | 386 | */ |
@@ -284,41 +391,57 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) | |||
284 | OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); | 391 | OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); |
285 | OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); | 392 | OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); |
286 | 393 | ||
287 | radeon_fifo_wait (1); | 394 | radeon_fifo_wait(rinfo, 1); |
288 | #if defined(__BIG_ENDIAN) | 395 | #ifdef __BIG_ENDIAN |
289 | OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); | 396 | OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); |
290 | #else | 397 | #else |
291 | OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); | 398 | OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); |
292 | #endif | 399 | #endif |
293 | radeon_fifo_wait (2); | 400 | radeon_fifo_wait(rinfo, 2); |
294 | OUTREG(DEFAULT_SC_TOP_LEFT, 0); | 401 | OUTREG(DEFAULT_SC_TOP_LEFT, 0); |
295 | OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | | 402 | OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | |
296 | DEFAULT_SC_BOTTOM_MAX)); | 403 | DEFAULT_SC_BOTTOM_MAX)); |
297 | 404 | ||
405 | /* set default DP_GUI_MASTER_CNTL */ | ||
298 | temp = radeon_get_dstbpp(rinfo->depth); | 406 | temp = radeon_get_dstbpp(rinfo->depth); |
299 | rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); | 407 | rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); |
300 | 408 | ||
301 | radeon_fifo_wait (1); | 409 | rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base | |
302 | OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl | | 410 | GMC_BRUSH_SOLID_COLOR | |
303 | GMC_BRUSH_SOLID_COLOR | | 411 | GMC_SRC_DATATYPE_COLOR; |
304 | GMC_SRC_DATATYPE_COLOR)); | 412 | radeon_fifo_wait(rinfo, 1); |
413 | OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache); | ||
305 | 414 | ||
306 | radeon_fifo_wait (7); | ||
307 | 415 | ||
308 | /* clear line drawing regs */ | 416 | /* clear line drawing regs */ |
417 | radeon_fifo_wait(rinfo, 2); | ||
309 | OUTREG(DST_LINE_START, 0); | 418 | OUTREG(DST_LINE_START, 0); |
310 | OUTREG(DST_LINE_END, 0); | 419 | OUTREG(DST_LINE_END, 0); |
311 | 420 | ||
312 | /* set brush color regs */ | 421 | /* set brush and source color regs */ |
313 | OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); | 422 | rinfo->dp_brush_fg_cache = 0xffffffff; |
314 | OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); | 423 | rinfo->dp_brush_bg_cache = 0x00000000; |
315 | 424 | rinfo->dp_src_fg_cache = 0xffffffff; | |
316 | /* set source color regs */ | 425 | rinfo->dp_src_bg_cache = 0x00000000; |
317 | OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); | 426 | radeon_fifo_wait(rinfo, 4); |
318 | OUTREG(DP_SRC_BKGD_CLR, 0x00000000); | 427 | OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache); |
428 | OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache); | ||
429 | OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache); | ||
430 | OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache); | ||
431 | |||
432 | /* Default direction */ | ||
433 | rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM; | ||
434 | radeon_fifo_wait(rinfo, 1); | ||
435 | OUTREG(DP_CNTL, rinfo->dp_cntl_cache); | ||
319 | 436 | ||
320 | /* default write mask */ | 437 | /* default write mask */ |
438 | radeon_fifo_wait(rinfo, 1); | ||
321 | OUTREG(DP_WRITE_MSK, 0xffffffff); | 439 | OUTREG(DP_WRITE_MSK, 0xffffffff); |
322 | 440 | ||
323 | radeon_engine_idle (); | 441 | /* Default to no swapping of host data */ |
442 | radeon_fifo_wait(rinfo, 1); | ||
443 | OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE); | ||
444 | |||
445 | /* Make sure it's settled */ | ||
446 | radeon_engine_idle(rinfo); | ||
324 | } | 447 | } |
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 1a056adb61c8..f343ba83f0ae 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c | |||
@@ -66,7 +66,7 @@ static int radeon_bl_update_status(struct backlight_device *bd) | |||
66 | level = bd->props.brightness; | 66 | level = bd->props.brightness; |
67 | 67 | ||
68 | del_timer_sync(&rinfo->lvds_timer); | 68 | del_timer_sync(&rinfo->lvds_timer); |
69 | radeon_engine_idle(); | 69 | radeon_engine_idle(rinfo); |
70 | 70 | ||
71 | lvds_gen_cntl = INREG(LVDS_GEN_CNTL); | 71 | lvds_gen_cntl = INREG(LVDS_GEN_CNTL); |
72 | if (level > 0) { | 72 | if (level > 0) { |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 652273e9f5f9..9a5821c65ebf 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -852,7 +852,6 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var, | |||
852 | if (rinfo->asleep) | 852 | if (rinfo->asleep) |
853 | return 0; | 853 | return 0; |
854 | 854 | ||
855 | radeon_fifo_wait(2); | ||
856 | OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) | 855 | OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) |
857 | * var->bits_per_pixel / 8) & ~7); | 856 | * var->bits_per_pixel / 8) & ~7); |
858 | return 0; | 857 | return 0; |
@@ -882,7 +881,6 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd, | |||
882 | if (rc) | 881 | if (rc) |
883 | return rc; | 882 | return rc; |
884 | 883 | ||
885 | radeon_fifo_wait(2); | ||
886 | if (value & 0x01) { | 884 | if (value & 0x01) { |
887 | tmp = INREG(LVDS_GEN_CNTL); | 885 | tmp = INREG(LVDS_GEN_CNTL); |
888 | 886 | ||
@@ -940,7 +938,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch) | |||
940 | if (rinfo->lock_blank) | 938 | if (rinfo->lock_blank) |
941 | return 0; | 939 | return 0; |
942 | 940 | ||
943 | radeon_engine_idle(); | 941 | radeon_engine_idle(rinfo); |
944 | 942 | ||
945 | val = INREG(CRTC_EXT_CNTL); | 943 | val = INREG(CRTC_EXT_CNTL); |
946 | val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | | 944 | val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | |
@@ -1048,7 +1046,7 @@ static int radeonfb_blank (int blank, struct fb_info *info) | |||
1048 | 1046 | ||
1049 | if (rinfo->asleep) | 1047 | if (rinfo->asleep) |
1050 | return 0; | 1048 | return 0; |
1051 | 1049 | ||
1052 | return radeon_screen_blank(rinfo, blank, 0); | 1050 | return radeon_screen_blank(rinfo, blank, 0); |
1053 | } | 1051 | } |
1054 | 1052 | ||
@@ -1074,8 +1072,6 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1074 | pindex = regno; | 1072 | pindex = regno; |
1075 | 1073 | ||
1076 | if (!rinfo->asleep) { | 1074 | if (!rinfo->asleep) { |
1077 | radeon_fifo_wait(9); | ||
1078 | |||
1079 | if (rinfo->bpp == 16) { | 1075 | if (rinfo->bpp == 16) { |
1080 | pindex = regno * 8; | 1076 | pindex = regno * 8; |
1081 | 1077 | ||
@@ -1244,8 +1240,6 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg | |||
1244 | { | 1240 | { |
1245 | int i; | 1241 | int i; |
1246 | 1242 | ||
1247 | radeon_fifo_wait(20); | ||
1248 | |||
1249 | /* Workaround from XFree */ | 1243 | /* Workaround from XFree */ |
1250 | if (rinfo->is_mobility) { | 1244 | if (rinfo->is_mobility) { |
1251 | /* A temporal workaround for the occational blanking on certain laptop | 1245 | /* A temporal workaround for the occational blanking on certain laptop |
@@ -1286,11 +1280,10 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg | |||
1286 | radeon_pll_errata_after_data(rinfo); | 1280 | radeon_pll_errata_after_data(rinfo); |
1287 | 1281 | ||
1288 | /* Set PPLL ref. div */ | 1282 | /* Set PPLL ref. div */ |
1289 | if (rinfo->family == CHIP_FAMILY_R300 || | 1283 | if (IS_R300_VARIANT(rinfo) || |
1290 | rinfo->family == CHIP_FAMILY_RS300 || | 1284 | rinfo->family == CHIP_FAMILY_RS300 || |
1291 | rinfo->family == CHIP_FAMILY_R350 || | 1285 | rinfo->family == CHIP_FAMILY_RS400 || |
1292 | rinfo->family == CHIP_FAMILY_RV350 || | 1286 | rinfo->family == CHIP_FAMILY_RS480) { |
1293 | rinfo->family == CHIP_FAMILY_RV380 ) { | ||
1294 | if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { | 1287 | if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { |
1295 | /* When restoring console mode, use saved PPLL_REF_DIV | 1288 | /* When restoring console mode, use saved PPLL_REF_DIV |
1296 | * setting. | 1289 | * setting. |
@@ -1342,7 +1335,7 @@ static void radeon_lvds_timer_func(unsigned long data) | |||
1342 | { | 1335 | { |
1343 | struct radeonfb_info *rinfo = (struct radeonfb_info *)data; | 1336 | struct radeonfb_info *rinfo = (struct radeonfb_info *)data; |
1344 | 1337 | ||
1345 | radeon_engine_idle(); | 1338 | radeon_engine_idle(rinfo); |
1346 | 1339 | ||
1347 | OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); | 1340 | OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); |
1348 | } | 1341 | } |
@@ -1360,10 +1353,11 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, | |||
1360 | if (nomodeset) | 1353 | if (nomodeset) |
1361 | return; | 1354 | return; |
1362 | 1355 | ||
1356 | radeon_engine_idle(rinfo); | ||
1357 | |||
1363 | if (!regs_only) | 1358 | if (!regs_only) |
1364 | radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); | 1359 | radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); |
1365 | 1360 | ||
1366 | radeon_fifo_wait(31); | ||
1367 | for (i=0; i<10; i++) | 1361 | for (i=0; i<10; i++) |
1368 | OUTREG(common_regs[i].reg, common_regs[i].val); | 1362 | OUTREG(common_regs[i].reg, common_regs[i].val); |
1369 | 1363 | ||
@@ -1391,7 +1385,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, | |||
1391 | radeon_write_pll_regs(rinfo, mode); | 1385 | radeon_write_pll_regs(rinfo, mode); |
1392 | 1386 | ||
1393 | if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { | 1387 | if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { |
1394 | radeon_fifo_wait(10); | ||
1395 | OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); | 1388 | OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); |
1396 | OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); | 1389 | OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); |
1397 | OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); | 1390 | OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); |
@@ -1406,7 +1399,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, | |||
1406 | if (!regs_only) | 1399 | if (!regs_only) |
1407 | radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); | 1400 | radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); |
1408 | 1401 | ||
1409 | radeon_fifo_wait(2); | ||
1410 | OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); | 1402 | OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); |
1411 | 1403 | ||
1412 | return; | 1404 | return; |
@@ -1461,10 +1453,7 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs | |||
1461 | /* Not all chip revs have the same format for this register, | 1453 | /* Not all chip revs have the same format for this register, |
1462 | * extract the source selection | 1454 | * extract the source selection |
1463 | */ | 1455 | */ |
1464 | if (rinfo->family == CHIP_FAMILY_R200 || | 1456 | if (rinfo->family == CHIP_FAMILY_R200 || IS_R300_VARIANT(rinfo)) { |
1465 | rinfo->family == CHIP_FAMILY_R300 || | ||
1466 | rinfo->family == CHIP_FAMILY_R350 || | ||
1467 | rinfo->family == CHIP_FAMILY_RV350) { | ||
1468 | source = (fp2_gen_cntl >> 10) & 0x3; | 1457 | source = (fp2_gen_cntl >> 10) & 0x3; |
1469 | /* sourced from transform unit, check for transform unit | 1458 | /* sourced from transform unit, check for transform unit |
1470 | * own source | 1459 | * own source |
@@ -1560,7 +1549,7 @@ static int radeonfb_set_par(struct fb_info *info) | |||
1560 | /* We always want engine to be idle on a mode switch, even | 1549 | /* We always want engine to be idle on a mode switch, even |
1561 | * if we won't actually change the mode | 1550 | * if we won't actually change the mode |
1562 | */ | 1551 | */ |
1563 | radeon_engine_idle(); | 1552 | radeon_engine_idle(rinfo); |
1564 | 1553 | ||
1565 | hSyncStart = mode->xres + mode->right_margin; | 1554 | hSyncStart = mode->xres + mode->right_margin; |
1566 | hSyncEnd = hSyncStart + mode->hsync_len; | 1555 | hSyncEnd = hSyncStart + mode->hsync_len; |
@@ -1855,7 +1844,6 @@ static int radeonfb_set_par(struct fb_info *info) | |||
1855 | return 0; | 1844 | return 0; |
1856 | } | 1845 | } |
1857 | 1846 | ||
1858 | |||
1859 | static struct fb_ops radeonfb_ops = { | 1847 | static struct fb_ops radeonfb_ops = { |
1860 | .owner = THIS_MODULE, | 1848 | .owner = THIS_MODULE, |
1861 | .fb_check_var = radeonfb_check_var, | 1849 | .fb_check_var = radeonfb_check_var, |
@@ -1879,6 +1867,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) | |||
1879 | info->par = rinfo; | 1867 | info->par = rinfo; |
1880 | info->pseudo_palette = rinfo->pseudo_palette; | 1868 | info->pseudo_palette = rinfo->pseudo_palette; |
1881 | info->flags = FBINFO_DEFAULT | 1869 | info->flags = FBINFO_DEFAULT |
1870 | | FBINFO_HWACCEL_IMAGEBLIT | ||
1882 | | FBINFO_HWACCEL_COPYAREA | 1871 | | FBINFO_HWACCEL_COPYAREA |
1883 | | FBINFO_HWACCEL_FILLRECT | 1872 | | FBINFO_HWACCEL_FILLRECT |
1884 | | FBINFO_HWACCEL_XPAN | 1873 | | FBINFO_HWACCEL_XPAN |
@@ -2005,11 +1994,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) | |||
2005 | (rinfo->family == CHIP_FAMILY_RS200) || | 1994 | (rinfo->family == CHIP_FAMILY_RS200) || |
2006 | (rinfo->family == CHIP_FAMILY_RS300) || | 1995 | (rinfo->family == CHIP_FAMILY_RS300) || |
2007 | (rinfo->family == CHIP_FAMILY_RC410) || | 1996 | (rinfo->family == CHIP_FAMILY_RC410) || |
1997 | (rinfo->family == CHIP_FAMILY_RS400) || | ||
2008 | (rinfo->family == CHIP_FAMILY_RS480) ) { | 1998 | (rinfo->family == CHIP_FAMILY_RS480) ) { |
2009 | u32 tom = INREG(NB_TOM); | 1999 | u32 tom = INREG(NB_TOM); |
2010 | tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); | 2000 | tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); |
2011 | 2001 | ||
2012 | radeon_fifo_wait(6); | ||
2013 | OUTREG(MC_FB_LOCATION, tom); | 2002 | OUTREG(MC_FB_LOCATION, tom); |
2014 | OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); | 2003 | OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); |
2015 | OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); | 2004 | OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); |
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index 8c8fa35f1b7c..2c5567175dca 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c | |||
@@ -139,12 +139,8 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) | |||
139 | int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, | 139 | int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, |
140 | u8 **out_edid) | 140 | u8 **out_edid) |
141 | { | 141 | { |
142 | u32 reg = rinfo->i2c[conn-1].ddc_reg; | ||
143 | u8 *edid; | 142 | u8 *edid; |
144 | 143 | ||
145 | OUTREG(reg, INREG(reg) & | ||
146 | ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT)); | ||
147 | |||
148 | edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); | 144 | edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); |
149 | 145 | ||
150 | if (out_edid) | 146 | if (out_edid) |
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 675abdafc2d8..3df5015f1d13 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c | |||
@@ -2653,9 +2653,9 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) | |||
2653 | 2653 | ||
2654 | if (!(info->flags & FBINFO_HWACCEL_DISABLED)) { | 2654 | if (!(info->flags & FBINFO_HWACCEL_DISABLED)) { |
2655 | /* Make sure engine is reset */ | 2655 | /* Make sure engine is reset */ |
2656 | radeon_engine_idle(); | 2656 | radeon_engine_idle(rinfo); |
2657 | radeonfb_engine_reset(rinfo); | 2657 | radeonfb_engine_reset(rinfo); |
2658 | radeon_engine_idle(); | 2658 | radeon_engine_idle(rinfo); |
2659 | } | 2659 | } |
2660 | 2660 | ||
2661 | /* Blank display and LCD */ | 2661 | /* Blank display and LCD */ |
@@ -2767,7 +2767,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev) | |||
2767 | 2767 | ||
2768 | rinfo->asleep = 0; | 2768 | rinfo->asleep = 0; |
2769 | } else | 2769 | } else |
2770 | radeon_engine_idle(); | 2770 | radeon_engine_idle(rinfo); |
2771 | 2771 | ||
2772 | /* Restore display & engine */ | 2772 | /* Restore display & engine */ |
2773 | radeon_write_mode (rinfo, &rinfo->state, 1); | 2773 | radeon_write_mode (rinfo, &rinfo->state, 1); |
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index ccbfffd12805..ea0b5b47acaf 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h | |||
@@ -53,6 +53,7 @@ enum radeon_family { | |||
53 | CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ | 53 | CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ |
54 | CHIP_FAMILY_R420, /* R420/R423/M18 */ | 54 | CHIP_FAMILY_R420, /* R420/R423/M18 */ |
55 | CHIP_FAMILY_RC410, | 55 | CHIP_FAMILY_RC410, |
56 | CHIP_FAMILY_RS400, | ||
56 | CHIP_FAMILY_RS480, | 57 | CHIP_FAMILY_RS480, |
57 | CHIP_FAMILY_LAST, | 58 | CHIP_FAMILY_LAST, |
58 | }; | 59 | }; |
@@ -335,7 +336,15 @@ struct radeonfb_info { | |||
335 | int mon2_type; | 336 | int mon2_type; |
336 | u8 *mon2_EDID; | 337 | u8 *mon2_EDID; |
337 | 338 | ||
338 | u32 dp_gui_master_cntl; | 339 | /* accel bits */ |
340 | u32 dp_gui_mc_base; | ||
341 | u32 dp_gui_mc_cache; | ||
342 | u32 dp_cntl_cache; | ||
343 | u32 dp_brush_fg_cache; | ||
344 | u32 dp_brush_bg_cache; | ||
345 | u32 dp_src_fg_cache; | ||
346 | u32 dp_src_bg_cache; | ||
347 | u32 fifo_free; | ||
339 | 348 | ||
340 | struct pll_info pll; | 349 | struct pll_info pll; |
341 | 350 | ||
@@ -347,6 +356,7 @@ struct radeonfb_info { | |||
347 | int lock_blank; | 356 | int lock_blank; |
348 | int dynclk; | 357 | int dynclk; |
349 | int no_schedule; | 358 | int no_schedule; |
359 | int gfx_mode; | ||
350 | enum radeon_pm_mode pm_mode; | 360 | enum radeon_pm_mode pm_mode; |
351 | reinit_function_ptr reinit_func; | 361 | reinit_function_ptr reinit_func; |
352 | 362 | ||
@@ -391,8 +401,14 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) | |||
391 | #define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) | 401 | #define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) |
392 | #define INREG16(addr) readw((rinfo->mmio_base)+addr) | 402 | #define INREG16(addr) readw((rinfo->mmio_base)+addr) |
393 | #define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr) | 403 | #define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr) |
404 | |||
405 | #ifdef CONFIG_PPC | ||
406 | #define INREG(addr) ({ eieio(); ld_le32(rinfo->mmio_base+(addr)); }) | ||
407 | #define OUTREG(addr,val) do { eieio(); st_le32(rinfo->mmio_base+(addr),(val)); } while(0) | ||
408 | #else | ||
394 | #define INREG(addr) readl((rinfo->mmio_base)+addr) | 409 | #define INREG(addr) readl((rinfo->mmio_base)+addr) |
395 | #define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) | 410 | #define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) |
411 | #endif | ||
396 | 412 | ||
397 | static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, | 413 | static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, |
398 | u32 val, u32 mask) | 414 | u32 val, u32 mask) |
@@ -533,16 +549,25 @@ static inline u32 radeon_get_dstbpp(u16 depth) | |||
533 | /* | 549 | /* |
534 | * 2D Engine helper routines | 550 | * 2D Engine helper routines |
535 | */ | 551 | */ |
552 | |||
553 | extern void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries); | ||
554 | |||
536 | static inline void radeon_engine_flush (struct radeonfb_info *rinfo) | 555 | static inline void radeon_engine_flush (struct radeonfb_info *rinfo) |
537 | { | 556 | { |
538 | int i; | 557 | int i; |
539 | 558 | ||
540 | /* initiate flush */ | 559 | /* Initiate flush */ |
541 | OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, | 560 | OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, |
542 | ~RB2D_DC_FLUSH_ALL); | 561 | ~RB2D_DC_FLUSH_ALL); |
543 | 562 | ||
563 | /* Ensure FIFO is empty, ie, make sure the flush commands | ||
564 | * has reached the cache | ||
565 | */ | ||
566 | radeon_fifo_update_and_wait(rinfo, 64); | ||
567 | |||
568 | /* Wait for the flush to complete */ | ||
544 | for (i=0; i < 2000000; i++) { | 569 | for (i=0; i < 2000000; i++) { |
545 | if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) | 570 | if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) |
546 | return; | 571 | return; |
547 | udelay(1); | 572 | udelay(1); |
548 | } | 573 | } |
@@ -550,25 +575,12 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo) | |||
550 | } | 575 | } |
551 | 576 | ||
552 | 577 | ||
553 | static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) | 578 | static inline void radeon_engine_idle(struct radeonfb_info *rinfo) |
554 | { | ||
555 | int i; | ||
556 | |||
557 | for (i=0; i<2000000; i++) { | ||
558 | if ((INREG(RBBM_STATUS) & 0x7f) >= entries) | ||
559 | return; | ||
560 | udelay(1); | ||
561 | } | ||
562 | printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); | ||
563 | } | ||
564 | |||
565 | |||
566 | static inline void _radeon_engine_idle(struct radeonfb_info *rinfo) | ||
567 | { | 579 | { |
568 | int i; | 580 | int i; |
569 | 581 | ||
570 | /* ensure FIFO is empty before waiting for idle */ | 582 | /* ensure FIFO is empty before waiting for idle */ |
571 | _radeon_fifo_wait (rinfo, 64); | 583 | radeon_fifo_update_and_wait (rinfo, 64); |
572 | 584 | ||
573 | for (i=0; i<2000000; i++) { | 585 | for (i=0; i<2000000; i++) { |
574 | if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { | 586 | if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { |
@@ -581,8 +593,6 @@ static inline void _radeon_engine_idle(struct radeonfb_info *rinfo) | |||
581 | } | 593 | } |
582 | 594 | ||
583 | 595 | ||
584 | #define radeon_engine_idle() _radeon_engine_idle(rinfo) | ||
585 | #define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) | ||
586 | #define radeon_msleep(ms) _radeon_msleep(rinfo,ms) | 596 | #define radeon_msleep(ms) _radeon_msleep(rinfo,ms) |
587 | 597 | ||
588 | 598 | ||
@@ -612,6 +622,7 @@ extern void radeonfb_imageblit(struct fb_info *p, const struct fb_image *image); | |||
612 | extern int radeonfb_sync(struct fb_info *info); | 622 | extern int radeonfb_sync(struct fb_info *info); |
613 | extern void radeonfb_engine_init (struct radeonfb_info *rinfo); | 623 | extern void radeonfb_engine_init (struct radeonfb_info *rinfo); |
614 | extern void radeonfb_engine_reset(struct radeonfb_info *rinfo); | 624 | extern void radeonfb_engine_reset(struct radeonfb_info *rinfo); |
625 | extern void radeon_fixup_mem_offset(struct radeonfb_info *rinfo); | ||
615 | 626 | ||
616 | /* Other functions */ | 627 | /* Other functions */ |
617 | extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch); | 628 | extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch); |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 452b770d8cc9..c72a13562954 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -24,6 +24,13 @@ config LCD_CLASS_DEVICE | |||
24 | To have support for your specific LCD panel you will have to | 24 | To have support for your specific LCD panel you will have to |
25 | select the proper drivers which depend on this option. | 25 | select the proper drivers which depend on this option. |
26 | 26 | ||
27 | config LCD_CORGI | ||
28 | tristate "LCD Panel support for SHARP corgi/spitz model" | ||
29 | depends on LCD_CLASS_DEVICE && SPI_MASTER && PXA_SHARPSL | ||
30 | help | ||
31 | Say y here to support the LCD panels usually found on SHARP | ||
32 | corgi (C7x0) and spitz (Cxx00) models. | ||
33 | |||
27 | config LCD_LTV350QV | 34 | config LCD_LTV350QV |
28 | tristate "Samsung LTV350QV LCD Panel" | 35 | tristate "Samsung LTV350QV LCD Panel" |
29 | depends on LCD_CLASS_DEVICE && SPI_MASTER | 36 | depends on LCD_CLASS_DEVICE && SPI_MASTER |
@@ -44,6 +51,14 @@ config LCD_ILI9320 | |||
44 | If you have a panel based on the ILI9320 controller chip | 51 | If you have a panel based on the ILI9320 controller chip |
45 | then say y to include a power driver for it. | 52 | then say y to include a power driver for it. |
46 | 53 | ||
54 | config LCD_TDO24M | ||
55 | tristate "Toppoly TDO24M LCD Panels support" | ||
56 | depends on LCD_CLASS_DEVICE && SPI_MASTER | ||
57 | default n | ||
58 | help | ||
59 | If you have a Toppoly TDO24M series LCD panel, say y here to | ||
60 | include the support for it. | ||
61 | |||
47 | config LCD_VGG2432A4 | 62 | config LCD_VGG2432A4 |
48 | tristate "VGG2432A4 LCM device support" | 63 | tristate "VGG2432A4 LCM device support" |
49 | depends on BACKLIGHT_LCD_SUPPORT && LCD_CLASS_DEVICE && SPI_MASTER | 64 | depends on BACKLIGHT_LCD_SUPPORT && LCD_CLASS_DEVICE && SPI_MASTER |
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index b405aace803f..3ec551eb472c 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -1,10 +1,12 @@ | |||
1 | # Backlight & LCD drivers | 1 | # Backlight & LCD drivers |
2 | 2 | ||
3 | obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o | 3 | obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o |
4 | obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o | ||
4 | obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o | 5 | obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o |
5 | obj-$(CONFIG_LCD_ILI9320) += ili9320.o | 6 | obj-$(CONFIG_LCD_ILI9320) += ili9320.o |
6 | obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o | 7 | obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o |
7 | obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o | 8 | obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o |
9 | obj-$(CONFIG_LCD_TDO24M) += tdo24m.o | ||
8 | 10 | ||
9 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o | 11 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o |
10 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o | 12 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o |
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c new file mode 100644 index 000000000000..2afd47eefe74 --- /dev/null +++ b/drivers/video/backlight/corgi_lcd.c | |||
@@ -0,0 +1,641 @@ | |||
1 | /* | ||
2 | * LCD/Backlight Driver for Sharp Zaurus Handhelds (various models) | ||
3 | * | ||
4 | * Copyright (c) 2004-2006 Richard Purdie | ||
5 | * | ||
6 | * Based on Sharp's 2.4 Backlight Driver | ||
7 | * | ||
8 | * Copyright (c) 2008 Marvell International Ltd. | ||
9 | * Converted to SPI device based LCD/Backlight device driver | ||
10 | * by Eric Miao <eric.miao@marvell.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/fb.h> | ||
24 | #include <linux/lcd.h> | ||
25 | #include <linux/spi/spi.h> | ||
26 | #include <linux/spi/corgi_lcd.h> | ||
27 | #include <asm/mach/sharpsl_param.h> | ||
28 | |||
29 | #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) | ||
30 | |||
31 | /* Register Addresses */ | ||
32 | #define RESCTL_ADRS 0x00 | ||
33 | #define PHACTRL_ADRS 0x01 | ||
34 | #define DUTYCTRL_ADRS 0x02 | ||
35 | #define POWERREG0_ADRS 0x03 | ||
36 | #define POWERREG1_ADRS 0x04 | ||
37 | #define GPOR3_ADRS 0x05 | ||
38 | #define PICTRL_ADRS 0x06 | ||
39 | #define POLCTRL_ADRS 0x07 | ||
40 | |||
41 | /* Register Bit Definitions */ | ||
42 | #define RESCTL_QVGA 0x01 | ||
43 | #define RESCTL_VGA 0x00 | ||
44 | |||
45 | #define POWER1_VW_ON 0x01 /* VW Supply FET ON */ | ||
46 | #define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */ | ||
47 | #define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */ | ||
48 | |||
49 | #define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */ | ||
50 | #define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */ | ||
51 | #define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */ | ||
52 | |||
53 | #define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */ | ||
54 | #define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */ | ||
55 | #define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */ | ||
56 | #define POWER0_COM_ON 0x08 /* COM Power Supply ON */ | ||
57 | #define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */ | ||
58 | |||
59 | #define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */ | ||
60 | #define POWER0_COM_OFF 0x00 /* COM Power Supply OFF */ | ||
61 | #define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */ | ||
62 | |||
63 | #define PICTRL_INIT_STATE 0x01 | ||
64 | #define PICTRL_INIOFF 0x02 | ||
65 | #define PICTRL_POWER_DOWN 0x04 | ||
66 | #define PICTRL_COM_SIGNAL_OFF 0x08 | ||
67 | #define PICTRL_DAC_SIGNAL_OFF 0x10 | ||
68 | |||
69 | #define POLCTRL_SYNC_POL_FALL 0x01 | ||
70 | #define POLCTRL_EN_POL_FALL 0x02 | ||
71 | #define POLCTRL_DATA_POL_FALL 0x04 | ||
72 | #define POLCTRL_SYNC_ACT_H 0x08 | ||
73 | #define POLCTRL_EN_ACT_L 0x10 | ||
74 | |||
75 | #define POLCTRL_SYNC_POL_RISE 0x00 | ||
76 | #define POLCTRL_EN_POL_RISE 0x00 | ||
77 | #define POLCTRL_DATA_POL_RISE 0x00 | ||
78 | #define POLCTRL_SYNC_ACT_L 0x00 | ||
79 | #define POLCTRL_EN_ACT_H 0x00 | ||
80 | |||
81 | #define PHACTRL_PHASE_MANUAL 0x01 | ||
82 | #define DEFAULT_PHAD_QVGA (9) | ||
83 | #define DEFAULT_COMADJ (125) | ||
84 | |||
85 | struct corgi_lcd { | ||
86 | struct spi_device *spi_dev; | ||
87 | struct lcd_device *lcd_dev; | ||
88 | struct backlight_device *bl_dev; | ||
89 | |||
90 | int limit_mask; | ||
91 | int intensity; | ||
92 | int power; | ||
93 | int mode; | ||
94 | char buf[2]; | ||
95 | |||
96 | int gpio_backlight_on; | ||
97 | int gpio_backlight_cont; | ||
98 | int gpio_backlight_cont_inverted; | ||
99 | |||
100 | void (*kick_battery)(void); | ||
101 | }; | ||
102 | |||
103 | static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int reg, uint8_t val); | ||
104 | |||
105 | static struct corgi_lcd *the_corgi_lcd; | ||
106 | static unsigned long corgibl_flags; | ||
107 | #define CORGIBL_SUSPENDED 0x01 | ||
108 | #define CORGIBL_BATTLOW 0x02 | ||
109 | |||
110 | /* | ||
111 | * This is only a psuedo I2C interface. We can't use the standard kernel | ||
112 | * routines as the interface is write only. We just assume the data is acked... | ||
113 | */ | ||
114 | static void lcdtg_ssp_i2c_send(struct corgi_lcd *lcd, uint8_t data) | ||
115 | { | ||
116 | corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, data); | ||
117 | udelay(10); | ||
118 | } | ||
119 | |||
120 | static void lcdtg_i2c_send_bit(struct corgi_lcd *lcd, uint8_t data) | ||
121 | { | ||
122 | lcdtg_ssp_i2c_send(lcd, data); | ||
123 | lcdtg_ssp_i2c_send(lcd, data | POWER0_COM_DCLK); | ||
124 | lcdtg_ssp_i2c_send(lcd, data); | ||
125 | } | ||
126 | |||
127 | static void lcdtg_i2c_send_start(struct corgi_lcd *lcd, uint8_t base) | ||
128 | { | ||
129 | lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT); | ||
130 | lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK); | ||
131 | lcdtg_ssp_i2c_send(lcd, base); | ||
132 | } | ||
133 | |||
134 | static void lcdtg_i2c_send_stop(struct corgi_lcd *lcd, uint8_t base) | ||
135 | { | ||
136 | lcdtg_ssp_i2c_send(lcd, base); | ||
137 | lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK); | ||
138 | lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT); | ||
139 | } | ||
140 | |||
141 | static void lcdtg_i2c_send_byte(struct corgi_lcd *lcd, | ||
142 | uint8_t base, uint8_t data) | ||
143 | { | ||
144 | int i; | ||
145 | for (i = 0; i < 8; i++) { | ||
146 | if (data & 0x80) | ||
147 | lcdtg_i2c_send_bit(lcd, base | POWER0_COM_DOUT); | ||
148 | else | ||
149 | lcdtg_i2c_send_bit(lcd, base); | ||
150 | data <<= 1; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | static void lcdtg_i2c_wait_ack(struct corgi_lcd *lcd, uint8_t base) | ||
155 | { | ||
156 | lcdtg_i2c_send_bit(lcd, base); | ||
157 | } | ||
158 | |||
159 | static void lcdtg_set_common_voltage(struct corgi_lcd *lcd, | ||
160 | uint8_t base_data, uint8_t data) | ||
161 | { | ||
162 | /* Set Common Voltage to M62332FP via I2C */ | ||
163 | lcdtg_i2c_send_start(lcd, base_data); | ||
164 | lcdtg_i2c_send_byte(lcd, base_data, 0x9c); | ||
165 | lcdtg_i2c_wait_ack(lcd, base_data); | ||
166 | lcdtg_i2c_send_byte(lcd, base_data, 0x00); | ||
167 | lcdtg_i2c_wait_ack(lcd, base_data); | ||
168 | lcdtg_i2c_send_byte(lcd, base_data, data); | ||
169 | lcdtg_i2c_wait_ack(lcd, base_data); | ||
170 | lcdtg_i2c_send_stop(lcd, base_data); | ||
171 | } | ||
172 | |||
173 | static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int adrs, uint8_t data) | ||
174 | { | ||
175 | struct spi_message msg; | ||
176 | struct spi_transfer xfer = { | ||
177 | .len = 1, | ||
178 | .cs_change = 1, | ||
179 | .tx_buf = lcd->buf, | ||
180 | }; | ||
181 | |||
182 | lcd->buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f); | ||
183 | spi_message_init(&msg); | ||
184 | spi_message_add_tail(&xfer, &msg); | ||
185 | |||
186 | return spi_sync(lcd->spi_dev, &msg); | ||
187 | } | ||
188 | |||
189 | /* Set Phase Adjust */ | ||
190 | static void lcdtg_set_phadadj(struct corgi_lcd *lcd, int mode) | ||
191 | { | ||
192 | int adj; | ||
193 | |||
194 | switch(mode) { | ||
195 | case CORGI_LCD_MODE_VGA: | ||
196 | /* Setting for VGA */ | ||
197 | adj = sharpsl_param.phadadj; | ||
198 | adj = (adj < 0) ? PHACTRL_PHASE_MANUAL : | ||
199 | PHACTRL_PHASE_MANUAL | ((adj & 0xf) << 1); | ||
200 | break; | ||
201 | case CORGI_LCD_MODE_QVGA: | ||
202 | default: | ||
203 | /* Setting for QVGA */ | ||
204 | adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL; | ||
205 | break; | ||
206 | } | ||
207 | |||
208 | corgi_ssp_lcdtg_send(lcd, PHACTRL_ADRS, adj); | ||
209 | } | ||
210 | |||
211 | static void corgi_lcd_power_on(struct corgi_lcd *lcd) | ||
212 | { | ||
213 | int comadj; | ||
214 | |||
215 | /* Initialize Internal Logic & Port */ | ||
216 | corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, | ||
217 | PICTRL_POWER_DOWN | PICTRL_INIOFF | | ||
218 | PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF | | ||
219 | PICTRL_DAC_SIGNAL_OFF); | ||
220 | |||
221 | corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, | ||
222 | POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF | | ||
223 | POWER0_COM_OFF | POWER0_VCC5_OFF); | ||
224 | |||
225 | corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, | ||
226 | POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); | ||
227 | |||
228 | /* VDD(+8V), SVSS(-4V) ON */ | ||
229 | corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, | ||
230 | POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); | ||
231 | mdelay(3); | ||
232 | |||
233 | /* DAC ON */ | ||
234 | corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, | ||
235 | POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON | | ||
236 | POWER0_COM_OFF | POWER0_VCC5_OFF); | ||
237 | |||
238 | /* INIB = H, INI = L */ | ||
239 | /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */ | ||
240 | corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, | ||
241 | PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF); | ||
242 | |||
243 | /* Set Common Voltage */ | ||
244 | comadj = sharpsl_param.comadj; | ||
245 | if (comadj < 0) | ||
246 | comadj = DEFAULT_COMADJ; | ||
247 | |||
248 | lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF | | ||
249 | POWER0_VCC5_OFF, comadj); | ||
250 | |||
251 | /* VCC5 ON, DAC ON */ | ||
252 | corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, | ||
253 | POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON | | ||
254 | POWER0_COM_OFF | POWER0_VCC5_ON); | ||
255 | |||
256 | /* GVSS(-8V) ON, VDD ON */ | ||
257 | corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, | ||
258 | POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); | ||
259 | mdelay(2); | ||
260 | |||
261 | /* COM SIGNAL ON (PICTL[3] = L) */ | ||
262 | corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_INIT_STATE); | ||
263 | |||
264 | /* COM ON, DAC ON, VCC5_ON */ | ||
265 | corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, | ||
266 | POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON | | ||
267 | POWER0_COM_ON | POWER0_VCC5_ON); | ||
268 | |||
269 | /* VW ON, GVSS ON, VDD ON */ | ||
270 | corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, | ||
271 | POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON); | ||
272 | |||
273 | /* Signals output enable */ | ||
274 | corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, 0); | ||
275 | |||
276 | /* Set Phase Adjust */ | ||
277 | lcdtg_set_phadadj(lcd, lcd->mode); | ||
278 | |||
279 | /* Initialize for Input Signals from ATI */ | ||
280 | corgi_ssp_lcdtg_send(lcd, POLCTRL_ADRS, | ||
281 | POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE | | ||
282 | POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | | ||
283 | POLCTRL_EN_ACT_H); | ||
284 | udelay(1000); | ||
285 | |||
286 | switch (lcd->mode) { | ||
287 | case CORGI_LCD_MODE_VGA: | ||
288 | corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA); | ||
289 | break; | ||
290 | case CORGI_LCD_MODE_QVGA: | ||
291 | default: | ||
292 | corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA); | ||
293 | break; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | static void corgi_lcd_power_off(struct corgi_lcd *lcd) | ||
298 | { | ||
299 | /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */ | ||
300 | msleep(34); | ||
301 | |||
302 | /* (1)VW OFF */ | ||
303 | corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, | ||
304 | POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); | ||
305 | |||
306 | /* (2)COM OFF */ | ||
307 | corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF); | ||
308 | corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, | ||
309 | POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON); | ||
310 | |||
311 | /* (3)Set Common Voltage Bias 0V */ | ||
312 | lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF | | ||
313 | POWER0_VCC5_ON, 0); | ||
314 | |||
315 | /* (4)GVSS OFF */ | ||
316 | corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, | ||
317 | POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); | ||
318 | |||
319 | /* (5)VCC5 OFF */ | ||
320 | corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, | ||
321 | POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF); | ||
322 | |||
323 | /* (6)Set PDWN, INIOFF, DACOFF */ | ||
324 | corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, | ||
325 | PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF | | ||
326 | PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF); | ||
327 | |||
328 | /* (7)DAC OFF */ | ||
329 | corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, | ||
330 | POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF); | ||
331 | |||
332 | /* (8)VDD OFF */ | ||
333 | corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, | ||
334 | POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); | ||
335 | } | ||
336 | |||
337 | static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m) | ||
338 | { | ||
339 | struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); | ||
340 | int mode = CORGI_LCD_MODE_QVGA; | ||
341 | |||
342 | if (m->xres == 640 || m->xres == 480) | ||
343 | mode = CORGI_LCD_MODE_VGA; | ||
344 | |||
345 | if (lcd->mode == mode) | ||
346 | return 0; | ||
347 | |||
348 | lcdtg_set_phadadj(lcd, mode); | ||
349 | |||
350 | switch (mode) { | ||
351 | case CORGI_LCD_MODE_VGA: | ||
352 | corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA); | ||
353 | break; | ||
354 | case CORGI_LCD_MODE_QVGA: | ||
355 | default: | ||
356 | corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA); | ||
357 | break; | ||
358 | } | ||
359 | |||
360 | lcd->mode = mode; | ||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static int corgi_lcd_set_power(struct lcd_device *ld, int power) | ||
365 | { | ||
366 | struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); | ||
367 | |||
368 | if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power)) | ||
369 | corgi_lcd_power_on(lcd); | ||
370 | |||
371 | if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power)) | ||
372 | corgi_lcd_power_off(lcd); | ||
373 | |||
374 | lcd->power = power; | ||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | static int corgi_lcd_get_power(struct lcd_device *ld) | ||
379 | { | ||
380 | struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); | ||
381 | |||
382 | return lcd->power; | ||
383 | } | ||
384 | |||
385 | static struct lcd_ops corgi_lcd_ops = { | ||
386 | .get_power = corgi_lcd_get_power, | ||
387 | .set_power = corgi_lcd_set_power, | ||
388 | .set_mode = corgi_lcd_set_mode, | ||
389 | }; | ||
390 | |||
391 | static int corgi_bl_get_intensity(struct backlight_device *bd) | ||
392 | { | ||
393 | struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev); | ||
394 | |||
395 | return lcd->intensity; | ||
396 | } | ||
397 | |||
398 | static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity) | ||
399 | { | ||
400 | int cont; | ||
401 | |||
402 | if (intensity > 0x10) | ||
403 | intensity += 0x10; | ||
404 | |||
405 | corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity); | ||
406 | |||
407 | /* Bit 5 via GPIO_BACKLIGHT_CONT */ | ||
408 | cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted; | ||
409 | |||
410 | if (gpio_is_valid(lcd->gpio_backlight_cont)) | ||
411 | gpio_set_value(lcd->gpio_backlight_cont, cont); | ||
412 | |||
413 | if (gpio_is_valid(lcd->gpio_backlight_on)) | ||
414 | gpio_set_value(lcd->gpio_backlight_on, intensity); | ||
415 | |||
416 | if (lcd->kick_battery) | ||
417 | lcd->kick_battery(); | ||
418 | |||
419 | lcd->intensity = intensity; | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int corgi_bl_update_status(struct backlight_device *bd) | ||
424 | { | ||
425 | struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev); | ||
426 | int intensity = bd->props.brightness; | ||
427 | |||
428 | if (bd->props.power != FB_BLANK_UNBLANK) | ||
429 | intensity = 0; | ||
430 | |||
431 | if (bd->props.fb_blank != FB_BLANK_UNBLANK) | ||
432 | intensity = 0; | ||
433 | |||
434 | if (corgibl_flags & CORGIBL_SUSPENDED) | ||
435 | intensity = 0; | ||
436 | if (corgibl_flags & CORGIBL_BATTLOW) | ||
437 | intensity &= lcd->limit_mask; | ||
438 | |||
439 | return corgi_bl_set_intensity(lcd, intensity); | ||
440 | } | ||
441 | |||
442 | void corgibl_limit_intensity(int limit) | ||
443 | { | ||
444 | if (limit) | ||
445 | corgibl_flags |= CORGIBL_BATTLOW; | ||
446 | else | ||
447 | corgibl_flags &= ~CORGIBL_BATTLOW; | ||
448 | |||
449 | backlight_update_status(the_corgi_lcd->bl_dev); | ||
450 | } | ||
451 | EXPORT_SYMBOL(corgibl_limit_intensity); | ||
452 | |||
453 | static struct backlight_ops corgi_bl_ops = { | ||
454 | .get_brightness = corgi_bl_get_intensity, | ||
455 | .update_status = corgi_bl_update_status, | ||
456 | }; | ||
457 | |||
458 | #ifdef CONFIG_PM | ||
459 | static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state) | ||
460 | { | ||
461 | struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); | ||
462 | |||
463 | corgibl_flags |= CORGIBL_SUSPENDED; | ||
464 | corgi_bl_set_intensity(lcd, 0); | ||
465 | corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); | ||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | static int corgi_lcd_resume(struct spi_device *spi) | ||
470 | { | ||
471 | struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); | ||
472 | |||
473 | corgibl_flags &= ~CORGIBL_SUSPENDED; | ||
474 | corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK); | ||
475 | backlight_update_status(lcd->bl_dev); | ||
476 | return 0; | ||
477 | } | ||
478 | #else | ||
479 | #define corgi_lcd_suspend NULL | ||
480 | #define corgi_lcd_resume NULL | ||
481 | #endif | ||
482 | |||
483 | static int setup_gpio_backlight(struct corgi_lcd *lcd, | ||
484 | struct corgi_lcd_platform_data *pdata) | ||
485 | { | ||
486 | struct spi_device *spi = lcd->spi_dev; | ||
487 | int err; | ||
488 | |||
489 | lcd->gpio_backlight_on = -1; | ||
490 | lcd->gpio_backlight_cont = -1; | ||
491 | |||
492 | if (gpio_is_valid(pdata->gpio_backlight_on)) { | ||
493 | err = gpio_request(pdata->gpio_backlight_on, "BL_ON"); | ||
494 | if (err) { | ||
495 | dev_err(&spi->dev, "failed to request GPIO%d for " | ||
496 | "backlight_on\n", pdata->gpio_backlight_on); | ||
497 | return err; | ||
498 | } | ||
499 | |||
500 | lcd->gpio_backlight_on = pdata->gpio_backlight_on; | ||
501 | gpio_direction_output(lcd->gpio_backlight_on, 0); | ||
502 | } | ||
503 | |||
504 | if (gpio_is_valid(pdata->gpio_backlight_cont)) { | ||
505 | err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT"); | ||
506 | if (err) { | ||
507 | dev_err(&spi->dev, "failed to request GPIO%d for " | ||
508 | "backlight_cont\n", pdata->gpio_backlight_cont); | ||
509 | goto err_free_backlight_on; | ||
510 | } | ||
511 | |||
512 | lcd->gpio_backlight_cont = pdata->gpio_backlight_cont; | ||
513 | |||
514 | /* spitz and akita use both GPIOs for backlight, and | ||
515 | * have inverted polarity of GPIO_BACKLIGHT_CONT | ||
516 | */ | ||
517 | if (gpio_is_valid(lcd->gpio_backlight_on)) { | ||
518 | lcd->gpio_backlight_cont_inverted = 1; | ||
519 | gpio_direction_output(lcd->gpio_backlight_cont, 1); | ||
520 | } else { | ||
521 | lcd->gpio_backlight_cont_inverted = 0; | ||
522 | gpio_direction_output(lcd->gpio_backlight_cont, 0); | ||
523 | } | ||
524 | } | ||
525 | return 0; | ||
526 | |||
527 | err_free_backlight_on: | ||
528 | if (gpio_is_valid(lcd->gpio_backlight_on)) | ||
529 | gpio_free(lcd->gpio_backlight_on); | ||
530 | return err; | ||
531 | } | ||
532 | |||
533 | static int __devinit corgi_lcd_probe(struct spi_device *spi) | ||
534 | { | ||
535 | struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; | ||
536 | struct corgi_lcd *lcd; | ||
537 | int ret = 0; | ||
538 | |||
539 | if (pdata == NULL) { | ||
540 | dev_err(&spi->dev, "platform data not available\n"); | ||
541 | return -EINVAL; | ||
542 | } | ||
543 | |||
544 | lcd = kzalloc(sizeof(struct corgi_lcd), GFP_KERNEL); | ||
545 | if (!lcd) { | ||
546 | dev_err(&spi->dev, "failed to allocate memory\n"); | ||
547 | return -ENOMEM; | ||
548 | } | ||
549 | |||
550 | lcd->spi_dev = spi; | ||
551 | |||
552 | lcd->lcd_dev = lcd_device_register("corgi_lcd", &spi->dev, | ||
553 | lcd, &corgi_lcd_ops); | ||
554 | if (IS_ERR(lcd->lcd_dev)) { | ||
555 | ret = PTR_ERR(lcd->lcd_dev); | ||
556 | goto err_free_lcd; | ||
557 | } | ||
558 | lcd->power = FB_BLANK_POWERDOWN; | ||
559 | lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; | ||
560 | |||
561 | lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, | ||
562 | lcd, &corgi_bl_ops); | ||
563 | if (IS_ERR(lcd->bl_dev)) { | ||
564 | ret = PTR_ERR(lcd->bl_dev); | ||
565 | goto err_unregister_lcd; | ||
566 | } | ||
567 | lcd->bl_dev->props.max_brightness = pdata->max_intensity; | ||
568 | lcd->bl_dev->props.brightness = pdata->default_intensity; | ||
569 | lcd->bl_dev->props.power = FB_BLANK_UNBLANK; | ||
570 | |||
571 | ret = setup_gpio_backlight(lcd, pdata); | ||
572 | if (ret) | ||
573 | goto err_unregister_bl; | ||
574 | |||
575 | lcd->kick_battery = pdata->kick_battery; | ||
576 | |||
577 | dev_set_drvdata(&spi->dev, lcd); | ||
578 | corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK); | ||
579 | backlight_update_status(lcd->bl_dev); | ||
580 | |||
581 | lcd->limit_mask = pdata->limit_mask; | ||
582 | the_corgi_lcd = lcd; | ||
583 | return 0; | ||
584 | |||
585 | err_unregister_bl: | ||
586 | backlight_device_unregister(lcd->bl_dev); | ||
587 | err_unregister_lcd: | ||
588 | lcd_device_unregister(lcd->lcd_dev); | ||
589 | err_free_lcd: | ||
590 | kfree(lcd); | ||
591 | return ret; | ||
592 | } | ||
593 | |||
594 | static int __devexit corgi_lcd_remove(struct spi_device *spi) | ||
595 | { | ||
596 | struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); | ||
597 | |||
598 | lcd->bl_dev->props.power = FB_BLANK_UNBLANK; | ||
599 | lcd->bl_dev->props.brightness = 0; | ||
600 | backlight_update_status(lcd->bl_dev); | ||
601 | backlight_device_unregister(lcd->bl_dev); | ||
602 | |||
603 | if (gpio_is_valid(lcd->gpio_backlight_on)) | ||
604 | gpio_free(lcd->gpio_backlight_on); | ||
605 | |||
606 | if (gpio_is_valid(lcd->gpio_backlight_cont)) | ||
607 | gpio_free(lcd->gpio_backlight_cont); | ||
608 | |||
609 | corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); | ||
610 | lcd_device_unregister(lcd->lcd_dev); | ||
611 | kfree(lcd); | ||
612 | |||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static struct spi_driver corgi_lcd_driver = { | ||
617 | .driver = { | ||
618 | .name = "corgi-lcd", | ||
619 | .owner = THIS_MODULE, | ||
620 | }, | ||
621 | .probe = corgi_lcd_probe, | ||
622 | .remove = __devexit_p(corgi_lcd_remove), | ||
623 | .suspend = corgi_lcd_suspend, | ||
624 | .resume = corgi_lcd_resume, | ||
625 | }; | ||
626 | |||
627 | static int __init corgi_lcd_init(void) | ||
628 | { | ||
629 | return spi_register_driver(&corgi_lcd_driver); | ||
630 | } | ||
631 | module_init(corgi_lcd_init); | ||
632 | |||
633 | static void __exit corgi_lcd_exit(void) | ||
634 | { | ||
635 | spi_unregister_driver(&corgi_lcd_driver); | ||
636 | } | ||
637 | module_exit(corgi_lcd_exit); | ||
638 | |||
639 | MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00"); | ||
640 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); | ||
641 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index b15b2b84a6f7..8e1731d3b228 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -27,14 +27,26 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
27 | struct fb_event *evdata = data; | 27 | struct fb_event *evdata = data; |
28 | 28 | ||
29 | /* If we aren't interested in this event, skip it immediately ... */ | 29 | /* If we aren't interested in this event, skip it immediately ... */ |
30 | if (event != FB_EVENT_BLANK) | 30 | switch (event) { |
31 | case FB_EVENT_BLANK: | ||
32 | case FB_EVENT_MODE_CHANGE: | ||
33 | case FB_EVENT_MODE_CHANGE_ALL: | ||
34 | break; | ||
35 | default: | ||
31 | return 0; | 36 | return 0; |
37 | } | ||
32 | 38 | ||
33 | ld = container_of(self, struct lcd_device, fb_notif); | 39 | ld = container_of(self, struct lcd_device, fb_notif); |
40 | if (!ld->ops) | ||
41 | return 0; | ||
42 | |||
34 | mutex_lock(&ld->ops_lock); | 43 | mutex_lock(&ld->ops_lock); |
35 | if (ld->ops) | 44 | if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { |
36 | if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) | 45 | if (event == FB_EVENT_BLANK) |
37 | ld->ops->set_power(ld, *(int *)evdata->data); | 46 | ld->ops->set_power(ld, *(int *)evdata->data); |
47 | else | ||
48 | ld->ops->set_mode(ld, evdata->data); | ||
49 | } | ||
38 | mutex_unlock(&ld->ops_lock); | 50 | mutex_unlock(&ld->ops_lock); |
39 | return 0; | 51 | return 0; |
40 | } | 52 | } |
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 385cba40ea87..06964af761c6 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c | |||
@@ -111,6 +111,4 @@ module_exit(mbp_exit); | |||
111 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | 111 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); |
112 | MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver"); | 112 | MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver"); |
113 | MODULE_LICENSE("GPL"); | 113 | MODULE_LICENSE("GPL"); |
114 | MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,1"); | 114 | MODULE_DEVICE_TABLE(dmi, mbp_device_table); |
115 | MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,2"); | ||
116 | MODULE_ALIAS("svnAppleInc.:pnMacBookPro4,1"); | ||
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c new file mode 100644 index 000000000000..8427669162ea --- /dev/null +++ b/drivers/video/backlight/tdo24m.c | |||
@@ -0,0 +1,396 @@ | |||
1 | /* | ||
2 | * tdo24m - SPI-based drivers for Toppoly TDO24M series LCD panels | ||
3 | * | ||
4 | * Copyright (C) 2008 Marvell International Ltd. | ||
5 | * Eric Miao <eric.miao@marvell.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * publishhed by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/spi/spi.h> | ||
17 | #include <linux/fb.h> | ||
18 | #include <linux/lcd.h> | ||
19 | |||
20 | #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) | ||
21 | |||
22 | #define TDO24M_SPI_BUFF_SIZE (4) | ||
23 | #define MODE_QVGA 0 | ||
24 | #define MODE_VGA 1 | ||
25 | |||
26 | struct tdo24m { | ||
27 | struct spi_device *spi_dev; | ||
28 | struct lcd_device *lcd_dev; | ||
29 | |||
30 | struct spi_message msg; | ||
31 | struct spi_transfer xfer; | ||
32 | uint8_t *buf; | ||
33 | |||
34 | int power; | ||
35 | int mode; | ||
36 | }; | ||
37 | |||
38 | /* use bit 30, 31 as the indicator of command parameter number */ | ||
39 | #define CMD0(x) ((0 << 30) | (x)) | ||
40 | #define CMD1(x, x1) ((1 << 30) | ((x) << 9) | 0x100 | (x1)) | ||
41 | #define CMD2(x, x1, x2) ((2 << 30) | ((x) << 18) | 0x20000 |\ | ||
42 | ((x1) << 9) | 0x100 | (x2)) | ||
43 | #define CMD_NULL (-1) | ||
44 | |||
45 | static uint32_t lcd_panel_reset[] = { | ||
46 | CMD0(0x1), /* reset */ | ||
47 | CMD0(0x0), /* nop */ | ||
48 | CMD0(0x0), /* nop */ | ||
49 | CMD0(0x0), /* nop */ | ||
50 | CMD_NULL, | ||
51 | }; | ||
52 | |||
53 | static uint32_t lcd_panel_on[] = { | ||
54 | CMD0(0x29), /* Display ON */ | ||
55 | CMD2(0xB8, 0xFF, 0xF9), /* Output Control */ | ||
56 | CMD0(0x11), /* Sleep out */ | ||
57 | CMD1(0xB0, 0x16), /* Wake */ | ||
58 | CMD_NULL, | ||
59 | }; | ||
60 | |||
61 | static uint32_t lcd_panel_off[] = { | ||
62 | CMD0(0x28), /* Display OFF */ | ||
63 | CMD2(0xB8, 0x80, 0x02), /* Output Control */ | ||
64 | CMD0(0x10), /* Sleep in */ | ||
65 | CMD1(0xB0, 0x00), /* Deep stand by in */ | ||
66 | CMD_NULL, | ||
67 | }; | ||
68 | |||
69 | static uint32_t lcd_vga_pass_through[] = { | ||
70 | CMD1(0xB0, 0x16), | ||
71 | CMD1(0xBC, 0x80), | ||
72 | CMD1(0xE1, 0x00), | ||
73 | CMD1(0x36, 0x50), | ||
74 | CMD1(0x3B, 0x00), | ||
75 | CMD_NULL, | ||
76 | }; | ||
77 | |||
78 | static uint32_t lcd_qvga_pass_through[] = { | ||
79 | CMD1(0xB0, 0x16), | ||
80 | CMD1(0xBC, 0x81), | ||
81 | CMD1(0xE1, 0x00), | ||
82 | CMD1(0x36, 0x50), | ||
83 | CMD1(0x3B, 0x22), | ||
84 | CMD_NULL, | ||
85 | }; | ||
86 | |||
87 | static uint32_t lcd_vga_transfer[] = { | ||
88 | CMD1(0xcf, 0x02), /* Blanking period control (1) */ | ||
89 | CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */ | ||
90 | CMD1(0xd1, 0x01), /* CKV timing control on/off */ | ||
91 | CMD2(0xd2, 0x14, 0x00), /* CKV 1,2 timing control */ | ||
92 | CMD2(0xd3, 0x1a, 0x0f), /* OEV timing control */ | ||
93 | CMD2(0xd4, 0x1f, 0xaf), /* ASW timing control (1) */ | ||
94 | CMD1(0xd5, 0x14), /* ASW timing control (2) */ | ||
95 | CMD0(0x21), /* Invert for normally black display */ | ||
96 | CMD0(0x29), /* Display on */ | ||
97 | CMD_NULL, | ||
98 | }; | ||
99 | |||
100 | static uint32_t lcd_qvga_transfer[] = { | ||
101 | CMD1(0xd6, 0x02), /* Blanking period control (1) */ | ||
102 | CMD2(0xd7, 0x08, 0x04), /* Blanking period control (2) */ | ||
103 | CMD1(0xd8, 0x01), /* CKV timing control on/off */ | ||
104 | CMD2(0xd9, 0x00, 0x08), /* CKV 1,2 timing control */ | ||
105 | CMD2(0xde, 0x05, 0x0a), /* OEV timing control */ | ||
106 | CMD2(0xdf, 0x0a, 0x19), /* ASW timing control (1) */ | ||
107 | CMD1(0xe0, 0x0a), /* ASW timing control (2) */ | ||
108 | CMD0(0x21), /* Invert for normally black display */ | ||
109 | CMD0(0x29), /* Display on */ | ||
110 | CMD_NULL, | ||
111 | }; | ||
112 | |||
113 | static uint32_t lcd_panel_config[] = { | ||
114 | CMD2(0xb8, 0xff, 0xf9), /* Output control */ | ||
115 | CMD0(0x11), /* sleep out */ | ||
116 | CMD1(0xba, 0x01), /* Display mode (1) */ | ||
117 | CMD1(0xbb, 0x00), /* Display mode (2) */ | ||
118 | CMD1(0x3a, 0x60), /* Display mode 18-bit RGB */ | ||
119 | CMD1(0xbf, 0x10), /* Drive system change control */ | ||
120 | CMD1(0xb1, 0x56), /* Booster operation setup */ | ||
121 | CMD1(0xb2, 0x33), /* Booster mode setup */ | ||
122 | CMD1(0xb3, 0x11), /* Booster frequency setup */ | ||
123 | CMD1(0xb4, 0x02), /* Op amp/system clock */ | ||
124 | CMD1(0xb5, 0x35), /* VCS voltage */ | ||
125 | CMD1(0xb6, 0x40), /* VCOM voltage */ | ||
126 | CMD1(0xb7, 0x03), /* External display signal */ | ||
127 | CMD1(0xbd, 0x00), /* ASW slew rate */ | ||
128 | CMD1(0xbe, 0x00), /* Dummy data for QuadData operation */ | ||
129 | CMD1(0xc0, 0x11), /* Sleep out FR count (A) */ | ||
130 | CMD1(0xc1, 0x11), /* Sleep out FR count (B) */ | ||
131 | CMD1(0xc2, 0x11), /* Sleep out FR count (C) */ | ||
132 | CMD2(0xc3, 0x20, 0x40), /* Sleep out FR count (D) */ | ||
133 | CMD2(0xc4, 0x60, 0xc0), /* Sleep out FR count (E) */ | ||
134 | CMD2(0xc5, 0x10, 0x20), /* Sleep out FR count (F) */ | ||
135 | CMD1(0xc6, 0xc0), /* Sleep out FR count (G) */ | ||
136 | CMD2(0xc7, 0x33, 0x43), /* Gamma 1 fine tuning (1) */ | ||
137 | CMD1(0xc8, 0x44), /* Gamma 1 fine tuning (2) */ | ||
138 | CMD1(0xc9, 0x33), /* Gamma 1 inclination adjustment */ | ||
139 | CMD1(0xca, 0x00), /* Gamma 1 blue offset adjustment */ | ||
140 | CMD2(0xec, 0x01, 0xf0), /* Horizontal clock cycles */ | ||
141 | CMD_NULL, | ||
142 | }; | ||
143 | |||
144 | static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array) | ||
145 | { | ||
146 | struct spi_transfer *x = &lcd->xfer; | ||
147 | uint32_t data, *p = array; | ||
148 | int nparams, err = 0; | ||
149 | |||
150 | for (; *p != CMD_NULL; p++) { | ||
151 | |||
152 | nparams = (*p >> 30) & 0x3; | ||
153 | |||
154 | data = *p << (7 - nparams); | ||
155 | switch (nparams) { | ||
156 | case 0: | ||
157 | lcd->buf[0] = (data >> 8) & 0xff; | ||
158 | lcd->buf[1] = data & 0xff; | ||
159 | break; | ||
160 | case 1: | ||
161 | lcd->buf[0] = (data >> 16) & 0xff; | ||
162 | lcd->buf[1] = (data >> 8) & 0xff; | ||
163 | lcd->buf[2] = data & 0xff; | ||
164 | break; | ||
165 | case 2: | ||
166 | lcd->buf[0] = (data >> 24) & 0xff; | ||
167 | lcd->buf[1] = (data >> 16) & 0xff; | ||
168 | lcd->buf[2] = (data >> 8) & 0xff; | ||
169 | lcd->buf[3] = data & 0xff; | ||
170 | break; | ||
171 | default: | ||
172 | continue; | ||
173 | } | ||
174 | x->len = nparams + 2; | ||
175 | err = spi_sync(lcd->spi_dev, &lcd->msg); | ||
176 | if (err) | ||
177 | break; | ||
178 | } | ||
179 | |||
180 | return err; | ||
181 | } | ||
182 | |||
183 | static int tdo24m_adj_mode(struct tdo24m *lcd, int mode) | ||
184 | { | ||
185 | switch (mode) { | ||
186 | case MODE_VGA: | ||
187 | tdo24m_writes(lcd, lcd_vga_pass_through); | ||
188 | tdo24m_writes(lcd, lcd_panel_config); | ||
189 | tdo24m_writes(lcd, lcd_vga_transfer); | ||
190 | break; | ||
191 | case MODE_QVGA: | ||
192 | tdo24m_writes(lcd, lcd_qvga_pass_through); | ||
193 | tdo24m_writes(lcd, lcd_panel_config); | ||
194 | tdo24m_writes(lcd, lcd_qvga_transfer); | ||
195 | break; | ||
196 | default: | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | |||
200 | lcd->mode = mode; | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int tdo24m_power_on(struct tdo24m *lcd) | ||
205 | { | ||
206 | int err; | ||
207 | |||
208 | err = tdo24m_writes(lcd, lcd_panel_on); | ||
209 | if (err) | ||
210 | goto out; | ||
211 | |||
212 | err = tdo24m_writes(lcd, lcd_panel_reset); | ||
213 | if (err) | ||
214 | goto out; | ||
215 | |||
216 | err = tdo24m_adj_mode(lcd, lcd->mode); | ||
217 | out: | ||
218 | return err; | ||
219 | } | ||
220 | |||
221 | static int tdo24m_power_off(struct tdo24m *lcd) | ||
222 | { | ||
223 | return tdo24m_writes(lcd, lcd_panel_off); | ||
224 | } | ||
225 | |||
226 | static int tdo24m_power(struct tdo24m *lcd, int power) | ||
227 | { | ||
228 | int ret = 0; | ||
229 | |||
230 | if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power)) | ||
231 | ret = tdo24m_power_on(lcd); | ||
232 | else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power)) | ||
233 | ret = tdo24m_power_off(lcd); | ||
234 | |||
235 | if (!ret) | ||
236 | lcd->power = power; | ||
237 | |||
238 | return ret; | ||
239 | } | ||
240 | |||
241 | |||
242 | static int tdo24m_set_power(struct lcd_device *ld, int power) | ||
243 | { | ||
244 | struct tdo24m *lcd = lcd_get_data(ld); | ||
245 | return tdo24m_power(lcd, power); | ||
246 | } | ||
247 | |||
248 | static int tdo24m_get_power(struct lcd_device *ld) | ||
249 | { | ||
250 | struct tdo24m *lcd = lcd_get_data(ld); | ||
251 | return lcd->power; | ||
252 | } | ||
253 | |||
254 | static int tdo24m_set_mode(struct lcd_device *ld, struct fb_videomode *m) | ||
255 | { | ||
256 | struct tdo24m *lcd = lcd_get_data(ld); | ||
257 | int mode = MODE_QVGA; | ||
258 | |||
259 | if (m->xres == 640 || m->xres == 480) | ||
260 | mode = MODE_VGA; | ||
261 | |||
262 | if (lcd->mode == mode) | ||
263 | return 0; | ||
264 | |||
265 | return tdo24m_adj_mode(lcd, mode); | ||
266 | } | ||
267 | |||
268 | static struct lcd_ops tdo24m_ops = { | ||
269 | .get_power = tdo24m_get_power, | ||
270 | .set_power = tdo24m_set_power, | ||
271 | .set_mode = tdo24m_set_mode, | ||
272 | }; | ||
273 | |||
274 | static int __devinit tdo24m_probe(struct spi_device *spi) | ||
275 | { | ||
276 | struct tdo24m *lcd; | ||
277 | struct spi_message *m; | ||
278 | struct spi_transfer *x; | ||
279 | int err; | ||
280 | |||
281 | spi->bits_per_word = 8; | ||
282 | spi->mode = SPI_MODE_3; | ||
283 | err = spi_setup(spi); | ||
284 | if (err) | ||
285 | return err; | ||
286 | |||
287 | lcd = kzalloc(sizeof(struct tdo24m), GFP_KERNEL); | ||
288 | if (!lcd) | ||
289 | return -ENOMEM; | ||
290 | |||
291 | lcd->spi_dev = spi; | ||
292 | lcd->power = FB_BLANK_POWERDOWN; | ||
293 | lcd->mode = MODE_VGA; /* default to VGA */ | ||
294 | |||
295 | lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL)); | ||
296 | if (lcd->buf == NULL) { | ||
297 | kfree(lcd); | ||
298 | return -ENOMEM; | ||
299 | } | ||
300 | |||
301 | m = &lcd->msg; | ||
302 | x = &lcd->xfer; | ||
303 | |||
304 | spi_message_init(m); | ||
305 | |||
306 | x->tx_buf = &lcd->buf[0]; | ||
307 | spi_message_add_tail(x, m); | ||
308 | |||
309 | lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev, | ||
310 | lcd, &tdo24m_ops); | ||
311 | if (IS_ERR(lcd->lcd_dev)) { | ||
312 | err = PTR_ERR(lcd->lcd_dev); | ||
313 | goto out_free; | ||
314 | } | ||
315 | |||
316 | dev_set_drvdata(&spi->dev, lcd); | ||
317 | err = tdo24m_power(lcd, FB_BLANK_UNBLANK); | ||
318 | if (err) | ||
319 | goto out_unregister; | ||
320 | |||
321 | return 0; | ||
322 | |||
323 | out_unregister: | ||
324 | lcd_device_unregister(lcd->lcd_dev); | ||
325 | out_free: | ||
326 | kfree(lcd->buf); | ||
327 | kfree(lcd); | ||
328 | return err; | ||
329 | } | ||
330 | |||
331 | static int __devexit tdo24m_remove(struct spi_device *spi) | ||
332 | { | ||
333 | struct tdo24m *lcd = dev_get_drvdata(&spi->dev); | ||
334 | |||
335 | tdo24m_power(lcd, FB_BLANK_POWERDOWN); | ||
336 | lcd_device_unregister(lcd->lcd_dev); | ||
337 | kfree(lcd->buf); | ||
338 | kfree(lcd); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | #ifdef CONFIG_PM | ||
344 | static int tdo24m_suspend(struct spi_device *spi, pm_message_t state) | ||
345 | { | ||
346 | struct tdo24m *lcd = dev_get_drvdata(&spi->dev); | ||
347 | |||
348 | return tdo24m_power(lcd, FB_BLANK_POWERDOWN); | ||
349 | } | ||
350 | |||
351 | static int tdo24m_resume(struct spi_device *spi) | ||
352 | { | ||
353 | struct tdo24m *lcd = dev_get_drvdata(&spi->dev); | ||
354 | |||
355 | return tdo24m_power(lcd, FB_BLANK_UNBLANK); | ||
356 | } | ||
357 | #else | ||
358 | #define tdo24m_suspend NULL | ||
359 | #define tdo24m_resume NULL | ||
360 | #endif | ||
361 | |||
362 | /* Power down all displays on reboot, poweroff or halt */ | ||
363 | static void tdo24m_shutdown(struct spi_device *spi) | ||
364 | { | ||
365 | struct tdo24m *lcd = dev_get_drvdata(&spi->dev); | ||
366 | |||
367 | tdo24m_power(lcd, FB_BLANK_POWERDOWN); | ||
368 | } | ||
369 | |||
370 | static struct spi_driver tdo24m_driver = { | ||
371 | .driver = { | ||
372 | .name = "tdo24m", | ||
373 | .owner = THIS_MODULE, | ||
374 | }, | ||
375 | .probe = tdo24m_probe, | ||
376 | .remove = __devexit_p(tdo24m_remove), | ||
377 | .shutdown = tdo24m_shutdown, | ||
378 | .suspend = tdo24m_suspend, | ||
379 | .resume = tdo24m_resume, | ||
380 | }; | ||
381 | |||
382 | static int __init tdo24m_init(void) | ||
383 | { | ||
384 | return spi_register_driver(&tdo24m_driver); | ||
385 | } | ||
386 | module_init(tdo24m_init); | ||
387 | |||
388 | static void __exit tdo24m_exit(void) | ||
389 | { | ||
390 | spi_unregister_driver(&tdo24m_driver); | ||
391 | } | ||
392 | module_exit(tdo24m_exit); | ||
393 | |||
394 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); | ||
395 | MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel"); | ||
396 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index e721644bad74..1e35ba6f18e0 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c | |||
@@ -372,7 +372,7 @@ static int __devexit bw2_remove(struct of_device *op) | |||
372 | return 0; | 372 | return 0; |
373 | } | 373 | } |
374 | 374 | ||
375 | static struct of_device_id bw2_match[] = { | 375 | static const struct of_device_id bw2_match[] = { |
376 | { | 376 | { |
377 | .name = "bwtwo", | 377 | .name = "bwtwo", |
378 | }, | 378 | }, |
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c index e15bb447440a..c9b191319a9a 100644 --- a/drivers/video/carminefb.c +++ b/drivers/video/carminefb.c | |||
@@ -535,7 +535,7 @@ static struct fb_ops carminefb_ops = { | |||
535 | .fb_setcolreg = carmine_setcolreg, | 535 | .fb_setcolreg = carmine_setcolreg, |
536 | }; | 536 | }; |
537 | 537 | ||
538 | static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base, | 538 | static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base, |
539 | int smem_offset, struct device *device, struct fb_info **rinfo) | 539 | int smem_offset, struct device *device, struct fb_info **rinfo) |
540 | { | 540 | { |
541 | int ret; | 541 | int ret; |
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index b17e74671779..a2d1882791a5 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c | |||
@@ -589,7 +589,7 @@ static int __devexit cg14_remove(struct of_device *op) | |||
589 | return 0; | 589 | return 0; |
590 | } | 590 | } |
591 | 591 | ||
592 | static struct of_device_id cg14_match[] = { | 592 | static const struct of_device_id cg14_match[] = { |
593 | { | 593 | { |
594 | .name = "cgfourteen", | 594 | .name = "cgfourteen", |
595 | }, | 595 | }, |
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 3aa7b6cb0268..99f87fb61d05 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c | |||
@@ -456,7 +456,7 @@ static int __devexit cg3_remove(struct of_device *op) | |||
456 | return 0; | 456 | return 0; |
457 | } | 457 | } |
458 | 458 | ||
459 | static struct of_device_id cg3_match[] = { | 459 | static const struct of_device_id cg3_match[] = { |
460 | { | 460 | { |
461 | .name = "cgthree", | 461 | .name = "cgthree", |
462 | }, | 462 | }, |
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 2f64bb3bd254..940ec04f0f1b 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c | |||
@@ -34,10 +34,11 @@ static int cg6_blank(int, struct fb_info *); | |||
34 | 34 | ||
35 | static void cg6_imageblit(struct fb_info *, const struct fb_image *); | 35 | static void cg6_imageblit(struct fb_info *, const struct fb_image *); |
36 | static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *); | 36 | static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *); |
37 | static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area); | ||
37 | static int cg6_sync(struct fb_info *); | 38 | static int cg6_sync(struct fb_info *); |
38 | static int cg6_mmap(struct fb_info *, struct vm_area_struct *); | 39 | static int cg6_mmap(struct fb_info *, struct vm_area_struct *); |
39 | static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long); | 40 | static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long); |
40 | static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area); | 41 | static int cg6_pan_display(struct fb_var_screeninfo *, struct fb_info *); |
41 | 42 | ||
42 | /* | 43 | /* |
43 | * Frame buffer operations | 44 | * Frame buffer operations |
@@ -47,6 +48,7 @@ static struct fb_ops cg6_ops = { | |||
47 | .owner = THIS_MODULE, | 48 | .owner = THIS_MODULE, |
48 | .fb_setcolreg = cg6_setcolreg, | 49 | .fb_setcolreg = cg6_setcolreg, |
49 | .fb_blank = cg6_blank, | 50 | .fb_blank = cg6_blank, |
51 | .fb_pan_display = cg6_pan_display, | ||
50 | .fb_fillrect = cg6_fillrect, | 52 | .fb_fillrect = cg6_fillrect, |
51 | .fb_copyarea = cg6_copyarea, | 53 | .fb_copyarea = cg6_copyarea, |
52 | .fb_imageblit = cg6_imageblit, | 54 | .fb_imageblit = cg6_imageblit, |
@@ -161,6 +163,7 @@ static struct fb_ops cg6_ops = { | |||
161 | #define CG6_THC_MISC_INT_ENAB (1 << 5) | 163 | #define CG6_THC_MISC_INT_ENAB (1 << 5) |
162 | #define CG6_THC_MISC_INT (1 << 4) | 164 | #define CG6_THC_MISC_INT (1 << 4) |
163 | #define CG6_THC_MISC_INIT 0x9f | 165 | #define CG6_THC_MISC_INIT 0x9f |
166 | #define CG6_THC_CURSOFF ((65536-32) | ((65536-32) << 16)) | ||
164 | 167 | ||
165 | /* The contents are unknown */ | 168 | /* The contents are unknown */ |
166 | struct cg6_tec { | 169 | struct cg6_tec { |
@@ -280,6 +283,33 @@ static int cg6_sync(struct fb_info *info) | |||
280 | return 0; | 283 | return 0; |
281 | } | 284 | } |
282 | 285 | ||
286 | static void cg6_switch_from_graph(struct cg6_par *par) | ||
287 | { | ||
288 | struct cg6_thc __iomem *thc = par->thc; | ||
289 | unsigned long flags; | ||
290 | |||
291 | spin_lock_irqsave(&par->lock, flags); | ||
292 | |||
293 | /* Hide the cursor. */ | ||
294 | sbus_writel(CG6_THC_CURSOFF, &thc->thc_cursxy); | ||
295 | |||
296 | spin_unlock_irqrestore(&par->lock, flags); | ||
297 | } | ||
298 | |||
299 | static int cg6_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | ||
300 | { | ||
301 | struct cg6_par *par = (struct cg6_par *)info->par; | ||
302 | |||
303 | /* We just use this to catch switches out of | ||
304 | * graphics mode. | ||
305 | */ | ||
306 | cg6_switch_from_graph(par); | ||
307 | |||
308 | if (var->xoffset || var->yoffset || var->vmode) | ||
309 | return -EINVAL; | ||
310 | return 0; | ||
311 | } | ||
312 | |||
283 | /** | 313 | /** |
284 | * cg6_fillrect - Draws a rectangle on the screen. | 314 | * cg6_fillrect - Draws a rectangle on the screen. |
285 | * | 315 | * |
@@ -643,9 +673,13 @@ static void __devinit cg6_chip_init(struct fb_info *info) | |||
643 | struct cg6_par *par = (struct cg6_par *)info->par; | 673 | struct cg6_par *par = (struct cg6_par *)info->par; |
644 | struct cg6_tec __iomem *tec = par->tec; | 674 | struct cg6_tec __iomem *tec = par->tec; |
645 | struct cg6_fbc __iomem *fbc = par->fbc; | 675 | struct cg6_fbc __iomem *fbc = par->fbc; |
676 | struct cg6_thc __iomem *thc = par->thc; | ||
646 | u32 rev, conf, mode; | 677 | u32 rev, conf, mode; |
647 | int i; | 678 | int i; |
648 | 679 | ||
680 | /* Hide the cursor. */ | ||
681 | sbus_writel(CG6_THC_CURSOFF, &thc->thc_cursxy); | ||
682 | |||
649 | /* Turn off stuff in the Transform Engine. */ | 683 | /* Turn off stuff in the Transform Engine. */ |
650 | sbus_writel(0, &tec->tec_matrix); | 684 | sbus_writel(0, &tec->tec_matrix); |
651 | sbus_writel(0, &tec->tec_clip); | 685 | sbus_writel(0, &tec->tec_clip); |
@@ -814,7 +848,7 @@ static int __devexit cg6_remove(struct of_device *op) | |||
814 | return 0; | 848 | return 0; |
815 | } | 849 | } |
816 | 850 | ||
817 | static struct of_device_id cg6_match[] = { | 851 | static const struct of_device_id cg6_match[] = { |
818 | { | 852 | { |
819 | .name = "cgsix", | 853 | .name = "cgsix", |
820 | }, | 854 | }, |
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index e729fb279645..048b139f0e50 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -327,29 +327,7 @@ static const struct { | |||
327 | #endif /* CONFIG_ZORRO */ | 327 | #endif /* CONFIG_ZORRO */ |
328 | 328 | ||
329 | struct cirrusfb_regs { | 329 | struct cirrusfb_regs { |
330 | long freq; | 330 | int multiplexing; |
331 | long nom; | ||
332 | long den; | ||
333 | long div; | ||
334 | long multiplexing; | ||
335 | long mclk; | ||
336 | long divMCLK; | ||
337 | |||
338 | long HorizRes; /* The x resolution in pixel */ | ||
339 | long HorizTotal; | ||
340 | long HorizDispEnd; | ||
341 | long HorizBlankStart; | ||
342 | long HorizBlankEnd; | ||
343 | long HorizSyncStart; | ||
344 | long HorizSyncEnd; | ||
345 | |||
346 | long VertRes; /* the physical y resolution in scanlines */ | ||
347 | long VertTotal; | ||
348 | long VertDispEnd; | ||
349 | long VertSyncStart; | ||
350 | long VertSyncEnd; | ||
351 | long VertBlankStart; | ||
352 | long VertBlankEnd; | ||
353 | }; | 331 | }; |
354 | 332 | ||
355 | #ifdef CIRRUSFB_DEBUG | 333 | #ifdef CIRRUSFB_DEBUG |
@@ -367,110 +345,13 @@ struct cirrusfb_info { | |||
367 | 345 | ||
368 | struct cirrusfb_regs currentmode; | 346 | struct cirrusfb_regs currentmode; |
369 | int blank_mode; | 347 | int blank_mode; |
348 | u32 pseudo_palette[16]; | ||
370 | 349 | ||
371 | u32 pseudo_palette[16]; | ||
372 | |||
373 | #ifdef CONFIG_ZORRO | ||
374 | struct zorro_dev *zdev; | ||
375 | #endif | ||
376 | #ifdef CONFIG_PCI | ||
377 | struct pci_dev *pdev; | ||
378 | #endif | ||
379 | void (*unmap)(struct fb_info *info); | 350 | void (*unmap)(struct fb_info *info); |
380 | }; | 351 | }; |
381 | 352 | ||
382 | static unsigned cirrusfb_def_mode = 1; | 353 | static int noaccel __devinitdata; |
383 | static int noaccel; | 354 | static char *mode_option __devinitdata = "640x480@60"; |
384 | |||
385 | /* | ||
386 | * Predefined Video Modes | ||
387 | */ | ||
388 | |||
389 | static const struct { | ||
390 | const char *name; | ||
391 | struct fb_var_screeninfo var; | ||
392 | } cirrusfb_predefined[] = { | ||
393 | { | ||
394 | /* autodetect mode */ | ||
395 | .name = "Autodetect", | ||
396 | }, { | ||
397 | /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */ | ||
398 | .name = "640x480", | ||
399 | .var = { | ||
400 | .xres = 640, | ||
401 | .yres = 480, | ||
402 | .xres_virtual = 640, | ||
403 | .yres_virtual = 480, | ||
404 | .bits_per_pixel = 8, | ||
405 | .red = { .length = 8 }, | ||
406 | .green = { .length = 8 }, | ||
407 | .blue = { .length = 8 }, | ||
408 | .width = -1, | ||
409 | .height = -1, | ||
410 | .pixclock = 40000, | ||
411 | .left_margin = 48, | ||
412 | .right_margin = 16, | ||
413 | .upper_margin = 32, | ||
414 | .lower_margin = 8, | ||
415 | .hsync_len = 96, | ||
416 | .vsync_len = 4, | ||
417 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
418 | .vmode = FB_VMODE_NONINTERLACED | ||
419 | } | ||
420 | }, { | ||
421 | /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */ | ||
422 | .name = "800x600", | ||
423 | .var = { | ||
424 | .xres = 800, | ||
425 | .yres = 600, | ||
426 | .xres_virtual = 800, | ||
427 | .yres_virtual = 600, | ||
428 | .bits_per_pixel = 8, | ||
429 | .red = { .length = 8 }, | ||
430 | .green = { .length = 8 }, | ||
431 | .blue = { .length = 8 }, | ||
432 | .width = -1, | ||
433 | .height = -1, | ||
434 | .pixclock = 20000, | ||
435 | .left_margin = 128, | ||
436 | .right_margin = 16, | ||
437 | .upper_margin = 24, | ||
438 | .lower_margin = 2, | ||
439 | .hsync_len = 96, | ||
440 | .vsync_len = 6, | ||
441 | .vmode = FB_VMODE_NONINTERLACED | ||
442 | } | ||
443 | }, { | ||
444 | /* | ||
445 | * Modeline from XF86Config: | ||
446 | * Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805 | ||
447 | */ | ||
448 | /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */ | ||
449 | .name = "1024x768", | ||
450 | .var = { | ||
451 | .xres = 1024, | ||
452 | .yres = 768, | ||
453 | .xres_virtual = 1024, | ||
454 | .yres_virtual = 768, | ||
455 | .bits_per_pixel = 8, | ||
456 | .red = { .length = 8 }, | ||
457 | .green = { .length = 8 }, | ||
458 | .blue = { .length = 8 }, | ||
459 | .width = -1, | ||
460 | .height = -1, | ||
461 | .pixclock = 12500, | ||
462 | .left_margin = 144, | ||
463 | .right_margin = 32, | ||
464 | .upper_margin = 30, | ||
465 | .lower_margin = 2, | ||
466 | .hsync_len = 192, | ||
467 | .vsync_len = 6, | ||
468 | .vmode = FB_VMODE_NONINTERLACED | ||
469 | } | ||
470 | } | ||
471 | }; | ||
472 | |||
473 | #define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined) | ||
474 | 355 | ||
475 | /****************************************************************************/ | 356 | /****************************************************************************/ |
476 | /**** BEGIN PROTOTYPES ******************************************************/ | 357 | /**** BEGIN PROTOTYPES ******************************************************/ |
@@ -514,10 +395,6 @@ static struct fb_ops cirrusfb_ops = { | |||
514 | .fb_imageblit = cirrusfb_imageblit, | 395 | .fb_imageblit = cirrusfb_imageblit, |
515 | }; | 396 | }; |
516 | 397 | ||
517 | /*--- Hardware Specific Routines -------------------------------------------*/ | ||
518 | static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, | ||
519 | struct cirrusfb_regs *regs, | ||
520 | struct fb_info *info); | ||
521 | /*--- Internal routines ----------------------------------------------------*/ | 398 | /*--- Internal routines ----------------------------------------------------*/ |
522 | static void init_vgachip(struct fb_info *info); | 399 | static void init_vgachip(struct fb_info *info); |
523 | static void switch_monitor(struct cirrusfb_info *cinfo, int on); | 400 | static void switch_monitor(struct cirrusfb_info *cinfo, int on); |
@@ -546,9 +423,7 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, | |||
546 | u_short width, u_short height, | 423 | u_short width, u_short height, |
547 | u_char color, u_short line_length); | 424 | u_char color, u_short line_length); |
548 | 425 | ||
549 | static void bestclock(long freq, long *best, | 426 | static void bestclock(long freq, int *nom, int *den, int *div); |
550 | long *nom, long *den, | ||
551 | long *div, long maxfreq); | ||
552 | 427 | ||
553 | #ifdef CIRRUSFB_DEBUG | 428 | #ifdef CIRRUSFB_DEBUG |
554 | static void cirrusfb_dump(void); | 429 | static void cirrusfb_dump(void); |
@@ -584,45 +459,28 @@ static int cirrusfb_release(struct fb_info *info, int user) | |||
584 | /****************************************************************************/ | 459 | /****************************************************************************/ |
585 | /**** BEGIN Hardware specific Routines **************************************/ | 460 | /**** BEGIN Hardware specific Routines **************************************/ |
586 | 461 | ||
587 | /* Get a good MCLK value */ | 462 | /* Check if the MCLK is not a better clock source */ |
588 | static long cirrusfb_get_mclk(long freq, int bpp, long *div) | 463 | static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq) |
589 | { | 464 | { |
590 | long mclk; | 465 | long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f; |
591 | 466 | ||
592 | assert(div != NULL); | 467 | /* Read MCLK value */ |
593 | 468 | mclk = (14318 * mclk) >> 3; | |
594 | /* Calculate MCLK, in case VCLK is high enough to require > 50MHz. | 469 | DPRINTK("Read MCLK of %ld kHz\n", mclk); |
595 | * Assume a 64-bit data path for now. The formula is: | ||
596 | * ((B * PCLK * 2)/W) * 1.2 | ||
597 | * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */ | ||
598 | mclk = ((bpp / 8) * freq * 2) / 4; | ||
599 | mclk = (mclk * 12) / 10; | ||
600 | if (mclk < 50000) | ||
601 | mclk = 50000; | ||
602 | DPRINTK("Use MCLK of %ld kHz\n", mclk); | ||
603 | |||
604 | /* Calculate value for SR1F. Multiply by 2 so we can round up. */ | ||
605 | mclk = ((mclk * 16) / 14318); | ||
606 | mclk = (mclk + 1) / 2; | ||
607 | DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk); | ||
608 | 470 | ||
609 | /* Determine if we should use MCLK instead of VCLK, and if so, what we | 471 | /* Determine if we should use MCLK instead of VCLK, and if so, what we |
610 | * should divide it by to get VCLK */ | 472 | * should divide it by to get VCLK |
611 | switch (freq) { | 473 | */ |
612 | case 24751 ... 25249: | 474 | |
613 | *div = 2; | 475 | if (abs(freq - mclk) < 250) { |
614 | DPRINTK("Using VCLK = MCLK/2\n"); | ||
615 | break; | ||
616 | case 49501 ... 50499: | ||
617 | *div = 1; | ||
618 | DPRINTK("Using VCLK = MCLK\n"); | 476 | DPRINTK("Using VCLK = MCLK\n"); |
619 | break; | 477 | return 1; |
620 | default: | 478 | } else if (abs(freq - (mclk / 2)) < 250) { |
621 | *div = 0; | 479 | DPRINTK("Using VCLK = MCLK/2\n"); |
622 | break; | 480 | return 2; |
623 | } | 481 | } |
624 | 482 | ||
625 | return mclk; | 483 | return 0; |
626 | } | 484 | } |
627 | 485 | ||
628 | static int cirrusfb_check_var(struct fb_var_screeninfo *var, | 486 | static int cirrusfb_check_var(struct fb_var_screeninfo *var, |
@@ -638,7 +496,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, | |||
638 | break; /* 8 pixel per byte, only 1/4th of mem usable */ | 496 | break; /* 8 pixel per byte, only 1/4th of mem usable */ |
639 | case 8: | 497 | case 8: |
640 | case 16: | 498 | case 16: |
641 | case 24: | ||
642 | case 32: | 499 | case 32: |
643 | break; /* 1 pixel == 1 byte */ | 500 | break; /* 1 pixel == 1 byte */ |
644 | default: | 501 | default: |
@@ -713,7 +570,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, | |||
713 | var->blue.length = 5; | 570 | var->blue.length = 5; |
714 | break; | 571 | break; |
715 | 572 | ||
716 | case 24: | ||
717 | case 32: | 573 | case 32: |
718 | if (isPReP) { | 574 | if (isPReP) { |
719 | var->red.offset = 8; | 575 | var->red.offset = 8; |
@@ -767,8 +623,6 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, | |||
767 | long maxclock; | 623 | long maxclock; |
768 | int maxclockidx = var->bits_per_pixel >> 3; | 624 | int maxclockidx = var->bits_per_pixel >> 3; |
769 | struct cirrusfb_info *cinfo = info->par; | 625 | struct cirrusfb_info *cinfo = info->par; |
770 | int xres, hfront, hsync, hback; | ||
771 | int yres, vfront, vsync, vback; | ||
772 | 626 | ||
773 | switch (var->bits_per_pixel) { | 627 | switch (var->bits_per_pixel) { |
774 | case 1: | 628 | case 1: |
@@ -782,10 +636,9 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, | |||
782 | break; | 636 | break; |
783 | 637 | ||
784 | case 16: | 638 | case 16: |
785 | case 24: | ||
786 | case 32: | 639 | case 32: |
787 | info->fix.line_length = var->xres_virtual * maxclockidx; | 640 | info->fix.line_length = var->xres_virtual * maxclockidx; |
788 | info->fix.visual = FB_VISUAL_DIRECTCOLOR; | 641 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
789 | break; | 642 | break; |
790 | 643 | ||
791 | default: | 644 | default: |
@@ -827,90 +680,33 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, | |||
827 | switch (var->bits_per_pixel) { | 680 | switch (var->bits_per_pixel) { |
828 | case 16: | 681 | case 16: |
829 | case 32: | 682 | case 32: |
830 | if (regs->HorizRes <= 800) | 683 | if (var->xres <= 800) |
831 | /* Xbh has this type of clock for 32-bit */ | 684 | /* Xbh has this type of clock for 32-bit */ |
832 | freq /= 2; | 685 | freq /= 2; |
833 | break; | 686 | break; |
834 | } | 687 | } |
835 | #endif | 688 | #endif |
836 | |||
837 | bestclock(freq, ®s->freq, ®s->nom, ®s->den, ®s->div, | ||
838 | maxclock); | ||
839 | regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel, | ||
840 | ®s->divMCLK); | ||
841 | |||
842 | xres = var->xres; | ||
843 | hfront = var->right_margin; | ||
844 | hsync = var->hsync_len; | ||
845 | hback = var->left_margin; | ||
846 | |||
847 | yres = var->yres; | ||
848 | vfront = var->lower_margin; | ||
849 | vsync = var->vsync_len; | ||
850 | vback = var->upper_margin; | ||
851 | |||
852 | if (var->vmode & FB_VMODE_DOUBLE) { | ||
853 | yres *= 2; | ||
854 | vfront *= 2; | ||
855 | vsync *= 2; | ||
856 | vback *= 2; | ||
857 | } else if (var->vmode & FB_VMODE_INTERLACED) { | ||
858 | yres = (yres + 1) / 2; | ||
859 | vfront = (vfront + 1) / 2; | ||
860 | vsync = (vsync + 1) / 2; | ||
861 | vback = (vback + 1) / 2; | ||
862 | } | ||
863 | regs->HorizRes = xres; | ||
864 | regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5; | ||
865 | regs->HorizDispEnd = xres / 8 - 1; | ||
866 | regs->HorizBlankStart = xres / 8; | ||
867 | /* does not count with "-5" */ | ||
868 | regs->HorizBlankEnd = regs->HorizTotal + 5; | ||
869 | regs->HorizSyncStart = (xres + hfront) / 8 + 1; | ||
870 | regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1; | ||
871 | |||
872 | regs->VertRes = yres; | ||
873 | regs->VertTotal = yres + vfront + vsync + vback - 2; | ||
874 | regs->VertDispEnd = yres - 1; | ||
875 | regs->VertBlankStart = yres; | ||
876 | regs->VertBlankEnd = regs->VertTotal; | ||
877 | regs->VertSyncStart = yres + vfront - 1; | ||
878 | regs->VertSyncEnd = yres + vfront + vsync - 1; | ||
879 | |||
880 | if (regs->VertRes >= 1024) { | ||
881 | regs->VertTotal /= 2; | ||
882 | regs->VertSyncStart /= 2; | ||
883 | regs->VertSyncEnd /= 2; | ||
884 | regs->VertDispEnd /= 2; | ||
885 | } | ||
886 | if (regs->multiplexing) { | ||
887 | regs->HorizTotal /= 2; | ||
888 | regs->HorizSyncStart /= 2; | ||
889 | regs->HorizSyncEnd /= 2; | ||
890 | regs->HorizDispEnd /= 2; | ||
891 | } | ||
892 | |||
893 | return 0; | 689 | return 0; |
894 | } | 690 | } |
895 | 691 | ||
896 | static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val, | 692 | static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo, |
897 | int div) | 693 | int div) |
898 | { | 694 | { |
695 | unsigned char old1f, old1e; | ||
899 | assert(cinfo != NULL); | 696 | assert(cinfo != NULL); |
697 | old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40; | ||
900 | 698 | ||
901 | if (div == 2) { | 699 | if (div) { |
902 | /* VCLK = MCLK/2 */ | 700 | DPRINTK("Set %s as pixclock source.\n", |
903 | unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E); | 701 | (div == 2) ? "MCLK/2" : "MCLK"); |
904 | vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1); | 702 | old1f |= 0x40; |
905 | vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); | 703 | old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1; |
906 | } else if (div == 1) { | 704 | if (div == 2) |
907 | /* VCLK = MCLK */ | 705 | old1e |= 1; |
908 | unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E); | 706 | |
909 | vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1); | 707 | vga_wseq(cinfo->regbase, CL_SEQR1E, old1e); |
910 | vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); | ||
911 | } else { | ||
912 | vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f); | ||
913 | } | 708 | } |
709 | vga_wseq(cinfo->regbase, CL_SEQR1F, old1f); | ||
914 | } | 710 | } |
915 | 711 | ||
916 | /************************************************************************* | 712 | /************************************************************************* |
@@ -927,6 +723,10 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
927 | unsigned char tmp; | 723 | unsigned char tmp; |
928 | int offset = 0, err; | 724 | int offset = 0, err; |
929 | const struct cirrusfb_board_info_rec *bi; | 725 | const struct cirrusfb_board_info_rec *bi; |
726 | int hdispend, hsyncstart, hsyncend, htotal; | ||
727 | int yres, vdispend, vsyncstart, vsyncend, vtotal; | ||
728 | long freq; | ||
729 | int nom, den, div; | ||
930 | 730 | ||
931 | DPRINTK("ENTER\n"); | 731 | DPRINTK("ENTER\n"); |
932 | DPRINTK("Requested mode: %dx%dx%d\n", | 732 | DPRINTK("Requested mode: %dx%dx%d\n", |
@@ -944,76 +744,117 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
944 | 744 | ||
945 | bi = &cirrusfb_board_info[cinfo->btype]; | 745 | bi = &cirrusfb_board_info[cinfo->btype]; |
946 | 746 | ||
747 | hsyncstart = var->xres + var->right_margin; | ||
748 | hsyncend = hsyncstart + var->hsync_len; | ||
749 | htotal = (hsyncend + var->left_margin) / 8 - 5; | ||
750 | hdispend = var->xres / 8 - 1; | ||
751 | hsyncstart = hsyncstart / 8 + 1; | ||
752 | hsyncend = hsyncend / 8 + 1; | ||
753 | |||
754 | yres = var->yres; | ||
755 | vsyncstart = yres + var->lower_margin; | ||
756 | vsyncend = vsyncstart + var->vsync_len; | ||
757 | vtotal = vsyncend + var->upper_margin; | ||
758 | vdispend = yres - 1; | ||
759 | |||
760 | if (var->vmode & FB_VMODE_DOUBLE) { | ||
761 | yres *= 2; | ||
762 | vsyncstart *= 2; | ||
763 | vsyncend *= 2; | ||
764 | vtotal *= 2; | ||
765 | } else if (var->vmode & FB_VMODE_INTERLACED) { | ||
766 | yres = (yres + 1) / 2; | ||
767 | vsyncstart = (vsyncstart + 1) / 2; | ||
768 | vsyncend = (vsyncend + 1) / 2; | ||
769 | vtotal = (vtotal + 1) / 2; | ||
770 | } | ||
771 | |||
772 | vtotal -= 2; | ||
773 | vsyncstart -= 1; | ||
774 | vsyncend -= 1; | ||
775 | |||
776 | if (yres >= 1024) { | ||
777 | vtotal /= 2; | ||
778 | vsyncstart /= 2; | ||
779 | vsyncend /= 2; | ||
780 | vdispend /= 2; | ||
781 | } | ||
782 | if (regs.multiplexing) { | ||
783 | htotal /= 2; | ||
784 | hsyncstart /= 2; | ||
785 | hsyncend /= 2; | ||
786 | hdispend /= 2; | ||
787 | } | ||
947 | /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ | 788 | /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ |
948 | vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ | 789 | vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ |
949 | 790 | ||
950 | /* if debugging is enabled, all parameters get output before writing */ | 791 | /* if debugging is enabled, all parameters get output before writing */ |
951 | DPRINTK("CRT0: %ld\n", regs.HorizTotal); | 792 | DPRINTK("CRT0: %d\n", htotal); |
952 | vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal); | 793 | vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal); |
953 | 794 | ||
954 | DPRINTK("CRT1: %ld\n", regs.HorizDispEnd); | 795 | DPRINTK("CRT1: %d\n", hdispend); |
955 | vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd); | 796 | vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend); |
956 | 797 | ||
957 | DPRINTK("CRT2: %ld\n", regs.HorizBlankStart); | 798 | DPRINTK("CRT2: %d\n", var->xres / 8); |
958 | vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart); | 799 | vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8); |
959 | 800 | ||
960 | /* + 128: Compatible read */ | 801 | /* + 128: Compatible read */ |
961 | DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32); | 802 | DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32); |
962 | vga_wcrt(regbase, VGA_CRTC_H_BLANK_END, | 803 | vga_wcrt(regbase, VGA_CRTC_H_BLANK_END, |
963 | 128 + (regs.HorizBlankEnd % 32)); | 804 | 128 + ((htotal + 5) % 32)); |
964 | 805 | ||
965 | DPRINTK("CRT4: %ld\n", regs.HorizSyncStart); | 806 | DPRINTK("CRT4: %d\n", hsyncstart); |
966 | vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart); | 807 | vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart); |
967 | 808 | ||
968 | tmp = regs.HorizSyncEnd % 32; | 809 | tmp = hsyncend % 32; |
969 | if (regs.HorizBlankEnd & 32) | 810 | if ((htotal + 5) & 32) |
970 | tmp += 128; | 811 | tmp += 128; |
971 | DPRINTK("CRT5: %d\n", tmp); | 812 | DPRINTK("CRT5: %d\n", tmp); |
972 | vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp); | 813 | vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp); |
973 | 814 | ||
974 | DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff); | 815 | DPRINTK("CRT6: %d\n", vtotal & 0xff); |
975 | vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff)); | 816 | vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff); |
976 | 817 | ||
977 | tmp = 16; /* LineCompare bit #9 */ | 818 | tmp = 16; /* LineCompare bit #9 */ |
978 | if (regs.VertTotal & 256) | 819 | if (vtotal & 256) |
979 | tmp |= 1; | 820 | tmp |= 1; |
980 | if (regs.VertDispEnd & 256) | 821 | if (vdispend & 256) |
981 | tmp |= 2; | 822 | tmp |= 2; |
982 | if (regs.VertSyncStart & 256) | 823 | if (vsyncstart & 256) |
983 | tmp |= 4; | 824 | tmp |= 4; |
984 | if (regs.VertBlankStart & 256) | 825 | if ((vdispend + 1) & 256) |
985 | tmp |= 8; | 826 | tmp |= 8; |
986 | if (regs.VertTotal & 512) | 827 | if (vtotal & 512) |
987 | tmp |= 32; | 828 | tmp |= 32; |
988 | if (regs.VertDispEnd & 512) | 829 | if (vdispend & 512) |
989 | tmp |= 64; | 830 | tmp |= 64; |
990 | if (regs.VertSyncStart & 512) | 831 | if (vsyncstart & 512) |
991 | tmp |= 128; | 832 | tmp |= 128; |
992 | DPRINTK("CRT7: %d\n", tmp); | 833 | DPRINTK("CRT7: %d\n", tmp); |
993 | vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp); | 834 | vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp); |
994 | 835 | ||
995 | tmp = 0x40; /* LineCompare bit #8 */ | 836 | tmp = 0x40; /* LineCompare bit #8 */ |
996 | if (regs.VertBlankStart & 512) | 837 | if ((vdispend + 1) & 512) |
997 | tmp |= 0x20; | 838 | tmp |= 0x20; |
998 | if (var->vmode & FB_VMODE_DOUBLE) | 839 | if (var->vmode & FB_VMODE_DOUBLE) |
999 | tmp |= 0x80; | 840 | tmp |= 0x80; |
1000 | DPRINTK("CRT9: %d\n", tmp); | 841 | DPRINTK("CRT9: %d\n", tmp); |
1001 | vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp); | 842 | vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp); |
1002 | 843 | ||
1003 | DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff); | 844 | DPRINTK("CRT10: %d\n", vsyncstart & 0xff); |
1004 | vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff); | 845 | vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff); |
1005 | 846 | ||
1006 | DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16); | 847 | DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16); |
1007 | vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32); | 848 | vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32); |
1008 | 849 | ||
1009 | DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff); | 850 | DPRINTK("CRT12: %d\n", vdispend & 0xff); |
1010 | vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff); | 851 | vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff); |
1011 | 852 | ||
1012 | DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff); | 853 | DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff); |
1013 | vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff); | 854 | vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff); |
1014 | 855 | ||
1015 | DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff); | 856 | DPRINTK("CRT16: %d\n", vtotal & 0xff); |
1016 | vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff); | 857 | vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff); |
1017 | 858 | ||
1018 | DPRINTK("CRT18: 0xff\n"); | 859 | DPRINTK("CRT18: 0xff\n"); |
1019 | vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff); | 860 | vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff); |
@@ -1021,38 +862,53 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1021 | tmp = 0; | 862 | tmp = 0; |
1022 | if (var->vmode & FB_VMODE_INTERLACED) | 863 | if (var->vmode & FB_VMODE_INTERLACED) |
1023 | tmp |= 1; | 864 | tmp |= 1; |
1024 | if (regs.HorizBlankEnd & 64) | 865 | if ((htotal + 5) & 64) |
1025 | tmp |= 16; | 866 | tmp |= 16; |
1026 | if (regs.HorizBlankEnd & 128) | 867 | if ((htotal + 5) & 128) |
1027 | tmp |= 32; | 868 | tmp |= 32; |
1028 | if (regs.VertBlankEnd & 256) | 869 | if (vtotal & 256) |
1029 | tmp |= 64; | 870 | tmp |= 64; |
1030 | if (regs.VertBlankEnd & 512) | 871 | if (vtotal & 512) |
1031 | tmp |= 128; | 872 | tmp |= 128; |
1032 | 873 | ||
1033 | DPRINTK("CRT1a: %d\n", tmp); | 874 | DPRINTK("CRT1a: %d\n", tmp); |
1034 | vga_wcrt(regbase, CL_CRT1A, tmp); | 875 | vga_wcrt(regbase, CL_CRT1A, tmp); |
1035 | 876 | ||
877 | freq = PICOS2KHZ(var->pixclock); | ||
878 | bestclock(freq, &nom, &den, &div); | ||
879 | |||
1036 | /* set VCLK0 */ | 880 | /* set VCLK0 */ |
1037 | /* hardware RefClock: 14.31818 MHz */ | 881 | /* hardware RefClock: 14.31818 MHz */ |
1038 | /* formula: VClk = (OSC * N) / (D * (1+P)) */ | 882 | /* formula: VClk = (OSC * N) / (D * (1+P)) */ |
1039 | /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ | 883 | /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ |
1040 | 884 | ||
1041 | vga_wseq(regbase, CL_SEQRB, regs.nom); | 885 | if (cinfo->btype == BT_ALPINE) { |
1042 | tmp = regs.den << 1; | 886 | /* if freq is close to mclk or mclk/2 select mclk |
1043 | if (regs.div != 0) | 887 | * as clock source |
1044 | tmp |= 1; | 888 | */ |
889 | int divMCLK = cirrusfb_check_mclk(cinfo, freq); | ||
890 | if (divMCLK) { | ||
891 | nom = 0; | ||
892 | cirrusfb_set_mclk_as_source(cinfo, divMCLK); | ||
893 | } | ||
894 | } | ||
895 | if (nom) { | ||
896 | vga_wseq(regbase, CL_SEQRB, nom); | ||
897 | tmp = den << 1; | ||
898 | if (div != 0) | ||
899 | tmp |= 1; | ||
1045 | 900 | ||
1046 | /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ | 901 | /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ |
1047 | if ((cinfo->btype == BT_SD64) || | 902 | if ((cinfo->btype == BT_SD64) || |
1048 | (cinfo->btype == BT_ALPINE) || | 903 | (cinfo->btype == BT_ALPINE) || |
1049 | (cinfo->btype == BT_GD5480)) | 904 | (cinfo->btype == BT_GD5480)) |
1050 | tmp |= 0x80; | 905 | tmp |= 0x80; |
1051 | 906 | ||
1052 | DPRINTK("CL_SEQR1B: %ld\n", (long) tmp); | 907 | DPRINTK("CL_SEQR1B: %ld\n", (long) tmp); |
1053 | vga_wseq(regbase, CL_SEQR1B, tmp); | 908 | vga_wseq(regbase, CL_SEQR1B, tmp); |
909 | } | ||
1054 | 910 | ||
1055 | if (regs.VertRes >= 1024) | 911 | if (yres >= 1024) |
1056 | /* 1280x1024 */ | 912 | /* 1280x1024 */ |
1057 | vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7); | 913 | vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7); |
1058 | else | 914 | else |
@@ -1066,7 +922,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1066 | /* don't know if it would hurt to also program this if no interlaced */ | 922 | /* don't know if it would hurt to also program this if no interlaced */ |
1067 | /* mode is used, but I feel better this way.. :-) */ | 923 | /* mode is used, but I feel better this way.. :-) */ |
1068 | if (var->vmode & FB_VMODE_INTERLACED) | 924 | if (var->vmode & FB_VMODE_INTERLACED) |
1069 | vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2); | 925 | vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2); |
1070 | else | 926 | else |
1071 | vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ | 927 | vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ |
1072 | 928 | ||
@@ -1240,7 +1096,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1240 | 1096 | ||
1241 | case BT_ALPINE: | 1097 | case BT_ALPINE: |
1242 | DPRINTK(" (for GD543x)\n"); | 1098 | DPRINTK(" (for GD543x)\n"); |
1243 | cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK); | ||
1244 | /* We already set SRF and SR1F */ | 1099 | /* We already set SRF and SR1F */ |
1245 | break; | 1100 | break; |
1246 | 1101 | ||
@@ -1312,11 +1167,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1312 | 1167 | ||
1313 | case BT_ALPINE: | 1168 | case BT_ALPINE: |
1314 | DPRINTK(" (for GD543x)\n"); | 1169 | DPRINTK(" (for GD543x)\n"); |
1315 | if (regs.HorizRes >= 1024) | 1170 | vga_wseq(regbase, CL_SEQR7, 0xa7); |
1316 | vga_wseq(regbase, CL_SEQR7, 0xa7); | ||
1317 | else | ||
1318 | vga_wseq(regbase, CL_SEQR7, 0xa3); | ||
1319 | cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK); | ||
1320 | break; | 1171 | break; |
1321 | 1172 | ||
1322 | case BT_GD5480: | 1173 | case BT_GD5480: |
@@ -1360,7 +1211,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1360 | */ | 1211 | */ |
1361 | 1212 | ||
1362 | else if (var->bits_per_pixel == 32) { | 1213 | else if (var->bits_per_pixel == 32) { |
1363 | DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n"); | 1214 | DPRINTK("cirrusfb: preparing for 32 bit deep display\n"); |
1364 | switch (cinfo->btype) { | 1215 | switch (cinfo->btype) { |
1365 | case BT_SD64: | 1216 | case BT_SD64: |
1366 | /* Extended Sequencer Mode: 256c col. mode */ | 1217 | /* Extended Sequencer Mode: 256c col. mode */ |
@@ -1394,7 +1245,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1394 | case BT_ALPINE: | 1245 | case BT_ALPINE: |
1395 | DPRINTK(" (for GD543x)\n"); | 1246 | DPRINTK(" (for GD543x)\n"); |
1396 | vga_wseq(regbase, CL_SEQR7, 0xa9); | 1247 | vga_wseq(regbase, CL_SEQR7, 0xa9); |
1397 | cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK); | ||
1398 | break; | 1248 | break; |
1399 | 1249 | ||
1400 | case BT_GD5480: | 1250 | case BT_GD5480: |
@@ -1949,8 +1799,6 @@ static void init_vgachip(struct fb_info *info) | |||
1949 | /* misc... */ | 1799 | /* misc... */ |
1950 | WHDR(cinfo, 0); /* Hidden DAC register: - */ | 1800 | WHDR(cinfo, 0); /* Hidden DAC register: - */ |
1951 | 1801 | ||
1952 | printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n", | ||
1953 | info->screen_size); | ||
1954 | DPRINTK("EXIT\n"); | 1802 | DPRINTK("EXIT\n"); |
1955 | return; | 1803 | return; |
1956 | } | 1804 | } |
@@ -2122,7 +1970,7 @@ static int release_io_ports; | |||
2122 | * based on the DRAM bandwidth bit and DRAM bank switching bit. This | 1970 | * based on the DRAM bandwidth bit and DRAM bank switching bit. This |
2123 | * works with 1MB, 2MB and 4MB configurations (which the Motorola boards | 1971 | * works with 1MB, 2MB and 4MB configurations (which the Motorola boards |
2124 | * seem to have. */ | 1972 | * seem to have. */ |
2125 | static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase) | 1973 | static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase) |
2126 | { | 1974 | { |
2127 | unsigned long mem; | 1975 | unsigned long mem; |
2128 | unsigned char SRF; | 1976 | unsigned char SRF; |
@@ -2188,8 +2036,7 @@ static void get_pci_addrs(const struct pci_dev *pdev, | |||
2188 | 2036 | ||
2189 | static void cirrusfb_pci_unmap(struct fb_info *info) | 2037 | static void cirrusfb_pci_unmap(struct fb_info *info) |
2190 | { | 2038 | { |
2191 | struct cirrusfb_info *cinfo = info->par; | 2039 | struct pci_dev *pdev = to_pci_dev(info->device); |
2192 | struct pci_dev *pdev = cinfo->pdev; | ||
2193 | 2040 | ||
2194 | iounmap(info->screen_base); | 2041 | iounmap(info->screen_base); |
2195 | #if 0 /* if system didn't claim this region, we would... */ | 2042 | #if 0 /* if system didn't claim this region, we would... */ |
@@ -2205,20 +2052,22 @@ static void cirrusfb_pci_unmap(struct fb_info *info) | |||
2205 | static void __devexit cirrusfb_zorro_unmap(struct fb_info *info) | 2052 | static void __devexit cirrusfb_zorro_unmap(struct fb_info *info) |
2206 | { | 2053 | { |
2207 | struct cirrusfb_info *cinfo = info->par; | 2054 | struct cirrusfb_info *cinfo = info->par; |
2208 | zorro_release_device(cinfo->zdev); | 2055 | struct zorro_dev *zdev = to_zorro_dev(info->device); |
2056 | |||
2057 | zorro_release_device(zdev); | ||
2209 | 2058 | ||
2210 | if (cinfo->btype == BT_PICASSO4) { | 2059 | if (cinfo->btype == BT_PICASSO4) { |
2211 | cinfo->regbase -= 0x600000; | 2060 | cinfo->regbase -= 0x600000; |
2212 | iounmap((void *)cinfo->regbase); | 2061 | iounmap((void *)cinfo->regbase); |
2213 | iounmap(info->screen_base); | 2062 | iounmap(info->screen_base); |
2214 | } else { | 2063 | } else { |
2215 | if (zorro_resource_start(cinfo->zdev) > 0x01000000) | 2064 | if (zorro_resource_start(zdev) > 0x01000000) |
2216 | iounmap(info->screen_base); | 2065 | iounmap(info->screen_base); |
2217 | } | 2066 | } |
2218 | } | 2067 | } |
2219 | #endif /* CONFIG_ZORRO */ | 2068 | #endif /* CONFIG_ZORRO */ |
2220 | 2069 | ||
2221 | static int cirrusfb_set_fbinfo(struct fb_info *info) | 2070 | static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) |
2222 | { | 2071 | { |
2223 | struct cirrusfb_info *cinfo = info->par; | 2072 | struct cirrusfb_info *cinfo = info->par; |
2224 | struct fb_var_screeninfo *var = &info->var; | 2073 | struct fb_var_screeninfo *var = &info->var; |
@@ -2235,7 +2084,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info) | |||
2235 | if (cinfo->btype == BT_GD5480) { | 2084 | if (cinfo->btype == BT_GD5480) { |
2236 | if (var->bits_per_pixel == 16) | 2085 | if (var->bits_per_pixel == 16) |
2237 | info->screen_base += 1 * MB_; | 2086 | info->screen_base += 1 * MB_; |
2238 | if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32) | 2087 | if (var->bits_per_pixel == 32) |
2239 | info->screen_base += 2 * MB_; | 2088 | info->screen_base += 2 * MB_; |
2240 | } | 2089 | } |
2241 | 2090 | ||
@@ -2262,7 +2111,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info) | |||
2262 | return 0; | 2111 | return 0; |
2263 | } | 2112 | } |
2264 | 2113 | ||
2265 | static int cirrusfb_register(struct fb_info *info) | 2114 | static int __devinit cirrusfb_register(struct fb_info *info) |
2266 | { | 2115 | { |
2267 | struct cirrusfb_info *cinfo = info->par; | 2116 | struct cirrusfb_info *cinfo = info->par; |
2268 | int err; | 2117 | int err; |
@@ -2278,23 +2127,27 @@ static int cirrusfb_register(struct fb_info *info) | |||
2278 | /* sanity checks */ | 2127 | /* sanity checks */ |
2279 | assert(btype != BT_NONE); | 2128 | assert(btype != BT_NONE); |
2280 | 2129 | ||
2130 | /* set all the vital stuff */ | ||
2131 | cirrusfb_set_fbinfo(info); | ||
2132 | |||
2281 | DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); | 2133 | DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); |
2282 | 2134 | ||
2283 | /* Make pretend we've set the var so our structures are in a "good" */ | 2135 | err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); |
2284 | /* state, even though we haven't written the mode to the hw yet... */ | 2136 | if (!err) { |
2285 | info->var = cirrusfb_predefined[cirrusfb_def_mode].var; | 2137 | DPRINTK("wrong initial video mode\n"); |
2138 | err = -EINVAL; | ||
2139 | goto err_dealloc_cmap; | ||
2140 | } | ||
2141 | |||
2286 | info->var.activate = FB_ACTIVATE_NOW; | 2142 | info->var.activate = FB_ACTIVATE_NOW; |
2287 | 2143 | ||
2288 | err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); | 2144 | err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); |
2289 | if (err < 0) { | 2145 | if (err < 0) { |
2290 | /* should never happen */ | 2146 | /* should never happen */ |
2291 | DPRINTK("choking on default var... umm, no good.\n"); | 2147 | DPRINTK("choking on default var... umm, no good.\n"); |
2292 | goto err_unmap_cirrusfb; | 2148 | goto err_dealloc_cmap; |
2293 | } | 2149 | } |
2294 | 2150 | ||
2295 | /* set all the vital stuff */ | ||
2296 | cirrusfb_set_fbinfo(info); | ||
2297 | |||
2298 | err = register_framebuffer(info); | 2151 | err = register_framebuffer(info); |
2299 | if (err < 0) { | 2152 | if (err < 0) { |
2300 | printk(KERN_ERR "cirrusfb: could not register " | 2153 | printk(KERN_ERR "cirrusfb: could not register " |
@@ -2307,7 +2160,6 @@ static int cirrusfb_register(struct fb_info *info) | |||
2307 | 2160 | ||
2308 | err_dealloc_cmap: | 2161 | err_dealloc_cmap: |
2309 | fb_dealloc_cmap(&info->cmap); | 2162 | fb_dealloc_cmap(&info->cmap); |
2310 | err_unmap_cirrusfb: | ||
2311 | cinfo->unmap(info); | 2163 | cinfo->unmap(info); |
2312 | framebuffer_release(info); | 2164 | framebuffer_release(info); |
2313 | return err; | 2165 | return err; |
@@ -2330,8 +2182,8 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info) | |||
2330 | } | 2182 | } |
2331 | 2183 | ||
2332 | #ifdef CONFIG_PCI | 2184 | #ifdef CONFIG_PCI |
2333 | static int cirrusfb_pci_register(struct pci_dev *pdev, | 2185 | static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, |
2334 | const struct pci_device_id *ent) | 2186 | const struct pci_device_id *ent) |
2335 | { | 2187 | { |
2336 | struct cirrusfb_info *cinfo; | 2188 | struct cirrusfb_info *cinfo; |
2337 | struct fb_info *info; | 2189 | struct fb_info *info; |
@@ -2353,7 +2205,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev, | |||
2353 | } | 2205 | } |
2354 | 2206 | ||
2355 | cinfo = info->par; | 2207 | cinfo = info->par; |
2356 | cinfo->pdev = pdev; | ||
2357 | cinfo->btype = btype = (enum cirrus_board) ent->driver_data; | 2208 | cinfo->btype = btype = (enum cirrus_board) ent->driver_data; |
2358 | 2209 | ||
2359 | DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n", | 2210 | DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n", |
@@ -2459,8 +2310,8 @@ static struct pci_driver cirrusfb_pci_driver = { | |||
2459 | #endif /* CONFIG_PCI */ | 2310 | #endif /* CONFIG_PCI */ |
2460 | 2311 | ||
2461 | #ifdef CONFIG_ZORRO | 2312 | #ifdef CONFIG_ZORRO |
2462 | static int cirrusfb_zorro_register(struct zorro_dev *z, | 2313 | static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, |
2463 | const struct zorro_device_id *ent) | 2314 | const struct zorro_device_id *ent) |
2464 | { | 2315 | { |
2465 | struct cirrusfb_info *cinfo; | 2316 | struct cirrusfb_info *cinfo; |
2466 | struct fb_info *info; | 2317 | struct fb_info *info; |
@@ -2489,7 +2340,6 @@ static int cirrusfb_zorro_register(struct zorro_dev *z, | |||
2489 | assert(z); | 2340 | assert(z); |
2490 | assert(btype != BT_NONE); | 2341 | assert(btype != BT_NONE); |
2491 | 2342 | ||
2492 | cinfo->zdev = z; | ||
2493 | board_addr = zorro_resource_start(z); | 2343 | board_addr = zorro_resource_start(z); |
2494 | board_size = zorro_resource_len(z); | 2344 | board_size = zorro_resource_len(z); |
2495 | info->screen_size = size; | 2345 | info->screen_size = size; |
@@ -2621,17 +2471,17 @@ static int __init cirrusfb_setup(char *options) { | |||
2621 | return 0; | 2471 | return 0; |
2622 | 2472 | ||
2623 | while ((this_opt = strsep(&options, ",")) != NULL) { | 2473 | while ((this_opt = strsep(&options, ",")) != NULL) { |
2624 | if (!*this_opt) continue; | 2474 | if (!*this_opt) |
2475 | continue; | ||
2625 | 2476 | ||
2626 | DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); | 2477 | DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); |
2627 | 2478 | ||
2628 | for (i = 0; i < NUM_TOTAL_MODES; i++) { | ||
2629 | sprintf(s, "mode:%s", cirrusfb_predefined[i].name); | ||
2630 | if (strcmp(this_opt, s) == 0) | ||
2631 | cirrusfb_def_mode = i; | ||
2632 | } | ||
2633 | if (!strcmp(this_opt, "noaccel")) | 2479 | if (!strcmp(this_opt, "noaccel")) |
2634 | noaccel = 1; | 2480 | noaccel = 1; |
2481 | else if (!strncmp(this_opt, "mode:", 5)) | ||
2482 | mode_option = this_opt + 5; | ||
2483 | else | ||
2484 | mode_option = this_opt; | ||
2635 | } | 2485 | } |
2636 | return 0; | 2486 | return 0; |
2637 | } | 2487 | } |
@@ -2657,6 +2507,11 @@ static void __exit cirrusfb_exit(void) | |||
2657 | 2507 | ||
2658 | module_init(cirrusfb_init); | 2508 | module_init(cirrusfb_init); |
2659 | 2509 | ||
2510 | module_param(mode_option, charp, 0); | ||
2511 | MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); | ||
2512 | module_param(noaccel, bool, 0); | ||
2513 | MODULE_PARM_DESC(noaccel, "Disable acceleration"); | ||
2514 | |||
2660 | #ifdef MODULE | 2515 | #ifdef MODULE |
2661 | module_exit(cirrusfb_exit); | 2516 | module_exit(cirrusfb_exit); |
2662 | #endif | 2517 | #endif |
@@ -3050,16 +2905,14 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, | |||
3050 | * bestclock() - determine closest possible clock lower(?) than the | 2905 | * bestclock() - determine closest possible clock lower(?) than the |
3051 | * desired pixel clock | 2906 | * desired pixel clock |
3052 | **************************************************************************/ | 2907 | **************************************************************************/ |
3053 | static void bestclock(long freq, long *best, long *nom, | 2908 | static void bestclock(long freq, int *nom, int *den, int *div) |
3054 | long *den, long *div, long maxfreq) | ||
3055 | { | 2909 | { |
3056 | long n, h, d, f; | 2910 | int n, d; |
2911 | long h, diff; | ||
3057 | 2912 | ||
3058 | assert(best != NULL); | ||
3059 | assert(nom != NULL); | 2913 | assert(nom != NULL); |
3060 | assert(den != NULL); | 2914 | assert(den != NULL); |
3061 | assert(div != NULL); | 2915 | assert(div != NULL); |
3062 | assert(maxfreq > 0); | ||
3063 | 2916 | ||
3064 | *nom = 0; | 2917 | *nom = 0; |
3065 | *den = 0; | 2918 | *den = 0; |
@@ -3070,51 +2923,47 @@ static void bestclock(long freq, long *best, long *nom, | |||
3070 | if (freq < 8000) | 2923 | if (freq < 8000) |
3071 | freq = 8000; | 2924 | freq = 8000; |
3072 | 2925 | ||
3073 | if (freq > maxfreq) | 2926 | diff = freq; |
3074 | freq = maxfreq; | ||
3075 | |||
3076 | *best = 0; | ||
3077 | f = freq * 10; | ||
3078 | 2927 | ||
3079 | for (n = 32; n < 128; n++) { | 2928 | for (n = 32; n < 128; n++) { |
3080 | d = (143181 * n) / f; | 2929 | int s = 0; |
2930 | |||
2931 | d = (14318 * n) / freq; | ||
3081 | if ((d >= 7) && (d <= 63)) { | 2932 | if ((d >= 7) && (d <= 63)) { |
3082 | if (d > 31) | 2933 | int temp = d; |
3083 | d = (d / 2) * 2; | 2934 | |
3084 | h = (14318 * n) / d; | 2935 | if (temp > 31) { |
3085 | if (abs(h - freq) < abs(*best - freq)) { | 2936 | s = 1; |
3086 | *best = h; | 2937 | temp >>= 1; |
2938 | } | ||
2939 | h = ((14318 * n) / temp) >> s; | ||
2940 | h = h > freq ? h - freq : freq - h; | ||
2941 | if (h < diff) { | ||
2942 | diff = h; | ||
3087 | *nom = n; | 2943 | *nom = n; |
3088 | if (d < 32) { | 2944 | *den = temp; |
3089 | *den = d; | 2945 | *div = s; |
3090 | *div = 0; | ||
3091 | } else { | ||
3092 | *den = d / 2; | ||
3093 | *div = 1; | ||
3094 | } | ||
3095 | } | 2946 | } |
3096 | } | 2947 | } |
3097 | d = DIV_ROUND_UP(143181 * n, f); | 2948 | d++; |
3098 | if ((d >= 7) && (d <= 63)) { | 2949 | if ((d >= 7) && (d <= 63)) { |
3099 | if (d > 31) | 2950 | if (d > 31) { |
3100 | d = (d / 2) * 2; | 2951 | s = 1; |
3101 | h = (14318 * n) / d; | 2952 | d >>= 1; |
3102 | if (abs(h - freq) < abs(*best - freq)) { | 2953 | } |
3103 | *best = h; | 2954 | h = ((14318 * n) / d) >> s; |
2955 | h = h > freq ? h - freq : freq - h; | ||
2956 | if (h < diff) { | ||
2957 | diff = h; | ||
3104 | *nom = n; | 2958 | *nom = n; |
3105 | if (d < 32) { | 2959 | *den = d; |
3106 | *den = d; | 2960 | *div = s; |
3107 | *div = 0; | ||
3108 | } else { | ||
3109 | *den = d / 2; | ||
3110 | *div = 1; | ||
3111 | } | ||
3112 | } | 2961 | } |
3113 | } | 2962 | } |
3114 | } | 2963 | } |
3115 | 2964 | ||
3116 | DPRINTK("Best possible values for given frequency:\n"); | 2965 | DPRINTK("Best possible values for given frequency:\n"); |
3117 | DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n", | 2966 | DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n", |
3118 | freq, *nom, *den, *div); | 2967 | freq, *nom, *den, *div); |
3119 | 2968 | ||
3120 | DPRINTK("EXIT\n"); | 2969 | DPRINTK("EXIT\n"); |
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 06f87b04f207..2f50a80b413e 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -43,22 +43,6 @@ config VGACON_SOFT_SCROLLBACK_SIZE | |||
43 | buffer. Each 64KB will give you approximately 16 80x25 | 43 | buffer. Each 64KB will give you approximately 16 80x25 |
44 | screenfuls of scrollback buffer | 44 | screenfuls of scrollback buffer |
45 | 45 | ||
46 | config VIDEO_SELECT | ||
47 | bool "Video mode selection support" | ||
48 | depends on X86 && VGA_CONSOLE | ||
49 | ---help--- | ||
50 | This enables support for text mode selection on kernel startup. If | ||
51 | you want to take advantage of some high-resolution text mode your | ||
52 | card's BIOS offers, but the traditional Linux utilities like | ||
53 | SVGATextMode don't, you can say Y here and set the mode using the | ||
54 | "vga=" option from your boot loader (lilo or loadlin) or set | ||
55 | "vga=ask" which brings up a video mode menu on kernel startup. (Try | ||
56 | "man bootparam" or see the documentation of your boot loader about | ||
57 | how to pass options to the kernel.) | ||
58 | |||
59 | Read the file <file:Documentation/svga.txt> for more information | ||
60 | about the Video mode selection support. If unsure, say N. | ||
61 | |||
62 | config MDA_CONSOLE | 46 | config MDA_CONSOLE |
63 | depends on !M68K && !PARISC && ISA | 47 | depends on !M68K && !PARISC && ISA |
64 | tristate "MDA text console (dual-headed) (EXPERIMENTAL)" | 48 | tristate "MDA text console (dual-headed) (EXPERIMENTAL)" |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index c6299e8a041d..64b3d30027b8 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -1855,8 +1855,6 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
1855 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | 1855 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
1856 | struct display *p = &fb_display[vc->vc_num]; | 1856 | struct display *p = &fb_display[vc->vc_num]; |
1857 | int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; | 1857 | int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; |
1858 | unsigned short saved_ec; | ||
1859 | int ret; | ||
1860 | 1858 | ||
1861 | if (fbcon_is_inactive(vc, info)) | 1859 | if (fbcon_is_inactive(vc, info)) |
1862 | return -EINVAL; | 1860 | return -EINVAL; |
@@ -1869,11 +1867,6 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
1869 | * whole screen (prevents flicker). | 1867 | * whole screen (prevents flicker). |
1870 | */ | 1868 | */ |
1871 | 1869 | ||
1872 | saved_ec = vc->vc_video_erase_char; | ||
1873 | vc->vc_video_erase_char = vc->vc_scrl_erase_char; | ||
1874 | |||
1875 | ret = 0; | ||
1876 | |||
1877 | switch (dir) { | 1870 | switch (dir) { |
1878 | case SM_UP: | 1871 | case SM_UP: |
1879 | if (count > vc->vc_rows) /* Maximum realistic size */ | 1872 | if (count > vc->vc_rows) /* Maximum realistic size */ |
@@ -1890,9 +1883,9 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
1890 | scr_memsetw((unsigned short *) (vc->vc_origin + | 1883 | scr_memsetw((unsigned short *) (vc->vc_origin + |
1891 | vc->vc_size_row * | 1884 | vc->vc_size_row * |
1892 | (b - count)), | 1885 | (b - count)), |
1893 | vc->vc_scrl_erase_char, | 1886 | vc->vc_video_erase_char, |
1894 | vc->vc_size_row * count); | 1887 | vc->vc_size_row * count); |
1895 | ret = 1; | 1888 | return 1; |
1896 | break; | 1889 | break; |
1897 | 1890 | ||
1898 | case SCROLL_WRAP_MOVE: | 1891 | case SCROLL_WRAP_MOVE: |
@@ -1962,10 +1955,9 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
1962 | scr_memsetw((unsigned short *) (vc->vc_origin + | 1955 | scr_memsetw((unsigned short *) (vc->vc_origin + |
1963 | vc->vc_size_row * | 1956 | vc->vc_size_row * |
1964 | (b - count)), | 1957 | (b - count)), |
1965 | vc->vc_scrl_erase_char, | 1958 | vc->vc_video_erase_char, |
1966 | vc->vc_size_row * count); | 1959 | vc->vc_size_row * count); |
1967 | ret = 1; | 1960 | return 1; |
1968 | break; | ||
1969 | } | 1961 | } |
1970 | break; | 1962 | break; |
1971 | 1963 | ||
@@ -1982,9 +1974,9 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
1982 | scr_memsetw((unsigned short *) (vc->vc_origin + | 1974 | scr_memsetw((unsigned short *) (vc->vc_origin + |
1983 | vc->vc_size_row * | 1975 | vc->vc_size_row * |
1984 | t), | 1976 | t), |
1985 | vc->vc_scrl_erase_char, | 1977 | vc->vc_video_erase_char, |
1986 | vc->vc_size_row * count); | 1978 | vc->vc_size_row * count); |
1987 | ret = 1; | 1979 | return 1; |
1988 | break; | 1980 | break; |
1989 | 1981 | ||
1990 | case SCROLL_WRAP_MOVE: | 1982 | case SCROLL_WRAP_MOVE: |
@@ -2052,15 +2044,12 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
2052 | scr_memsetw((unsigned short *) (vc->vc_origin + | 2044 | scr_memsetw((unsigned short *) (vc->vc_origin + |
2053 | vc->vc_size_row * | 2045 | vc->vc_size_row * |
2054 | t), | 2046 | t), |
2055 | vc->vc_scrl_erase_char, | 2047 | vc->vc_video_erase_char, |
2056 | vc->vc_size_row * count); | 2048 | vc->vc_size_row * count); |
2057 | ret = 1; | 2049 | return 1; |
2058 | break; | ||
2059 | } | 2050 | } |
2060 | break; | ||
2061 | } | 2051 | } |
2062 | vc->vc_video_erase_char = saved_ec; | 2052 | return 0; |
2063 | return ret; | ||
2064 | } | 2053 | } |
2065 | 2054 | ||
2066 | 2055 | ||
@@ -2400,11 +2389,15 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) | |||
2400 | 2389 | ||
2401 | if (!fbcon_is_inactive(vc, info)) { | 2390 | if (!fbcon_is_inactive(vc, info)) { |
2402 | if (ops->blank_state != blank) { | 2391 | if (ops->blank_state != blank) { |
2392 | int ret = 1; | ||
2393 | |||
2403 | ops->blank_state = blank; | 2394 | ops->blank_state = blank; |
2404 | fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); | 2395 | fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); |
2405 | ops->cursor_flash = (!blank); | 2396 | ops->cursor_flash = (!blank); |
2406 | 2397 | ||
2407 | if (fb_blank(info, blank)) | 2398 | if (info->fbops->fb_blank) |
2399 | ret = info->fbops->fb_blank(blank, info); | ||
2400 | if (ret) | ||
2408 | fbcon_generic_blank(vc, info, blank); | 2401 | fbcon_generic_blank(vc, info, blank); |
2409 | } | 2402 | } |
2410 | 2403 | ||
@@ -2518,9 +2511,6 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, | |||
2518 | c = vc->vc_video_erase_char; | 2511 | c = vc->vc_video_erase_char; |
2519 | vc->vc_video_erase_char = | 2512 | vc->vc_video_erase_char = |
2520 | ((c & 0xfe00) >> 1) | (c & 0xff); | 2513 | ((c & 0xfe00) >> 1) | (c & 0xff); |
2521 | c = vc->vc_scrl_erase_char; | ||
2522 | vc->vc_scrl_erase_char = | ||
2523 | ((c & 0xFE00) >> 1) | (c & 0xFF); | ||
2524 | vc->vc_attr >>= 1; | 2514 | vc->vc_attr >>= 1; |
2525 | } | 2515 | } |
2526 | } else if (!vc->vc_hi_font_mask && cnt == 512) { | 2516 | } else if (!vc->vc_hi_font_mask && cnt == 512) { |
@@ -2551,14 +2541,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, | |||
2551 | if (vc->vc_can_do_color) { | 2541 | if (vc->vc_can_do_color) { |
2552 | vc->vc_video_erase_char = | 2542 | vc->vc_video_erase_char = |
2553 | ((c & 0xff00) << 1) | (c & 0xff); | 2543 | ((c & 0xff00) << 1) | (c & 0xff); |
2554 | c = vc->vc_scrl_erase_char; | ||
2555 | vc->vc_scrl_erase_char = | ||
2556 | ((c & 0xFF00) << 1) | (c & 0xFF); | ||
2557 | vc->vc_attr <<= 1; | 2544 | vc->vc_attr <<= 1; |
2558 | } else { | 2545 | } else |
2559 | vc->vc_video_erase_char = c & ~0x100; | 2546 | vc->vc_video_erase_char = c & ~0x100; |
2560 | vc->vc_scrl_erase_char = c & ~0x100; | ||
2561 | } | ||
2562 | } | 2547 | } |
2563 | 2548 | ||
2564 | } | 2549 | } |
@@ -2992,8 +2977,8 @@ static void fbcon_set_all_vcs(struct fb_info *info) | |||
2992 | p = &fb_display[vc->vc_num]; | 2977 | p = &fb_display[vc->vc_num]; |
2993 | set_blitting_type(vc, info); | 2978 | set_blitting_type(vc, info); |
2994 | var_to_display(p, &info->var, info); | 2979 | var_to_display(p, &info->var, info); |
2995 | cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres); | 2980 | cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); |
2996 | rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres); | 2981 | rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); |
2997 | cols /= vc->vc_font.width; | 2982 | cols /= vc->vc_font.width; |
2998 | rows /= vc->vc_font.height; | 2983 | rows /= vc->vc_font.height; |
2999 | vc_resize(vc, cols, rows); | 2984 | vc_resize(vc, cols, rows); |
@@ -3588,8 +3573,8 @@ static int __init fb_console_init(void) | |||
3588 | 3573 | ||
3589 | acquire_console_sem(); | 3574 | acquire_console_sem(); |
3590 | fb_register_client(&fbcon_event_notifier); | 3575 | fb_register_client(&fbcon_event_notifier); |
3591 | fbcon_device = device_create_drvdata(fb_class, NULL, MKDEV(0, 0), | 3576 | fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL, |
3592 | NULL, "fbcon"); | 3577 | "fbcon"); |
3593 | 3578 | ||
3594 | if (IS_ERR(fbcon_device)) { | 3579 | if (IS_ERR(fbcon_device)) { |
3595 | printk(KERN_WARNING "Unable to create device " | 3580 | printk(KERN_WARNING "Unable to create device " |
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index a6e38e9ea73f..89a346880ec0 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h | |||
@@ -110,7 +110,7 @@ static inline int mono_col(const struct fb_info *info) | |||
110 | __u32 max_len; | 110 | __u32 max_len; |
111 | max_len = max(info->var.green.length, info->var.red.length); | 111 | max_len = max(info->var.green.length, info->var.red.length); |
112 | max_len = max(info->var.blue.length, max_len); | 112 | max_len = max(info->var.blue.length, max_len); |
113 | return ~(0xfff << (max_len & 0xff)); | 113 | return (~(0xfff << max_len)) & 0xff; |
114 | } | 114 | } |
115 | 115 | ||
116 | static inline int attr_col_ec(int shift, struct vc_data *vc, | 116 | static inline int attr_col_ec(int shift, struct vc_data *vc, |
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 9901064199bd..dd3eaaad4441 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c | |||
@@ -533,7 +533,7 @@ static void mdacon_cursor(struct vc_data *c, int mode) | |||
533 | 533 | ||
534 | static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines) | 534 | static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines) |
535 | { | 535 | { |
536 | u16 eattr = mda_convert_attr(c->vc_scrl_erase_char); | 536 | u16 eattr = mda_convert_attr(c->vc_video_erase_char); |
537 | 537 | ||
538 | if (!lines) | 538 | if (!lines) |
539 | return 0; | 539 | return 0; |
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 4055dbdd1b42..491c1c1baf4c 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c | |||
@@ -170,12 +170,12 @@ static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count) | |||
170 | switch (dir) { | 170 | switch (dir) { |
171 | case SM_UP: | 171 | case SM_UP: |
172 | sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); | 172 | sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); |
173 | sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_scrl_erase_char); | 173 | sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char); |
174 | break; | 174 | break; |
175 | 175 | ||
176 | case SM_DOWN: | 176 | case SM_DOWN: |
177 | sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); | 177 | sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); |
178 | sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_scrl_erase_char); | 178 | sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char); |
179 | break; | 179 | break; |
180 | } | 180 | } |
181 | 181 | ||
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index bd1f57b259d9..448d209a0bf2 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -239,8 +239,7 @@ static void vgacon_restore_screen(struct vc_data *c) | |||
239 | 239 | ||
240 | static int vgacon_scrolldelta(struct vc_data *c, int lines) | 240 | static int vgacon_scrolldelta(struct vc_data *c, int lines) |
241 | { | 241 | { |
242 | int start, end, count, soff, diff; | 242 | int start, end, count, soff; |
243 | void *d, *s; | ||
244 | 243 | ||
245 | if (!lines) { | 244 | if (!lines) { |
246 | c->vc_visible_origin = c->vc_origin; | 245 | c->vc_visible_origin = c->vc_origin; |
@@ -287,29 +286,29 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) | |||
287 | if (count > c->vc_rows) | 286 | if (count > c->vc_rows) |
288 | count = c->vc_rows; | 287 | count = c->vc_rows; |
289 | 288 | ||
290 | diff = c->vc_rows - count; | 289 | if (count) { |
290 | int copysize; | ||
291 | 291 | ||
292 | d = (void *) c->vc_origin; | 292 | int diff = c->vc_rows - count; |
293 | s = (void *) c->vc_screenbuf; | 293 | void *d = (void *) c->vc_origin; |
294 | void *s = (void *) c->vc_screenbuf; | ||
294 | 295 | ||
295 | while (count--) { | 296 | count *= c->vc_size_row; |
296 | scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row); | 297 | /* how much memory to end of buffer left? */ |
297 | d += c->vc_size_row; | 298 | copysize = min(count, vgacon_scrollback_size - soff); |
298 | soff += c->vc_size_row; | 299 | scr_memcpyw(d, vgacon_scrollback + soff, copysize); |
300 | d += copysize; | ||
301 | count -= copysize; | ||
299 | 302 | ||
300 | if (soff >= vgacon_scrollback_size) | 303 | if (count) { |
301 | soff = 0; | 304 | scr_memcpyw(d, vgacon_scrollback, count); |
302 | } | 305 | d += count; |
306 | } | ||
303 | 307 | ||
304 | if (diff == c->vc_rows) { | 308 | if (diff) |
309 | scr_memcpyw(d, s, diff * c->vc_size_row); | ||
310 | } else | ||
305 | vgacon_cursor(c, CM_MOVE); | 311 | vgacon_cursor(c, CM_MOVE); |
306 | } else { | ||
307 | while (diff--) { | ||
308 | scr_memcpyw(d, s, c->vc_size_row); | ||
309 | d += c->vc_size_row; | ||
310 | s += c->vc_size_row; | ||
311 | } | ||
312 | } | ||
313 | 312 | ||
314 | return 1; | 313 | return 1; |
315 | } | 314 | } |
@@ -1350,7 +1349,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, | |||
1350 | } else | 1349 | } else |
1351 | c->vc_origin += delta; | 1350 | c->vc_origin += delta; |
1352 | scr_memsetw((u16 *) (c->vc_origin + c->vc_screenbuf_size - | 1351 | scr_memsetw((u16 *) (c->vc_origin + c->vc_screenbuf_size - |
1353 | delta), c->vc_scrl_erase_char, | 1352 | delta), c->vc_video_erase_char, |
1354 | delta); | 1353 | delta); |
1355 | } else { | 1354 | } else { |
1356 | if (oldo - delta < vga_vram_base) { | 1355 | if (oldo - delta < vga_vram_base) { |
@@ -1363,7 +1362,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, | |||
1363 | } else | 1362 | } else |
1364 | c->vc_origin -= delta; | 1363 | c->vc_origin -= delta; |
1365 | c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; | 1364 | c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; |
1366 | scr_memsetw((u16 *) (c->vc_origin), c->vc_scrl_erase_char, | 1365 | scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char, |
1367 | delta); | 1366 | delta); |
1368 | } | 1367 | } |
1369 | c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; | 1368 | c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; |
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c index 6ef800bdf482..4830b1bf51e5 100644 --- a/drivers/video/display/display-sysfs.c +++ b/drivers/video/display/display-sysfs.c | |||
@@ -153,12 +153,9 @@ struct display_device *display_device_register(struct display_driver *driver, | |||
153 | mutex_unlock(&allocated_dsp_lock); | 153 | mutex_unlock(&allocated_dsp_lock); |
154 | 154 | ||
155 | if (!ret) { | 155 | if (!ret) { |
156 | new_dev->dev = device_create_drvdata(display_class, | 156 | new_dev->dev = device_create(display_class, parent, |
157 | parent, | 157 | MKDEV(0, 0), new_dev, |
158 | MKDEV(0,0), | 158 | "display%d", new_dev->idx); |
159 | new_dev, | ||
160 | "display%d", | ||
161 | new_dev->idx); | ||
162 | if (!IS_ERR(new_dev->dev)) { | 159 | if (!IS_ERR(new_dev->dev)) { |
163 | new_dev->parent = parent; | 160 | new_dev->parent = parent; |
164 | new_dev->driver = driver; | 161 | new_dev->driver = driver; |
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index bd779ae44b1e..daf9b81878a4 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/fb.h> | 12 | #include <linux/fb.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/screen_info.h> | 14 | #include <linux/screen_info.h> |
15 | #include <linux/dmi.h> | ||
15 | 16 | ||
16 | #include <video/vga.h> | 17 | #include <video/vga.h> |
17 | 18 | ||
@@ -33,6 +34,105 @@ static struct fb_fix_screeninfo efifb_fix __initdata = { | |||
33 | .visual = FB_VISUAL_TRUECOLOR, | 34 | .visual = FB_VISUAL_TRUECOLOR, |
34 | }; | 35 | }; |
35 | 36 | ||
37 | enum { | ||
38 | M_I17, /* 17-Inch iMac */ | ||
39 | M_I20, /* 20-Inch iMac */ | ||
40 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ | ||
41 | M_I24, /* 24-Inch iMac */ | ||
42 | M_MINI, /* Mac Mini */ | ||
43 | M_MB, /* MacBook */ | ||
44 | M_MB_2, /* MacBook, 2nd rev. */ | ||
45 | M_MB_3, /* MacBook, 3rd rev. */ | ||
46 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ | ||
47 | M_MBA, /* MacBook Air */ | ||
48 | M_MBP, /* MacBook Pro */ | ||
49 | M_MBP_2, /* MacBook Pro 2nd gen */ | ||
50 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ | ||
51 | M_MBP_4, /* MacBook Pro, 4th gen */ | ||
52 | M_UNKNOWN /* placeholder */ | ||
53 | }; | ||
54 | |||
55 | static struct efifb_dmi_info { | ||
56 | char *optname; | ||
57 | unsigned long base; | ||
58 | int stride; | ||
59 | int width; | ||
60 | int height; | ||
61 | } dmi_list[] = { | ||
62 | [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 }, | ||
63 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ | ||
64 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, | ||
65 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */ | ||
66 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 }, | ||
67 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 }, | ||
68 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 }, | ||
69 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 }, | ||
70 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */ | ||
71 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 }, | ||
72 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 }, | ||
73 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0 } | ||
74 | }; | ||
75 | |||
76 | static int set_system(const struct dmi_system_id *id); | ||
77 | |||
78 | #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ | ||
79 | { set_system, name, { \ | ||
80 | DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ | ||
81 | DMI_MATCH(DMI_PRODUCT_NAME, name) }, \ | ||
82 | &dmi_list[enumid] } | ||
83 | |||
84 | static struct dmi_system_id __initdata dmi_system_table[] = { | ||
85 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), | ||
86 | /* At least one of these two will be right; maybe both? */ | ||
87 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), | ||
88 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20), | ||
89 | /* At least one of these two will be right; maybe both? */ | ||
90 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), | ||
91 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), | ||
92 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), | ||
93 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), | ||
94 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), | ||
95 | /* At least one of these two will be right; maybe both? */ | ||
96 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), | ||
97 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB), | ||
98 | /* At least one of these two will be right; maybe both? */ | ||
99 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), | ||
100 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), | ||
101 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), | ||
102 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), | ||
103 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), | ||
104 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), | ||
105 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), | ||
106 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), | ||
107 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), | ||
108 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), | ||
109 | {}, | ||
110 | }; | ||
111 | |||
112 | static int set_system(const struct dmi_system_id *id) | ||
113 | { | ||
114 | struct efifb_dmi_info *info = id->driver_data; | ||
115 | if (info->base == 0) | ||
116 | return -ENODEV; | ||
117 | |||
118 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " | ||
119 | "(%dx%d, stride %d)\n", id->ident, | ||
120 | (void *)info->base, info->width, info->height, | ||
121 | info->stride); | ||
122 | |||
123 | /* Trust the bootloader over the DMI tables */ | ||
124 | if (screen_info.lfb_base == 0) | ||
125 | screen_info.lfb_base = info->base; | ||
126 | if (screen_info.lfb_linelength == 0) | ||
127 | screen_info.lfb_linelength = info->stride; | ||
128 | if (screen_info.lfb_width == 0) | ||
129 | screen_info.lfb_width = info->width; | ||
130 | if (screen_info.lfb_height == 0) | ||
131 | screen_info.lfb_height = info->height; | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
36 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, | 136 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, |
37 | unsigned blue, unsigned transp, | 137 | unsigned blue, unsigned transp, |
38 | struct fb_info *info) | 138 | struct fb_info *info) |
@@ -67,6 +167,38 @@ static struct fb_ops efifb_ops = { | |||
67 | .fb_imageblit = cfb_imageblit, | 167 | .fb_imageblit = cfb_imageblit, |
68 | }; | 168 | }; |
69 | 169 | ||
170 | static int __init efifb_setup(char *options) | ||
171 | { | ||
172 | char *this_opt; | ||
173 | int i; | ||
174 | |||
175 | if (!options || !*options) | ||
176 | return 0; | ||
177 | |||
178 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
179 | if (!*this_opt) continue; | ||
180 | |||
181 | for (i = 0; i < M_UNKNOWN; i++) { | ||
182 | if (!strcmp(this_opt, dmi_list[i].optname) && | ||
183 | dmi_list[i].base != 0) { | ||
184 | screen_info.lfb_base = dmi_list[i].base; | ||
185 | screen_info.lfb_linelength = dmi_list[i].stride; | ||
186 | screen_info.lfb_width = dmi_list[i].width; | ||
187 | screen_info.lfb_height = dmi_list[i].height; | ||
188 | } | ||
189 | } | ||
190 | if (!strncmp(this_opt, "base:", 5)) | ||
191 | screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0); | ||
192 | else if (!strncmp(this_opt, "stride:", 7)) | ||
193 | screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4; | ||
194 | else if (!strncmp(this_opt, "height:", 7)) | ||
195 | screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0); | ||
196 | else if (!strncmp(this_opt, "width:", 6)) | ||
197 | screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0); | ||
198 | } | ||
199 | return 0; | ||
200 | } | ||
201 | |||
70 | static int __init efifb_probe(struct platform_device *dev) | 202 | static int __init efifb_probe(struct platform_device *dev) |
71 | { | 203 | { |
72 | struct fb_info *info; | 204 | struct fb_info *info; |
@@ -74,6 +206,26 @@ static int __init efifb_probe(struct platform_device *dev) | |||
74 | unsigned int size_vmode; | 206 | unsigned int size_vmode; |
75 | unsigned int size_remap; | 207 | unsigned int size_remap; |
76 | unsigned int size_total; | 208 | unsigned int size_total; |
209 | int request_succeeded = 0; | ||
210 | |||
211 | printk(KERN_INFO "efifb: probing for efifb\n"); | ||
212 | |||
213 | if (!screen_info.lfb_depth) | ||
214 | screen_info.lfb_depth = 32; | ||
215 | if (!screen_info.pages) | ||
216 | screen_info.pages = 1; | ||
217 | |||
218 | /* just assume they're all unset if any are */ | ||
219 | if (!screen_info.blue_size) { | ||
220 | screen_info.blue_size = 8; | ||
221 | screen_info.blue_pos = 0; | ||
222 | screen_info.green_size = 8; | ||
223 | screen_info.green_pos = 8; | ||
224 | screen_info.red_size = 8; | ||
225 | screen_info.red_pos = 16; | ||
226 | screen_info.rsvd_size = 8; | ||
227 | screen_info.rsvd_pos = 24; | ||
228 | } | ||
77 | 229 | ||
78 | efifb_fix.smem_start = screen_info.lfb_base; | 230 | efifb_fix.smem_start = screen_info.lfb_base; |
79 | efifb_defined.bits_per_pixel = screen_info.lfb_depth; | 231 | efifb_defined.bits_per_pixel = screen_info.lfb_depth; |
@@ -98,21 +250,25 @@ static int __init efifb_probe(struct platform_device *dev) | |||
98 | * option to simply use size_total as that | 250 | * option to simply use size_total as that |
99 | * wastes plenty of kernel address space. */ | 251 | * wastes plenty of kernel address space. */ |
100 | size_remap = size_vmode * 2; | 252 | size_remap = size_vmode * 2; |
101 | if (size_remap < size_vmode) | ||
102 | size_remap = size_vmode; | ||
103 | if (size_remap > size_total) | 253 | if (size_remap > size_total) |
104 | size_remap = size_total; | 254 | size_remap = size_total; |
255 | if (size_remap % PAGE_SIZE) | ||
256 | size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE); | ||
105 | efifb_fix.smem_len = size_remap; | 257 | efifb_fix.smem_len = size_remap; |
106 | 258 | ||
107 | if (!request_mem_region(efifb_fix.smem_start, size_total, "efifb")) | 259 | if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) { |
260 | request_succeeded = 1; | ||
261 | } else { | ||
108 | /* We cannot make this fatal. Sometimes this comes from magic | 262 | /* We cannot make this fatal. Sometimes this comes from magic |
109 | spaces our resource handlers simply don't know about */ | 263 | spaces our resource handlers simply don't know about */ |
110 | printk(KERN_WARNING | 264 | printk(KERN_WARNING |
111 | "efifb: cannot reserve video memory at 0x%lx\n", | 265 | "efifb: cannot reserve video memory at 0x%lx\n", |
112 | efifb_fix.smem_start); | 266 | efifb_fix.smem_start); |
267 | } | ||
113 | 268 | ||
114 | info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); | 269 | info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); |
115 | if (!info) { | 270 | if (!info) { |
271 | printk(KERN_ERR "efifb: cannot allocate framebuffer\n"); | ||
116 | err = -ENOMEM; | 272 | err = -ENOMEM; |
117 | goto err_release_mem; | 273 | goto err_release_mem; |
118 | } | 274 | } |
@@ -125,7 +281,7 @@ static int __init efifb_probe(struct platform_device *dev) | |||
125 | "0x%x @ 0x%lx\n", | 281 | "0x%x @ 0x%lx\n", |
126 | efifb_fix.smem_len, efifb_fix.smem_start); | 282 | efifb_fix.smem_len, efifb_fix.smem_start); |
127 | err = -EIO; | 283 | err = -EIO; |
128 | goto err_unmap; | 284 | goto err_release_fb; |
129 | } | 285 | } |
130 | 286 | ||
131 | printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, " | 287 | printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, " |
@@ -178,25 +334,27 @@ static int __init efifb_probe(struct platform_device *dev) | |||
178 | info->fix = efifb_fix; | 334 | info->fix = efifb_fix; |
179 | info->flags = FBINFO_FLAG_DEFAULT; | 335 | info->flags = FBINFO_FLAG_DEFAULT; |
180 | 336 | ||
181 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { | 337 | if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) { |
182 | err = -ENOMEM; | 338 | printk(KERN_ERR "efifb: cannot allocate colormap\n"); |
183 | goto err_unmap; | 339 | goto err_unmap; |
184 | } | 340 | } |
185 | if (register_framebuffer(info) < 0) { | 341 | if ((err = register_framebuffer(info)) < 0) { |
186 | err = -EINVAL; | 342 | printk(KERN_ERR "efifb: cannot register framebuffer\n"); |
187 | goto err_fb_dealoc; | 343 | goto err_fb_dealoc; |
188 | } | 344 | } |
189 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | 345 | printk(KERN_INFO "fb%d: %s frame buffer device\n", |
190 | info->node, info->fix.id); | 346 | info->node, info->fix.id); |
191 | return 0; | 347 | return 0; |
192 | 348 | ||
193 | err_fb_dealoc: | 349 | err_fb_dealoc: |
194 | fb_dealloc_cmap(&info->cmap); | 350 | fb_dealloc_cmap(&info->cmap); |
195 | err_unmap: | 351 | err_unmap: |
196 | iounmap(info->screen_base); | 352 | iounmap(info->screen_base); |
353 | err_release_fb: | ||
197 | framebuffer_release(info); | 354 | framebuffer_release(info); |
198 | err_release_mem: | 355 | err_release_mem: |
199 | release_mem_region(efifb_fix.smem_start, size_total); | 356 | if (request_succeeded) |
357 | release_mem_region(efifb_fix.smem_start, size_total); | ||
200 | return err; | 358 | return err; |
201 | } | 359 | } |
202 | 360 | ||
@@ -214,9 +372,22 @@ static struct platform_device efifb_device = { | |||
214 | static int __init efifb_init(void) | 372 | static int __init efifb_init(void) |
215 | { | 373 | { |
216 | int ret; | 374 | int ret; |
375 | char *option = NULL; | ||
217 | 376 | ||
218 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) | 377 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) |
219 | return -ENODEV; | 378 | return -ENODEV; |
379 | dmi_check_system(dmi_system_table); | ||
380 | |||
381 | if (fb_get_options("efifb", &option)) | ||
382 | return -ENODEV; | ||
383 | efifb_setup(option); | ||
384 | |||
385 | /* We don't get linelength from UGA Draw Protocol, only from | ||
386 | * EFI Graphics Protocol. So if it's not in DMI, and it's not | ||
387 | * passed in from the user, we really can't use the framebuffer. | ||
388 | */ | ||
389 | if (!screen_info.lfb_linelength) | ||
390 | return -ENODEV; | ||
220 | 391 | ||
221 | ret = platform_driver_register(&efifb_driver); | 392 | ret = platform_driver_register(&efifb_driver); |
222 | 393 | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 98843c2ecf73..217c5118ae9e 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -28,9 +28,7 @@ | |||
28 | #include <linux/proc_fs.h> | 28 | #include <linux/proc_fs.h> |
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/console.h> | 30 | #include <linux/console.h> |
31 | #ifdef CONFIG_KMOD | ||
32 | #include <linux/kmod.h> | 31 | #include <linux/kmod.h> |
33 | #endif | ||
34 | #include <linux/err.h> | 32 | #include <linux/err.h> |
35 | #include <linux/device.h> | 33 | #include <linux/device.h> |
36 | #include <linux/efi.h> | 34 | #include <linux/efi.h> |
@@ -837,13 +835,6 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
837 | return (cnt) ? cnt : err; | 835 | return (cnt) ? cnt : err; |
838 | } | 836 | } |
839 | 837 | ||
840 | #ifdef CONFIG_KMOD | ||
841 | static void try_to_load(int fb) | ||
842 | { | ||
843 | request_module("fb%d", fb); | ||
844 | } | ||
845 | #endif /* CONFIG_KMOD */ | ||
846 | |||
847 | int | 838 | int |
848 | fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) | 839 | fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) |
849 | { | 840 | { |
@@ -979,6 +970,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
979 | 970 | ||
980 | info->flags &= ~FBINFO_MISC_USEREVENT; | 971 | info->flags &= ~FBINFO_MISC_USEREVENT; |
981 | event.info = info; | 972 | event.info = info; |
973 | event.data = &mode; | ||
982 | fb_notifier_call_chain(evnt, &event); | 974 | fb_notifier_call_chain(evnt, &event); |
983 | } | 975 | } |
984 | } | 976 | } |
@@ -1085,10 +1077,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
1085 | return -EINVAL; | 1077 | return -EINVAL; |
1086 | if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) | 1078 | if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) |
1087 | return -EINVAL; | 1079 | return -EINVAL; |
1088 | #ifdef CONFIG_KMOD | ||
1089 | if (!registered_fb[con2fb.framebuffer]) | 1080 | if (!registered_fb[con2fb.framebuffer]) |
1090 | try_to_load(con2fb.framebuffer); | 1081 | request_module("fb%d", con2fb.framebuffer); |
1091 | #endif /* CONFIG_KMOD */ | ||
1092 | if (!registered_fb[con2fb.framebuffer]) | 1082 | if (!registered_fb[con2fb.framebuffer]) |
1093 | return -EINVAL; | 1083 | return -EINVAL; |
1094 | event.info = info; | 1084 | event.info = info; |
@@ -1326,10 +1316,8 @@ fb_open(struct inode *inode, struct file *file) | |||
1326 | if (fbidx >= FB_MAX) | 1316 | if (fbidx >= FB_MAX) |
1327 | return -ENODEV; | 1317 | return -ENODEV; |
1328 | lock_kernel(); | 1318 | lock_kernel(); |
1329 | #ifdef CONFIG_KMOD | ||
1330 | if (!(info = registered_fb[fbidx])) | 1319 | if (!(info = registered_fb[fbidx])) |
1331 | try_to_load(fbidx); | 1320 | request_module("fb%d", fbidx); |
1332 | #endif /* CONFIG_KMOD */ | ||
1333 | if (!(info = registered_fb[fbidx])) { | 1321 | if (!(info = registered_fb[fbidx])) { |
1334 | res = -ENODEV; | 1322 | res = -ENODEV; |
1335 | goto out; | 1323 | goto out; |
@@ -1442,9 +1430,8 @@ register_framebuffer(struct fb_info *fb_info) | |||
1442 | break; | 1430 | break; |
1443 | fb_info->node = i; | 1431 | fb_info->node = i; |
1444 | 1432 | ||
1445 | fb_info->dev = device_create_drvdata(fb_class, fb_info->device, | 1433 | fb_info->dev = device_create(fb_class, fb_info->device, |
1446 | MKDEV(FB_MAJOR, i), NULL, | 1434 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); |
1447 | "fb%d", i); | ||
1448 | if (IS_ERR(fb_info->dev)) { | 1435 | if (IS_ERR(fb_info->dev)) { |
1449 | /* Not fatal */ | 1436 | /* Not fatal */ |
1450 | printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev)); | 1437 | printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev)); |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 6a0aa180c266..5c1a2c01778f 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -564,7 +564,13 @@ static void get_detailed_timing(unsigned char *block, | |||
564 | mode->sync |= FB_SYNC_VERT_HIGH_ACT; | 564 | mode->sync |= FB_SYNC_VERT_HIGH_ACT; |
565 | mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) * | 565 | mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) * |
566 | (V_ACTIVE + V_BLANKING)); | 566 | (V_ACTIVE + V_BLANKING)); |
567 | mode->vmode = 0; | 567 | if (INTERLACED) { |
568 | mode->yres *= 2; | ||
569 | mode->upper_margin *= 2; | ||
570 | mode->lower_margin *= 2; | ||
571 | mode->vsync_len *= 2; | ||
572 | mode->vmode |= FB_VMODE_INTERLACED; | ||
573 | } | ||
568 | mode->flag = FB_MODE_IS_DETAILED; | 574 | mode->flag = FB_MODE_IS_DETAILED; |
569 | 575 | ||
570 | DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000); | 576 | DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000); |
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 7992b13ee68f..9dbb9646081f 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c | |||
@@ -1042,7 +1042,7 @@ static int __devexit ffb_remove(struct of_device *op) | |||
1042 | return 0; | 1042 | return 0; |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | static struct of_device_id ffb_match[] = { | 1045 | static const struct of_device_id ffb_match[] = { |
1046 | { | 1046 | { |
1047 | .name = "SUNW,ffb", | 1047 | .name = "SUNW,ffb", |
1048 | }, | 1048 | }, |
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c index 9366ef2bb5f7..e69de29bb2d1 100644 --- a/drivers/video/imacfb.c +++ b/drivers/video/imacfb.c | |||
@@ -1,376 +0,0 @@ | |||
1 | /* | ||
2 | * framebuffer driver for Intel Based Mac's | ||
3 | * | ||
4 | * (c) 2006 Edgar Hucek <gimli@dark-green.com> | ||
5 | * Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de> | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #include <linux/delay.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/fb.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/ioport.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/screen_info.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/dmi.h> | ||
22 | #include <linux/efi.h> | ||
23 | |||
24 | #include <asm/io.h> | ||
25 | |||
26 | #include <video/vga.h> | ||
27 | |||
28 | typedef enum _MAC_TYPE { | ||
29 | M_I17, | ||
30 | M_I20, | ||
31 | M_MINI, | ||
32 | M_MACBOOK, | ||
33 | M_UNKNOWN | ||
34 | } MAC_TYPE; | ||
35 | |||
36 | /* --------------------------------------------------------------------- */ | ||
37 | |||
38 | static struct fb_var_screeninfo imacfb_defined __initdata = { | ||
39 | .activate = FB_ACTIVATE_NOW, | ||
40 | .height = -1, | ||
41 | .width = -1, | ||
42 | .right_margin = 32, | ||
43 | .upper_margin = 16, | ||
44 | .lower_margin = 4, | ||
45 | .vsync_len = 4, | ||
46 | .vmode = FB_VMODE_NONINTERLACED, | ||
47 | }; | ||
48 | |||
49 | static struct fb_fix_screeninfo imacfb_fix __initdata = { | ||
50 | .id = "IMAC VGA", | ||
51 | .type = FB_TYPE_PACKED_PIXELS, | ||
52 | .accel = FB_ACCEL_NONE, | ||
53 | .visual = FB_VISUAL_TRUECOLOR, | ||
54 | }; | ||
55 | |||
56 | static int inverse; | ||
57 | static int model = M_UNKNOWN; | ||
58 | static int manual_height; | ||
59 | static int manual_width; | ||
60 | |||
61 | static int set_system(const struct dmi_system_id *id) | ||
62 | { | ||
63 | printk(KERN_INFO "imacfb: %s detected - set system to %ld\n", | ||
64 | id->ident, (long)id->driver_data); | ||
65 | |||
66 | model = (long)id->driver_data; | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static struct dmi_system_id __initdata dmi_system_table[] = { | ||
72 | { set_system, "iMac4,1", { | ||
73 | DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), | ||
74 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac4,1") }, (void*)M_I17}, | ||
75 | { set_system, "MacBookPro1,1", { | ||
76 | DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), | ||
77 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro1,1") }, (void*)M_I17}, | ||
78 | { set_system, "MacBook1,1", { | ||
79 | DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), | ||
80 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK}, | ||
81 | { set_system, "Macmini1,1", { | ||
82 | DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), | ||
83 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini1,1")}, (void *)M_MINI}, | ||
84 | {}, | ||
85 | }; | ||
86 | |||
87 | #define DEFAULT_FB_MEM 1024*1024*16 | ||
88 | |||
89 | /* --------------------------------------------------------------------- */ | ||
90 | |||
91 | static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
92 | unsigned blue, unsigned transp, | ||
93 | struct fb_info *info) | ||
94 | { | ||
95 | /* | ||
96 | * Set a single color register. The values supplied are | ||
97 | * already rounded down to the hardware's capabilities | ||
98 | * (according to the entries in the `var' structure). Return | ||
99 | * != 0 for invalid regno. | ||
100 | */ | ||
101 | |||
102 | if (regno >= info->cmap.len) | ||
103 | return 1; | ||
104 | |||
105 | if (regno < 16) { | ||
106 | red >>= 8; | ||
107 | green >>= 8; | ||
108 | blue >>= 8; | ||
109 | ((u32 *)(info->pseudo_palette))[regno] = | ||
110 | (red << info->var.red.offset) | | ||
111 | (green << info->var.green.offset) | | ||
112 | (blue << info->var.blue.offset); | ||
113 | } | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static struct fb_ops imacfb_ops = { | ||
118 | .owner = THIS_MODULE, | ||
119 | .fb_setcolreg = imacfb_setcolreg, | ||
120 | .fb_fillrect = cfb_fillrect, | ||
121 | .fb_copyarea = cfb_copyarea, | ||
122 | .fb_imageblit = cfb_imageblit, | ||
123 | }; | ||
124 | |||
125 | static int __init imacfb_setup(char *options) | ||
126 | { | ||
127 | char *this_opt; | ||
128 | |||
129 | if (!options || !*options) | ||
130 | return 0; | ||
131 | |||
132 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
133 | if (!*this_opt) continue; | ||
134 | |||
135 | if (!strcmp(this_opt, "inverse")) | ||
136 | inverse = 1; | ||
137 | else if (!strcmp(this_opt, "i17")) | ||
138 | model = M_I17; | ||
139 | else if (!strcmp(this_opt, "i20")) | ||
140 | model = M_I20; | ||
141 | else if (!strcmp(this_opt, "mini")) | ||
142 | model = M_MINI; | ||
143 | else if (!strcmp(this_opt, "macbook")) | ||
144 | model = M_MACBOOK; | ||
145 | else if (!strncmp(this_opt, "height:", 7)) | ||
146 | manual_height = simple_strtoul(this_opt+7, NULL, 0); | ||
147 | else if (!strncmp(this_opt, "width:", 6)) | ||
148 | manual_width = simple_strtoul(this_opt+6, NULL, 0); | ||
149 | } | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int __init imacfb_probe(struct platform_device *dev) | ||
154 | { | ||
155 | struct fb_info *info; | ||
156 | int err; | ||
157 | unsigned int size_vmode; | ||
158 | unsigned int size_remap; | ||
159 | unsigned int size_total; | ||
160 | |||
161 | screen_info.lfb_depth = 32; | ||
162 | screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000; | ||
163 | screen_info.pages=1; | ||
164 | screen_info.blue_size = 8; | ||
165 | screen_info.blue_pos = 0; | ||
166 | screen_info.green_size = 8; | ||
167 | screen_info.green_pos = 8; | ||
168 | screen_info.red_size = 8; | ||
169 | screen_info.red_pos = 16; | ||
170 | screen_info.rsvd_size = 8; | ||
171 | screen_info.rsvd_pos = 24; | ||
172 | |||
173 | switch (model) { | ||
174 | case M_I17: | ||
175 | screen_info.lfb_width = 1440; | ||
176 | screen_info.lfb_height = 900; | ||
177 | screen_info.lfb_linelength = 1472 * 4; | ||
178 | screen_info.lfb_base = 0x80010000; | ||
179 | break; | ||
180 | case M_I20: | ||
181 | screen_info.lfb_width = 1680; | ||
182 | screen_info.lfb_height = 1050; | ||
183 | screen_info.lfb_linelength = 1728 * 4; | ||
184 | screen_info.lfb_base = 0x80010000; | ||
185 | break; | ||
186 | case M_MINI: | ||
187 | screen_info.lfb_width = 1024; | ||
188 | screen_info.lfb_height = 768; | ||
189 | screen_info.lfb_linelength = 2048 * 4; | ||
190 | screen_info.lfb_base = 0x80000000; | ||
191 | break; | ||
192 | case M_MACBOOK: | ||
193 | screen_info.lfb_width = 1280; | ||
194 | screen_info.lfb_height = 800; | ||
195 | screen_info.lfb_linelength = 2048 * 4; | ||
196 | screen_info.lfb_base = 0x80000000; | ||
197 | break; | ||
198 | } | ||
199 | |||
200 | /* if the user wants to manually specify height/width, | ||
201 | we will override the defaults */ | ||
202 | /* TODO: eventually get auto-detection working */ | ||
203 | if (manual_height > 0) | ||
204 | screen_info.lfb_height = manual_height; | ||
205 | if (manual_width > 0) | ||
206 | screen_info.lfb_width = manual_width; | ||
207 | |||
208 | imacfb_fix.smem_start = screen_info.lfb_base; | ||
209 | imacfb_defined.bits_per_pixel = screen_info.lfb_depth; | ||
210 | imacfb_defined.xres = screen_info.lfb_width; | ||
211 | imacfb_defined.yres = screen_info.lfb_height; | ||
212 | imacfb_fix.line_length = screen_info.lfb_linelength; | ||
213 | |||
214 | /* size_vmode -- that is the amount of memory needed for the | ||
215 | * used video mode, i.e. the minimum amount of | ||
216 | * memory we need. */ | ||
217 | size_vmode = imacfb_defined.yres * imacfb_fix.line_length; | ||
218 | |||
219 | /* size_total -- all video memory we have. Used for | ||
220 | * entries, ressource allocation and bounds | ||
221 | * checking. */ | ||
222 | size_total = screen_info.lfb_size * 65536; | ||
223 | if (size_total < size_vmode) | ||
224 | size_total = size_vmode; | ||
225 | |||
226 | /* size_remap -- the amount of video memory we are going to | ||
227 | * use for imacfb. With modern cards it is no | ||
228 | * option to simply use size_total as that | ||
229 | * wastes plenty of kernel address space. */ | ||
230 | size_remap = size_vmode * 2; | ||
231 | if (size_remap < size_vmode) | ||
232 | size_remap = size_vmode; | ||
233 | if (size_remap > size_total) | ||
234 | size_remap = size_total; | ||
235 | imacfb_fix.smem_len = size_remap; | ||
236 | |||
237 | if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) { | ||
238 | printk(KERN_WARNING | ||
239 | "imacfb: cannot reserve video memory at 0x%lx\n", | ||
240 | imacfb_fix.smem_start); | ||
241 | /* We cannot make this fatal. Sometimes this comes from magic | ||
242 | spaces our resource handlers simply don't know about */ | ||
243 | } | ||
244 | |||
245 | info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); | ||
246 | if (!info) { | ||
247 | err = -ENOMEM; | ||
248 | goto err_release_mem; | ||
249 | } | ||
250 | info->pseudo_palette = info->par; | ||
251 | info->par = NULL; | ||
252 | |||
253 | info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len); | ||
254 | if (!info->screen_base) { | ||
255 | printk(KERN_ERR "imacfb: abort, cannot ioremap video memory " | ||
256 | "0x%x @ 0x%lx\n", | ||
257 | imacfb_fix.smem_len, imacfb_fix.smem_start); | ||
258 | err = -EIO; | ||
259 | goto err_unmap; | ||
260 | } | ||
261 | |||
262 | printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, " | ||
263 | "using %dk, total %dk\n", | ||
264 | imacfb_fix.smem_start, info->screen_base, | ||
265 | size_remap/1024, size_total/1024); | ||
266 | printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n", | ||
267 | imacfb_defined.xres, imacfb_defined.yres, | ||
268 | imacfb_defined.bits_per_pixel, imacfb_fix.line_length, | ||
269 | screen_info.pages); | ||
270 | |||
271 | imacfb_defined.xres_virtual = imacfb_defined.xres; | ||
272 | imacfb_defined.yres_virtual = imacfb_fix.smem_len / | ||
273 | imacfb_fix.line_length; | ||
274 | printk(KERN_INFO "imacfb: scrolling: redraw\n"); | ||
275 | imacfb_defined.yres_virtual = imacfb_defined.yres; | ||
276 | |||
277 | /* some dummy values for timing to make fbset happy */ | ||
278 | imacfb_defined.pixclock = 10000000 / imacfb_defined.xres * | ||
279 | 1000 / imacfb_defined.yres; | ||
280 | imacfb_defined.left_margin = (imacfb_defined.xres / 8) & 0xf8; | ||
281 | imacfb_defined.hsync_len = (imacfb_defined.xres / 8) & 0xf8; | ||
282 | |||
283 | imacfb_defined.red.offset = screen_info.red_pos; | ||
284 | imacfb_defined.red.length = screen_info.red_size; | ||
285 | imacfb_defined.green.offset = screen_info.green_pos; | ||
286 | imacfb_defined.green.length = screen_info.green_size; | ||
287 | imacfb_defined.blue.offset = screen_info.blue_pos; | ||
288 | imacfb_defined.blue.length = screen_info.blue_size; | ||
289 | imacfb_defined.transp.offset = screen_info.rsvd_pos; | ||
290 | imacfb_defined.transp.length = screen_info.rsvd_size; | ||
291 | |||
292 | printk(KERN_INFO "imacfb: %s: " | ||
293 | "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", | ||
294 | "Truecolor", | ||
295 | screen_info.rsvd_size, | ||
296 | screen_info.red_size, | ||
297 | screen_info.green_size, | ||
298 | screen_info.blue_size, | ||
299 | screen_info.rsvd_pos, | ||
300 | screen_info.red_pos, | ||
301 | screen_info.green_pos, | ||
302 | screen_info.blue_pos); | ||
303 | |||
304 | imacfb_fix.ypanstep = 0; | ||
305 | imacfb_fix.ywrapstep = 0; | ||
306 | |||
307 | /* request failure does not faze us, as vgacon probably has this | ||
308 | * region already (FIXME) */ | ||
309 | request_region(0x3c0, 32, "imacfb"); | ||
310 | |||
311 | info->fbops = &imacfb_ops; | ||
312 | info->var = imacfb_defined; | ||
313 | info->fix = imacfb_fix; | ||
314 | info->flags = FBINFO_FLAG_DEFAULT; | ||
315 | |||
316 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { | ||
317 | err = -ENOMEM; | ||
318 | goto err_unmap; | ||
319 | } | ||
320 | if (register_framebuffer(info)<0) { | ||
321 | err = -EINVAL; | ||
322 | goto err_fb_dealoc; | ||
323 | } | ||
324 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | ||
325 | info->node, info->fix.id); | ||
326 | return 0; | ||
327 | |||
328 | err_fb_dealoc: | ||
329 | fb_dealloc_cmap(&info->cmap); | ||
330 | err_unmap: | ||
331 | iounmap(info->screen_base); | ||
332 | framebuffer_release(info); | ||
333 | err_release_mem: | ||
334 | release_mem_region(imacfb_fix.smem_start, size_total); | ||
335 | return err; | ||
336 | } | ||
337 | |||
338 | static struct platform_driver imacfb_driver = { | ||
339 | .probe = imacfb_probe, | ||
340 | .driver = { | ||
341 | .name = "imacfb", | ||
342 | }, | ||
343 | }; | ||
344 | |||
345 | static struct platform_device imacfb_device = { | ||
346 | .name = "imacfb", | ||
347 | }; | ||
348 | |||
349 | static int __init imacfb_init(void) | ||
350 | { | ||
351 | int ret; | ||
352 | char *option = NULL; | ||
353 | |||
354 | if (!efi_enabled) | ||
355 | return -ENODEV; | ||
356 | if (!dmi_check_system(dmi_system_table)) | ||
357 | return -ENODEV; | ||
358 | if (model == M_UNKNOWN) | ||
359 | return -ENODEV; | ||
360 | |||
361 | if (fb_get_options("imacfb", &option)) | ||
362 | return -ENODEV; | ||
363 | |||
364 | imacfb_setup(option); | ||
365 | ret = platform_driver_register(&imacfb_driver); | ||
366 | |||
367 | if (!ret) { | ||
368 | ret = platform_device_register(&imacfb_device); | ||
369 | if (ret) | ||
370 | platform_driver_unregister(&imacfb_driver); | ||
371 | } | ||
372 | return ret; | ||
373 | } | ||
374 | module_init(imacfb_init); | ||
375 | |||
376 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index 3325fbd68ab3..a50bea614804 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h | |||
@@ -12,9 +12,9 @@ | |||
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | /*** Version/name ***/ | 14 | /*** Version/name ***/ |
15 | #define INTELFB_VERSION "0.9.5" | 15 | #define INTELFB_VERSION "0.9.6" |
16 | #define INTELFB_MODULE_NAME "intelfb" | 16 | #define INTELFB_MODULE_NAME "intelfb" |
17 | #define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM" | 17 | #define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM" |
18 | 18 | ||
19 | 19 | ||
20 | /*** Debug/feature defines ***/ | 20 | /*** Debug/feature defines ***/ |
@@ -58,6 +58,7 @@ | |||
58 | #define PCI_DEVICE_ID_INTEL_915GM 0x2592 | 58 | #define PCI_DEVICE_ID_INTEL_915GM 0x2592 |
59 | #define PCI_DEVICE_ID_INTEL_945G 0x2772 | 59 | #define PCI_DEVICE_ID_INTEL_945G 0x2772 |
60 | #define PCI_DEVICE_ID_INTEL_945GM 0x27A2 | 60 | #define PCI_DEVICE_ID_INTEL_945GM 0x27A2 |
61 | #define PCI_DEVICE_ID_INTEL_945GME 0x27AE | ||
61 | #define PCI_DEVICE_ID_INTEL_965G 0x29A2 | 62 | #define PCI_DEVICE_ID_INTEL_965G 0x29A2 |
62 | #define PCI_DEVICE_ID_INTEL_965GM 0x2A02 | 63 | #define PCI_DEVICE_ID_INTEL_965GM 0x2A02 |
63 | 64 | ||
@@ -160,6 +161,7 @@ enum intel_chips { | |||
160 | INTEL_915GM, | 161 | INTEL_915GM, |
161 | INTEL_945G, | 162 | INTEL_945G, |
162 | INTEL_945GM, | 163 | INTEL_945GM, |
164 | INTEL_945GME, | ||
163 | INTEL_965G, | 165 | INTEL_965G, |
164 | INTEL_965GM, | 166 | INTEL_965GM, |
165 | }; | 167 | }; |
@@ -363,6 +365,7 @@ struct intelfb_info { | |||
363 | ((dinfo)->chipset == INTEL_915GM) || \ | 365 | ((dinfo)->chipset == INTEL_915GM) || \ |
364 | ((dinfo)->chipset == INTEL_945G) || \ | 366 | ((dinfo)->chipset == INTEL_945G) || \ |
365 | ((dinfo)->chipset == INTEL_945GM) || \ | 367 | ((dinfo)->chipset == INTEL_945GM) || \ |
368 | ((dinfo)->chipset == INTEL_945GME) || \ | ||
366 | ((dinfo)->chipset == INTEL_965G) || \ | 369 | ((dinfo)->chipset == INTEL_965G) || \ |
367 | ((dinfo)->chipset == INTEL_965GM)) | 370 | ((dinfo)->chipset == INTEL_965GM)) |
368 | 371 | ||
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c index fcf9fadbf572..5d896b81f4e0 100644 --- a/drivers/video/intelfb/intelfb_i2c.c +++ b/drivers/video/intelfb/intelfb_i2c.c | |||
@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo) | |||
171 | /* has some LVDS + tv-out */ | 171 | /* has some LVDS + tv-out */ |
172 | case INTEL_945G: | 172 | case INTEL_945G: |
173 | case INTEL_945GM: | 173 | case INTEL_945GM: |
174 | case INTEL_945GME: | ||
174 | case INTEL_965G: | 175 | case INTEL_965G: |
175 | case INTEL_965GM: | 176 | case INTEL_965GM: |
176 | /* SDVO ports have a single control bus - 2 devices */ | 177 | /* SDVO ports have a single control bus - 2 devices */ |
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index e44303f9bc52..a09e23649357 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * intelfb | 2 | * intelfb |
3 | * | 3 | * |
4 | * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/ | 4 | * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/ |
5 | * 945G/945GM/965G/965GM integrated graphics chips. | 5 | * 945G/945GM/945GME/965G/965GM integrated graphics chips. |
6 | * | 6 | * |
7 | * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> | 7 | * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> |
8 | * 2004 Sylvain Meyer | 8 | * 2004 Sylvain Meyer |
@@ -102,6 +102,9 @@ | |||
102 | * | 102 | * |
103 | * 04/2008 - Version 0.9.5 | 103 | * 04/2008 - Version 0.9.5 |
104 | * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>) | 104 | * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>) |
105 | * | ||
106 | * 08/2008 - Version 0.9.6 | ||
107 | * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>) | ||
105 | */ | 108 | */ |
106 | 109 | ||
107 | #include <linux/module.h> | 110 | #include <linux/module.h> |
@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = { | |||
183 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, | 186 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, |
184 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, | 187 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, |
185 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM }, | 188 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM }, |
189 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME }, | ||
186 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G }, | 190 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G }, |
187 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM }, | 191 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM }, |
188 | { 0, } | 192 | { 0, } |
@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev, | |||
555 | (ent->device == PCI_DEVICE_ID_INTEL_915GM) || | 559 | (ent->device == PCI_DEVICE_ID_INTEL_915GM) || |
556 | (ent->device == PCI_DEVICE_ID_INTEL_945G) || | 560 | (ent->device == PCI_DEVICE_ID_INTEL_945G) || |
557 | (ent->device == PCI_DEVICE_ID_INTEL_945GM) || | 561 | (ent->device == PCI_DEVICE_ID_INTEL_945GM) || |
562 | (ent->device == PCI_DEVICE_ID_INTEL_945GME) || | ||
558 | (ent->device == PCI_DEVICE_ID_INTEL_965G) || | 563 | (ent->device == PCI_DEVICE_ID_INTEL_965G) || |
559 | (ent->device == PCI_DEVICE_ID_INTEL_965GM)) { | 564 | (ent->device == PCI_DEVICE_ID_INTEL_965GM)) { |
560 | 565 | ||
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 8e6d6a4db0ad..8b26b27c2db6 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo) | |||
143 | dinfo->mobile = 1; | 143 | dinfo->mobile = 1; |
144 | dinfo->pll_index = PLLS_I9xx; | 144 | dinfo->pll_index = PLLS_I9xx; |
145 | return 0; | 145 | return 0; |
146 | case PCI_DEVICE_ID_INTEL_945GME: | ||
147 | dinfo->name = "Intel(R) 945GME"; | ||
148 | dinfo->chipset = INTEL_945GME; | ||
149 | dinfo->mobile = 1; | ||
150 | dinfo->pll_index = PLLS_I9xx; | ||
151 | return 0; | ||
146 | case PCI_DEVICE_ID_INTEL_965G: | 152 | case PCI_DEVICE_ID_INTEL_965G: |
147 | dinfo->name = "Intel(R) 965G"; | 153 | dinfo->name = "Intel(R) 965G"; |
148 | dinfo->chipset = INTEL_965G; | 154 | dinfo->chipset = INTEL_965G; |
@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, | |||
186 | case PCI_DEVICE_ID_INTEL_915GM: | 192 | case PCI_DEVICE_ID_INTEL_915GM: |
187 | case PCI_DEVICE_ID_INTEL_945G: | 193 | case PCI_DEVICE_ID_INTEL_945G: |
188 | case PCI_DEVICE_ID_INTEL_945GM: | 194 | case PCI_DEVICE_ID_INTEL_945GM: |
195 | case PCI_DEVICE_ID_INTEL_945GME: | ||
189 | case PCI_DEVICE_ID_INTEL_965G: | 196 | case PCI_DEVICE_ID_INTEL_965G: |
190 | case PCI_DEVICE_ID_INTEL_965GM: | 197 | case PCI_DEVICE_ID_INTEL_965GM: |
191 | /* 915, 945 and 965 chipsets support a 256MB aperture. | 198 | /* 915, 945 and 965 chipsets support a 256MB aperture. |
diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 13fea61d6ae4..7c7e8c2da9d9 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c | |||
@@ -33,6 +33,7 @@ static int leo_blank(int, struct fb_info *); | |||
33 | 33 | ||
34 | static int leo_mmap(struct fb_info *, struct vm_area_struct *); | 34 | static int leo_mmap(struct fb_info *, struct vm_area_struct *); |
35 | static int leo_ioctl(struct fb_info *, unsigned int, unsigned long); | 35 | static int leo_ioctl(struct fb_info *, unsigned int, unsigned long); |
36 | static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *); | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Frame buffer operations | 39 | * Frame buffer operations |
@@ -42,6 +43,7 @@ static struct fb_ops leo_ops = { | |||
42 | .owner = THIS_MODULE, | 43 | .owner = THIS_MODULE, |
43 | .fb_setcolreg = leo_setcolreg, | 44 | .fb_setcolreg = leo_setcolreg, |
44 | .fb_blank = leo_blank, | 45 | .fb_blank = leo_blank, |
46 | .fb_pan_display = leo_pan_display, | ||
45 | .fb_fillrect = cfb_fillrect, | 47 | .fb_fillrect = cfb_fillrect, |
46 | .fb_copyarea = cfb_copyarea, | 48 | .fb_copyarea = cfb_copyarea, |
47 | .fb_imageblit = cfb_imageblit, | 49 | .fb_imageblit = cfb_imageblit, |
@@ -206,6 +208,60 @@ static void leo_wait(struct leo_lx_krn __iomem *lx_krn) | |||
206 | return; | 208 | return; |
207 | } | 209 | } |
208 | 210 | ||
211 | static void leo_switch_from_graph(struct fb_info *info) | ||
212 | { | ||
213 | struct leo_par *par = (struct leo_par *) info->par; | ||
214 | struct leo_ld_ss0 __iomem *ss = par->ld_ss0; | ||
215 | struct leo_cursor __iomem *cursor = par->cursor; | ||
216 | unsigned long flags; | ||
217 | u32 val; | ||
218 | |||
219 | spin_lock_irqsave(&par->lock, flags); | ||
220 | |||
221 | par->extent = ((info->var.xres - 1) | | ||
222 | ((info->var.yres - 1) << 16)); | ||
223 | |||
224 | sbus_writel(0xffffffff, &ss->wid); | ||
225 | sbus_writel(0xffff, &ss->wmask); | ||
226 | sbus_writel(0, &ss->vclipmin); | ||
227 | sbus_writel(par->extent, &ss->vclipmax); | ||
228 | sbus_writel(0, &ss->fg); | ||
229 | sbus_writel(0xff000000, &ss->planemask); | ||
230 | sbus_writel(0x310850, &ss->rop); | ||
231 | sbus_writel(0, &ss->widclip); | ||
232 | sbus_writel((info->var.xres-1) | ((info->var.yres-1) << 11), | ||
233 | &par->lc_ss0_usr->extent); | ||
234 | sbus_writel(4, &par->lc_ss0_usr->addrspace); | ||
235 | sbus_writel(0x80000000, &par->lc_ss0_usr->fill); | ||
236 | sbus_writel(0, &par->lc_ss0_usr->fontt); | ||
237 | do { | ||
238 | val = sbus_readl(&par->lc_ss0_usr->csr); | ||
239 | } while (val & 0x20000000); | ||
240 | |||
241 | /* setup screen buffer for cfb_* functions */ | ||
242 | sbus_writel(1, &ss->wid); | ||
243 | sbus_writel(0x00ffffff, &ss->planemask); | ||
244 | sbus_writel(0x310b90, &ss->rop); | ||
245 | sbus_writel(0, &par->lc_ss0_usr->addrspace); | ||
246 | |||
247 | /* hide cursor */ | ||
248 | sbus_writel(sbus_readl(&cursor->cur_misc) & ~LEO_CUR_ENABLE, &cursor->cur_misc); | ||
249 | |||
250 | spin_unlock_irqrestore(&par->lock, flags); | ||
251 | } | ||
252 | |||
253 | static int leo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | ||
254 | { | ||
255 | /* We just use this to catch switches out of | ||
256 | * graphics mode. | ||
257 | */ | ||
258 | leo_switch_from_graph(info); | ||
259 | |||
260 | if (var->xoffset || var->yoffset || var->vmode) | ||
261 | return -EINVAL; | ||
262 | return 0; | ||
263 | } | ||
264 | |||
209 | /** | 265 | /** |
210 | * leo_setcolreg - Optional function. Sets a color register. | 266 | * leo_setcolreg - Optional function. Sets a color register. |
211 | * @regno: boolean, 0 copy local, 1 get_user() function | 267 | * @regno: boolean, 0 copy local, 1 get_user() function |
@@ -454,44 +510,6 @@ static void leo_init_wids(struct fb_info *info) | |||
454 | leo_wid_put(info, &wl); | 510 | leo_wid_put(info, &wl); |
455 | } | 511 | } |
456 | 512 | ||
457 | static void leo_switch_from_graph(struct fb_info *info) | ||
458 | { | ||
459 | struct leo_par *par = (struct leo_par *) info->par; | ||
460 | struct leo_ld_ss0 __iomem *ss = par->ld_ss0; | ||
461 | unsigned long flags; | ||
462 | u32 val; | ||
463 | |||
464 | spin_lock_irqsave(&par->lock, flags); | ||
465 | |||
466 | par->extent = ((info->var.xres - 1) | | ||
467 | ((info->var.yres - 1) << 16)); | ||
468 | |||
469 | sbus_writel(0xffffffff, &ss->wid); | ||
470 | sbus_writel(0xffff, &ss->wmask); | ||
471 | sbus_writel(0, &ss->vclipmin); | ||
472 | sbus_writel(par->extent, &ss->vclipmax); | ||
473 | sbus_writel(0, &ss->fg); | ||
474 | sbus_writel(0xff000000, &ss->planemask); | ||
475 | sbus_writel(0x310850, &ss->rop); | ||
476 | sbus_writel(0, &ss->widclip); | ||
477 | sbus_writel((info->var.xres-1) | ((info->var.yres-1) << 11), | ||
478 | &par->lc_ss0_usr->extent); | ||
479 | sbus_writel(4, &par->lc_ss0_usr->addrspace); | ||
480 | sbus_writel(0x80000000, &par->lc_ss0_usr->fill); | ||
481 | sbus_writel(0, &par->lc_ss0_usr->fontt); | ||
482 | do { | ||
483 | val = sbus_readl(&par->lc_ss0_usr->csr); | ||
484 | } while (val & 0x20000000); | ||
485 | |||
486 | /* setup screen buffer for cfb_* functions */ | ||
487 | sbus_writel(1, &ss->wid); | ||
488 | sbus_writel(0x00ffffff, &ss->planemask); | ||
489 | sbus_writel(0x310b90, &ss->rop); | ||
490 | sbus_writel(0, &par->lc_ss0_usr->addrspace); | ||
491 | |||
492 | spin_unlock_irqrestore(&par->lock, flags); | ||
493 | } | ||
494 | |||
495 | static void leo_init_hw(struct fb_info *info) | 513 | static void leo_init_hw(struct fb_info *info) |
496 | { | 514 | { |
497 | struct leo_par *par = (struct leo_par *) info->par; | 515 | struct leo_par *par = (struct leo_par *) info->par; |
@@ -641,7 +659,7 @@ static int __devexit leo_remove(struct of_device *op) | |||
641 | return 0; | 659 | return 0; |
642 | } | 660 | } |
643 | 661 | ||
644 | static struct of_device_id leo_match[] = { | 662 | static const struct of_device_id leo_match[] = { |
645 | { | 663 | { |
646 | .name = "SUNW,leo", | 664 | .name = "SUNW,leo", |
647 | }, | 665 | }, |
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index c02136202792..8e7a275df50c 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c | |||
@@ -1453,6 +1453,13 @@ static struct board { | |||
1453 | MGA_G100, | 1453 | MGA_G100, |
1454 | &vbG100, | 1454 | &vbG100, |
1455 | "MGA-G100 (AGP)"}, | 1455 | "MGA-G100 (AGP)"}, |
1456 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, 0xFF, | ||
1457 | 0, 0, | ||
1458 | DEVF_G200, | ||
1459 | 230000, | ||
1460 | MGA_G200, | ||
1461 | &vbG200, | ||
1462 | "MGA-G200eV (PCI)"}, | ||
1456 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, | 1463 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, |
1457 | 0, 0, | 1464 | 0, 0, |
1458 | DEVF_G200, | 1465 | DEVF_G200, |
@@ -2118,6 +2125,8 @@ static struct pci_device_id matroxfb_devices[] = { | |||
2118 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2125 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2119 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, | 2126 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, |
2120 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2127 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2128 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, | ||
2129 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
2121 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, | 2130 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, |
2122 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2131 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2123 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, | 2132 | {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, |
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c index cc4c038a1b3f..df1f757a6161 100644 --- a/drivers/video/metronomefb.c +++ b/drivers/video/metronomefb.c | |||
@@ -40,29 +40,63 @@ | |||
40 | 40 | ||
41 | #include <asm/unaligned.h> | 41 | #include <asm/unaligned.h> |
42 | 42 | ||
43 | |||
44 | #define DEBUG 1 | ||
45 | #ifdef DEBUG | ||
46 | #define DPRINTK(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a) | ||
47 | #else | ||
48 | #define DPRINTK(f, a...) | ||
49 | #endif | ||
50 | |||
51 | |||
52 | /* Display specific information */ | 43 | /* Display specific information */ |
53 | #define DPY_W 832 | 44 | #define DPY_W 832 |
54 | #define DPY_H 622 | 45 | #define DPY_H 622 |
55 | 46 | ||
47 | static int user_wfm_size; | ||
48 | |||
56 | /* frame differs from image. frame includes non-visible pixels */ | 49 | /* frame differs from image. frame includes non-visible pixels */ |
57 | struct epd_frame { | 50 | struct epd_frame { |
58 | int fw; /* frame width */ | 51 | int fw; /* frame width */ |
59 | int fh; /* frame height */ | 52 | int fh; /* frame height */ |
53 | u16 config[4]; | ||
54 | int wfm_size; | ||
60 | }; | 55 | }; |
61 | 56 | ||
62 | static struct epd_frame epd_frame_table[] = { | 57 | static struct epd_frame epd_frame_table[] = { |
63 | { | 58 | { |
64 | .fw = 832, | 59 | .fw = 832, |
65 | .fh = 622 | 60 | .fh = 622, |
61 | .config = { | ||
62 | 15 /* sdlew */ | ||
63 | | 2 << 8 /* sdosz */ | ||
64 | | 0 << 11 /* sdor */ | ||
65 | | 0 << 12 /* sdces */ | ||
66 | | 0 << 15, /* sdcer */ | ||
67 | 42 /* gdspl */ | ||
68 | | 1 << 8 /* gdr1 */ | ||
69 | | 1 << 9 /* sdshr */ | ||
70 | | 0 << 15, /* gdspp */ | ||
71 | 18 /* gdspw */ | ||
72 | | 0 << 15, /* dispc */ | ||
73 | 599 /* vdlc */ | ||
74 | | 0 << 11 /* dsi */ | ||
75 | | 0 << 12, /* dsic */ | ||
76 | }, | ||
77 | .wfm_size = 47001, | ||
78 | }, | ||
79 | { | ||
80 | .fw = 1088, | ||
81 | .fh = 791, | ||
82 | .config = { | ||
83 | 0x0104, | ||
84 | 0x031f, | ||
85 | 0x0088, | ||
86 | 0x02ff, | ||
87 | }, | ||
88 | .wfm_size = 46770, | ||
89 | }, | ||
90 | { | ||
91 | .fw = 1200, | ||
92 | .fh = 842, | ||
93 | .config = { | ||
94 | 0x0101, | ||
95 | 0x030e, | ||
96 | 0x0012, | ||
97 | 0x0280, | ||
98 | }, | ||
99 | .wfm_size = 46770, | ||
66 | }, | 100 | }, |
67 | }; | 101 | }; |
68 | 102 | ||
@@ -134,9 +168,8 @@ static u16 calc_img_cksum(u16 *start, int length) | |||
134 | } | 168 | } |
135 | 169 | ||
136 | /* here we decode the incoming waveform file and populate metromem */ | 170 | /* here we decode the incoming waveform file and populate metromem */ |
137 | #define EXP_WFORM_SIZE 47001 | 171 | static int __devinit load_waveform(u8 *mem, size_t size, int m, int t, |
138 | static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, | 172 | struct metronomefb_par *par) |
139 | u8 *frame_count) | ||
140 | { | 173 | { |
141 | int tta; | 174 | int tta; |
142 | int wmta; | 175 | int wmta; |
@@ -148,26 +181,31 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, | |||
148 | int wfm_idx, owfm_idx; | 181 | int wfm_idx, owfm_idx; |
149 | int mem_idx = 0; | 182 | int mem_idx = 0; |
150 | struct waveform_hdr *wfm_hdr; | 183 | struct waveform_hdr *wfm_hdr; |
184 | u8 *metromem = par->metromem_wfm; | ||
185 | struct device *dev = par->info->dev; | ||
151 | 186 | ||
152 | if (size != EXP_WFORM_SIZE) { | 187 | if (user_wfm_size) |
153 | printk(KERN_ERR "Error: unexpected size %d != %d\n", size, | 188 | epd_frame_table[par->dt].wfm_size = user_wfm_size; |
154 | EXP_WFORM_SIZE); | 189 | |
190 | if (size != epd_frame_table[par->dt].wfm_size) { | ||
191 | dev_err(dev, "Error: unexpected size %Zd != %d\n", size, | ||
192 | epd_frame_table[par->dt].wfm_size); | ||
155 | return -EINVAL; | 193 | return -EINVAL; |
156 | } | 194 | } |
157 | 195 | ||
158 | wfm_hdr = (struct waveform_hdr *) mem; | 196 | wfm_hdr = (struct waveform_hdr *) mem; |
159 | 197 | ||
160 | if (wfm_hdr->fvsn != 1) { | 198 | if (wfm_hdr->fvsn != 1) { |
161 | printk(KERN_ERR "Error: bad fvsn %x\n", wfm_hdr->fvsn); | 199 | dev_err(dev, "Error: bad fvsn %x\n", wfm_hdr->fvsn); |
162 | return -EINVAL; | 200 | return -EINVAL; |
163 | } | 201 | } |
164 | if (wfm_hdr->luts != 0) { | 202 | if (wfm_hdr->luts != 0) { |
165 | printk(KERN_ERR "Error: bad luts %x\n", wfm_hdr->luts); | 203 | dev_err(dev, "Error: bad luts %x\n", wfm_hdr->luts); |
166 | return -EINVAL; | 204 | return -EINVAL; |
167 | } | 205 | } |
168 | cksum = calc_cksum(32, 47, mem); | 206 | cksum = calc_cksum(32, 47, mem); |
169 | if (cksum != wfm_hdr->wfm_cs) { | 207 | if (cksum != wfm_hdr->wfm_cs) { |
170 | printk(KERN_ERR "Error: bad cksum %x != %x\n", cksum, | 208 | dev_err(dev, "Error: bad cksum %x != %x\n", cksum, |
171 | wfm_hdr->wfm_cs); | 209 | wfm_hdr->wfm_cs); |
172 | return -EINVAL; | 210 | return -EINVAL; |
173 | } | 211 | } |
@@ -175,7 +213,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, | |||
175 | wfm_hdr->trc += 1; | 213 | wfm_hdr->trc += 1; |
176 | for (i = 0; i < 5; i++) { | 214 | for (i = 0; i < 5; i++) { |
177 | if (*(wfm_hdr->stuff2a + i) != 0) { | 215 | if (*(wfm_hdr->stuff2a + i) != 0) { |
178 | printk(KERN_ERR "Error: unexpected value in padding\n"); | 216 | dev_err(dev, "Error: unexpected value in padding\n"); |
179 | return -EINVAL; | 217 | return -EINVAL; |
180 | } | 218 | } |
181 | } | 219 | } |
@@ -200,7 +238,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, | |||
200 | return -EINVAL; | 238 | return -EINVAL; |
201 | cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem); | 239 | cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem); |
202 | if (cksum != mem[cksum_idx]) { | 240 | if (cksum != mem[cksum_idx]) { |
203 | printk(KERN_ERR "Error: bad temperature range table cksum" | 241 | dev_err(dev, "Error: bad temperature range table cksum" |
204 | " %x != %x\n", cksum, mem[cksum_idx]); | 242 | " %x != %x\n", cksum, mem[cksum_idx]); |
205 | return -EINVAL; | 243 | return -EINVAL; |
206 | } | 244 | } |
@@ -212,7 +250,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, | |||
212 | return -EINVAL; | 250 | return -EINVAL; |
213 | cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem); | 251 | cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem); |
214 | if (cksum != mem[cksum_idx]) { | 252 | if (cksum != mem[cksum_idx]) { |
215 | printk(KERN_ERR "Error: bad mode table address cksum" | 253 | dev_err(dev, "Error: bad mode table address cksum" |
216 | " %x != %x\n", cksum, mem[cksum_idx]); | 254 | " %x != %x\n", cksum, mem[cksum_idx]); |
217 | return -EINVAL; | 255 | return -EINVAL; |
218 | } | 256 | } |
@@ -224,7 +262,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, | |||
224 | return -EINVAL; | 262 | return -EINVAL; |
225 | cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem); | 263 | cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem); |
226 | if (cksum != mem[cksum_idx]) { | 264 | if (cksum != mem[cksum_idx]) { |
227 | printk(KERN_ERR "Error: bad temperature table address cksum" | 265 | dev_err(dev, "Error: bad temperature table address cksum" |
228 | " %x != %x\n", cksum, mem[cksum_idx]); | 266 | " %x != %x\n", cksum, mem[cksum_idx]); |
229 | return -EINVAL; | 267 | return -EINVAL; |
230 | } | 268 | } |
@@ -259,11 +297,11 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, | |||
259 | return -EINVAL; | 297 | return -EINVAL; |
260 | cksum = calc_cksum(owfm_idx, cksum_idx, mem); | 298 | cksum = calc_cksum(owfm_idx, cksum_idx, mem); |
261 | if (cksum != mem[cksum_idx]) { | 299 | if (cksum != mem[cksum_idx]) { |
262 | printk(KERN_ERR "Error: bad waveform data cksum" | 300 | dev_err(dev, "Error: bad waveform data cksum" |
263 | " %x != %x\n", cksum, mem[cksum_idx]); | 301 | " %x != %x\n", cksum, mem[cksum_idx]); |
264 | return -EINVAL; | 302 | return -EINVAL; |
265 | } | 303 | } |
266 | *frame_count = (mem_idx/64); | 304 | par->frame_count = (mem_idx/64); |
267 | 305 | ||
268 | return 0; | 306 | return 0; |
269 | } | 307 | } |
@@ -274,15 +312,12 @@ static int metronome_display_cmd(struct metronomefb_par *par) | |||
274 | u16 cs; | 312 | u16 cs; |
275 | u16 opcode; | 313 | u16 opcode; |
276 | static u8 borderval; | 314 | static u8 borderval; |
277 | u8 *ptr; | ||
278 | 315 | ||
279 | /* setup display command | 316 | /* setup display command |
280 | we can't immediately set the opcode since the controller | 317 | we can't immediately set the opcode since the controller |
281 | will try parse the command before we've set it all up | 318 | will try parse the command before we've set it all up |
282 | so we just set cs here and set the opcode at the end */ | 319 | so we just set cs here and set the opcode at the end */ |
283 | 320 | ||
284 | ptr = par->metromem; | ||
285 | |||
286 | if (par->metromem_cmd->opcode == 0xCC40) | 321 | if (par->metromem_cmd->opcode == 0xCC40) |
287 | opcode = cs = 0xCC41; | 322 | opcode = cs = 0xCC41; |
288 | else | 323 | else |
@@ -335,44 +370,17 @@ static int __devinit metronome_powerup_cmd(struct metronomefb_par *par) | |||
335 | 370 | ||
336 | static int __devinit metronome_config_cmd(struct metronomefb_par *par) | 371 | static int __devinit metronome_config_cmd(struct metronomefb_par *par) |
337 | { | 372 | { |
338 | int i; | ||
339 | u16 cs; | ||
340 | |||
341 | /* setup config command | 373 | /* setup config command |
342 | we can't immediately set the opcode since the controller | 374 | we can't immediately set the opcode since the controller |
343 | will try parse the command before we've set it all up | 375 | will try parse the command before we've set it all up */ |
344 | so we just set cs here and set the opcode at the end */ | ||
345 | |||
346 | cs = 0xCC10; | ||
347 | |||
348 | /* set the 12 args ( 8 bytes ) for config. see spec for meanings */ | ||
349 | i = 0; | ||
350 | par->metromem_cmd->args[i] = 15 /* sdlew */ | ||
351 | | 2 << 8 /* sdosz */ | ||
352 | | 0 << 11 /* sdor */ | ||
353 | | 0 << 12 /* sdces */ | ||
354 | | 0 << 15; /* sdcer */ | ||
355 | cs += par->metromem_cmd->args[i++]; | ||
356 | |||
357 | par->metromem_cmd->args[i] = 42 /* gdspl */ | ||
358 | | 1 << 8 /* gdr1 */ | ||
359 | | 1 << 9 /* sdshr */ | ||
360 | | 0 << 15; /* gdspp */ | ||
361 | cs += par->metromem_cmd->args[i++]; | ||
362 | |||
363 | par->metromem_cmd->args[i] = 18 /* gdspw */ | ||
364 | | 0 << 15; /* dispc */ | ||
365 | cs += par->metromem_cmd->args[i++]; | ||
366 | |||
367 | par->metromem_cmd->args[i] = 599 /* vdlc */ | ||
368 | | 0 << 11 /* dsi */ | ||
369 | | 0 << 12; /* dsic */ | ||
370 | cs += par->metromem_cmd->args[i++]; | ||
371 | 376 | ||
377 | memcpy(par->metromem_cmd->args, epd_frame_table[par->dt].config, | ||
378 | sizeof(epd_frame_table[par->dt].config)); | ||
372 | /* the rest are 0 */ | 379 | /* the rest are 0 */ |
373 | memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2); | 380 | memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2); |
374 | 381 | ||
375 | par->metromem_cmd->csum = cs; | 382 | par->metromem_cmd->csum = 0xCC10; |
383 | par->metromem_cmd->csum += calc_img_cksum(par->metromem_cmd->args, 4); | ||
376 | par->metromem_cmd->opcode = 0xCC10; /* config cmd */ | 384 | par->metromem_cmd->opcode = 0xCC10; /* config cmd */ |
377 | 385 | ||
378 | return par->board->met_wait_event(par); | 386 | return par->board->met_wait_event(par); |
@@ -408,12 +416,9 @@ static int __devinit metronome_init_regs(struct metronomefb_par *par) | |||
408 | { | 416 | { |
409 | int res; | 417 | int res; |
410 | 418 | ||
411 | par->board->init_gpio_regs(par); | 419 | res = par->board->setup_io(par); |
412 | 420 | if (res) | |
413 | par->board->init_lcdc_regs(par); | 421 | return res; |
414 | |||
415 | /* now that lcd is setup, setup dma descriptor */ | ||
416 | par->board->post_dma_setup(par); | ||
417 | 422 | ||
418 | res = metronome_powerup_cmd(par); | 423 | res = metronome_powerup_cmd(par); |
419 | if (res) | 424 | if (res) |
@@ -430,16 +435,16 @@ static int __devinit metronome_init_regs(struct metronomefb_par *par) | |||
430 | 435 | ||
431 | static void metronomefb_dpy_update(struct metronomefb_par *par) | 436 | static void metronomefb_dpy_update(struct metronomefb_par *par) |
432 | { | 437 | { |
438 | int fbsize; | ||
433 | u16 cksum; | 439 | u16 cksum; |
434 | unsigned char *buf = (unsigned char __force *)par->info->screen_base; | 440 | unsigned char *buf = (unsigned char __force *)par->info->screen_base; |
435 | 441 | ||
442 | fbsize = par->info->fix.smem_len; | ||
436 | /* copy from vm to metromem */ | 443 | /* copy from vm to metromem */ |
437 | memcpy(par->metromem_img, buf, DPY_W*DPY_H); | 444 | memcpy(par->metromem_img, buf, fbsize); |
438 | 445 | ||
439 | cksum = calc_img_cksum((u16 *) par->metromem_img, | 446 | cksum = calc_img_cksum((u16 *) par->metromem_img, fbsize/2); |
440 | (epd_frame_table[0].fw * DPY_H)/2); | 447 | *((u16 *)(par->metromem_img) + fbsize/2) = cksum; |
441 | *((u16 *)(par->metromem_img) + | ||
442 | (epd_frame_table[0].fw * DPY_H)/2) = cksum; | ||
443 | metronome_display_cmd(par); | 448 | metronome_display_cmd(par); |
444 | } | 449 | } |
445 | 450 | ||
@@ -574,8 +579,10 @@ static int __devinit metronomefb_probe(struct platform_device *dev) | |||
574 | unsigned char *videomemory; | 579 | unsigned char *videomemory; |
575 | struct metronomefb_par *par; | 580 | struct metronomefb_par *par; |
576 | const struct firmware *fw_entry; | 581 | const struct firmware *fw_entry; |
577 | int cmd_size, wfm_size, img_size, padding_size, totalsize; | ||
578 | int i; | 582 | int i; |
583 | int panel_type; | ||
584 | int fw, fh; | ||
585 | int epd_dt_index; | ||
579 | 586 | ||
580 | /* pick up board specific routines */ | 587 | /* pick up board specific routines */ |
581 | board = dev->dev.platform_data; | 588 | board = dev->dev.platform_data; |
@@ -586,96 +593,108 @@ static int __devinit metronomefb_probe(struct platform_device *dev) | |||
586 | if (!try_module_get(board->owner)) | 593 | if (!try_module_get(board->owner)) |
587 | return -ENODEV; | 594 | return -ENODEV; |
588 | 595 | ||
596 | info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev); | ||
597 | if (!info) | ||
598 | goto err; | ||
599 | |||
589 | /* we have two blocks of memory. | 600 | /* we have two blocks of memory. |
590 | info->screen_base which is vm, and is the fb used by apps. | 601 | info->screen_base which is vm, and is the fb used by apps. |
591 | par->metromem which is physically contiguous memory and | 602 | par->metromem which is physically contiguous memory and |
592 | contains the display controller commands, waveform, | 603 | contains the display controller commands, waveform, |
593 | processed image data and padding. this is the data pulled | 604 | processed image data and padding. this is the data pulled |
594 | by the device's LCD controller and pushed to Metronome */ | 605 | by the device's LCD controller and pushed to Metronome. |
606 | the metromem memory is allocated by the board driver and | ||
607 | is provided to us */ | ||
608 | |||
609 | panel_type = board->get_panel_type(); | ||
610 | switch (panel_type) { | ||
611 | case 6: | ||
612 | epd_dt_index = 0; | ||
613 | break; | ||
614 | case 8: | ||
615 | epd_dt_index = 1; | ||
616 | break; | ||
617 | case 97: | ||
618 | epd_dt_index = 2; | ||
619 | break; | ||
620 | default: | ||
621 | dev_err(&dev->dev, "Unexpected panel type. Defaulting to 6\n"); | ||
622 | epd_dt_index = 0; | ||
623 | break; | ||
624 | } | ||
625 | |||
626 | fw = epd_frame_table[epd_dt_index].fw; | ||
627 | fh = epd_frame_table[epd_dt_index].fh; | ||
595 | 628 | ||
596 | videomemorysize = (DPY_W*DPY_H); | 629 | /* we need to add a spare page because our csum caching scheme walks |
630 | * to the end of the page */ | ||
631 | videomemorysize = PAGE_SIZE + (fw * fh); | ||
597 | videomemory = vmalloc(videomemorysize); | 632 | videomemory = vmalloc(videomemorysize); |
598 | if (!videomemory) | 633 | if (!videomemory) |
599 | return -ENOMEM; | 634 | goto err_fb_rel; |
600 | 635 | ||
601 | memset(videomemory, 0, videomemorysize); | 636 | memset(videomemory, 0, videomemorysize); |
602 | 637 | ||
603 | info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev); | ||
604 | if (!info) | ||
605 | goto err_vfree; | ||
606 | |||
607 | info->screen_base = (char __force __iomem *)videomemory; | 638 | info->screen_base = (char __force __iomem *)videomemory; |
608 | info->fbops = &metronomefb_ops; | 639 | info->fbops = &metronomefb_ops; |
609 | 640 | ||
641 | metronomefb_fix.line_length = fw; | ||
642 | metronomefb_var.xres = fw; | ||
643 | metronomefb_var.yres = fh; | ||
644 | metronomefb_var.xres_virtual = fw; | ||
645 | metronomefb_var.yres_virtual = fh; | ||
610 | info->var = metronomefb_var; | 646 | info->var = metronomefb_var; |
611 | info->fix = metronomefb_fix; | 647 | info->fix = metronomefb_fix; |
612 | info->fix.smem_len = videomemorysize; | 648 | info->fix.smem_len = videomemorysize; |
613 | par = info->par; | 649 | par = info->par; |
614 | par->info = info; | 650 | par->info = info; |
615 | par->board = board; | 651 | par->board = board; |
652 | par->dt = epd_dt_index; | ||
616 | init_waitqueue_head(&par->waitq); | 653 | init_waitqueue_head(&par->waitq); |
617 | 654 | ||
618 | /* this table caches per page csum values. */ | 655 | /* this table caches per page csum values. */ |
619 | par->csum_table = vmalloc(videomemorysize/PAGE_SIZE); | 656 | par->csum_table = vmalloc(videomemorysize/PAGE_SIZE); |
620 | if (!par->csum_table) | 657 | if (!par->csum_table) |
658 | goto err_vfree; | ||
659 | |||
660 | /* the physical framebuffer that we use is setup by | ||
661 | * the platform device driver. It will provide us | ||
662 | * with cmd, wfm and image memory in a contiguous area. */ | ||
663 | retval = board->setup_fb(par); | ||
664 | if (retval) { | ||
665 | dev_err(&dev->dev, "Failed to setup fb\n"); | ||
621 | goto err_csum_table; | 666 | goto err_csum_table; |
667 | } | ||
622 | 668 | ||
623 | /* the metromem buffer is divided as follows: | 669 | /* after this point we should have a framebuffer */ |
624 | command | CRC | padding | 670 | if ((!par->metromem_wfm) || (!par->metromem_img) || |
625 | 16kb waveform data | CRC | padding | 671 | (!par->metromem_dma)) { |
626 | image data | CRC | 672 | dev_err(&dev->dev, "fb access failure\n"); |
627 | and an extra 256 bytes for dma descriptors | 673 | retval = -EINVAL; |
628 | eg: IW=832 IH=622 WS=128 | 674 | goto err_csum_table; |
629 | */ | ||
630 | |||
631 | cmd_size = 1 * epd_frame_table[0].fw; | ||
632 | wfm_size = ((16*1024 + 2 + epd_frame_table[0].fw - 1) | ||
633 | / epd_frame_table[0].fw) * epd_frame_table[0].fw; | ||
634 | img_size = epd_frame_table[0].fh * epd_frame_table[0].fw; | ||
635 | padding_size = 4 * epd_frame_table[0].fw; | ||
636 | totalsize = cmd_size + wfm_size + img_size + padding_size; | ||
637 | par->metromemsize = PAGE_ALIGN(totalsize + 256); | ||
638 | DPRINTK("desired memory size = %d\n", par->metromemsize); | ||
639 | dev->dev.coherent_dma_mask = 0xffffffffull; | ||
640 | par->metromem = dma_alloc_writecombine(&dev->dev, par->metromemsize, | ||
641 | &par->metromem_dma, GFP_KERNEL); | ||
642 | if (!par->metromem) { | ||
643 | printk(KERN_ERR | ||
644 | "metronomefb: unable to allocate dma buffer\n"); | ||
645 | goto err_vfree; | ||
646 | } | 675 | } |
647 | 676 | ||
648 | info->fix.smem_start = par->metromem_dma; | 677 | info->fix.smem_start = par->metromem_dma; |
649 | par->metromem_cmd = (struct metromem_cmd *) par->metromem; | ||
650 | par->metromem_wfm = par->metromem + cmd_size; | ||
651 | par->metromem_img = par->metromem + cmd_size + wfm_size; | ||
652 | par->metromem_img_csum = (u16 *) (par->metromem_img + | ||
653 | (epd_frame_table[0].fw * DPY_H)); | ||
654 | DPRINTK("img offset=0x%x\n", cmd_size + wfm_size); | ||
655 | par->metromem_desc = (struct metromem_desc *) (par->metromem + cmd_size | ||
656 | + wfm_size + img_size + padding_size); | ||
657 | par->metromem_desc_dma = par->metromem_dma + cmd_size + wfm_size | ||
658 | + img_size + padding_size; | ||
659 | 678 | ||
660 | /* load the waveform in. assume mode 3, temp 31 for now | 679 | /* load the waveform in. assume mode 3, temp 31 for now |
661 | a) request the waveform file from userspace | 680 | a) request the waveform file from userspace |
662 | b) process waveform and decode into metromem */ | 681 | b) process waveform and decode into metromem */ |
663 | retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev); | 682 | retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev); |
664 | if (retval < 0) { | 683 | if (retval < 0) { |
665 | printk(KERN_ERR "metronomefb: couldn't get waveform\n"); | 684 | dev_err(&dev->dev, "Failed to get waveform\n"); |
666 | goto err_dma_free; | 685 | goto err_csum_table; |
667 | } | 686 | } |
668 | 687 | ||
669 | retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, | 688 | retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, 3, 31, |
670 | par->metromem_wfm, 3, 31, &par->frame_count); | 689 | par); |
671 | release_firmware(fw_entry); | 690 | release_firmware(fw_entry); |
672 | if (retval < 0) { | 691 | if (retval < 0) { |
673 | printk(KERN_ERR "metronomefb: couldn't process waveform\n"); | 692 | dev_err(&dev->dev, "Failed processing waveform\n"); |
674 | goto err_dma_free; | 693 | goto err_csum_table; |
675 | } | 694 | } |
676 | 695 | ||
677 | if (board->setup_irq(info)) | 696 | if (board->setup_irq(info)) |
678 | goto err_dma_free; | 697 | goto err_csum_table; |
679 | 698 | ||
680 | retval = metronome_init_regs(par); | 699 | retval = metronome_init_regs(par); |
681 | if (retval < 0) | 700 | if (retval < 0) |
@@ -688,8 +707,8 @@ static int __devinit metronomefb_probe(struct platform_device *dev) | |||
688 | 707 | ||
689 | retval = fb_alloc_cmap(&info->cmap, 8, 0); | 708 | retval = fb_alloc_cmap(&info->cmap, 8, 0); |
690 | if (retval < 0) { | 709 | if (retval < 0) { |
691 | printk(KERN_ERR "Failed to allocate colormap\n"); | 710 | dev_err(&dev->dev, "Failed to allocate colormap\n"); |
692 | goto err_fb_rel; | 711 | goto err_free_irq; |
693 | } | 712 | } |
694 | 713 | ||
695 | /* set cmap */ | 714 | /* set cmap */ |
@@ -704,7 +723,7 @@ static int __devinit metronomefb_probe(struct platform_device *dev) | |||
704 | 723 | ||
705 | platform_set_drvdata(dev, info); | 724 | platform_set_drvdata(dev, info); |
706 | 725 | ||
707 | printk(KERN_INFO | 726 | dev_dbg(&dev->dev, |
708 | "fb%d: Metronome frame buffer device, using %dK of video" | 727 | "fb%d: Metronome frame buffer device, using %dK of video" |
709 | " memory\n", info->node, videomemorysize >> 10); | 728 | " memory\n", info->node, videomemorysize >> 10); |
710 | 729 | ||
@@ -712,17 +731,15 @@ static int __devinit metronomefb_probe(struct platform_device *dev) | |||
712 | 731 | ||
713 | err_cmap: | 732 | err_cmap: |
714 | fb_dealloc_cmap(&info->cmap); | 733 | fb_dealloc_cmap(&info->cmap); |
715 | err_fb_rel: | ||
716 | framebuffer_release(info); | ||
717 | err_free_irq: | 734 | err_free_irq: |
718 | board->free_irq(info); | 735 | board->cleanup(par); |
719 | err_dma_free: | ||
720 | dma_free_writecombine(&dev->dev, par->metromemsize, par->metromem, | ||
721 | par->metromem_dma); | ||
722 | err_csum_table: | 736 | err_csum_table: |
723 | vfree(par->csum_table); | 737 | vfree(par->csum_table); |
724 | err_vfree: | 738 | err_vfree: |
725 | vfree(videomemory); | 739 | vfree(videomemory); |
740 | err_fb_rel: | ||
741 | framebuffer_release(info); | ||
742 | err: | ||
726 | module_put(board->owner); | 743 | module_put(board->owner); |
727 | return retval; | 744 | return retval; |
728 | } | 745 | } |
@@ -733,15 +750,15 @@ static int __devexit metronomefb_remove(struct platform_device *dev) | |||
733 | 750 | ||
734 | if (info) { | 751 | if (info) { |
735 | struct metronomefb_par *par = info->par; | 752 | struct metronomefb_par *par = info->par; |
753 | |||
754 | unregister_framebuffer(info); | ||
736 | fb_deferred_io_cleanup(info); | 755 | fb_deferred_io_cleanup(info); |
737 | dma_free_writecombine(&dev->dev, par->metromemsize, | ||
738 | par->metromem, par->metromem_dma); | ||
739 | fb_dealloc_cmap(&info->cmap); | 756 | fb_dealloc_cmap(&info->cmap); |
757 | par->board->cleanup(par); | ||
740 | vfree(par->csum_table); | 758 | vfree(par->csum_table); |
741 | unregister_framebuffer(info); | ||
742 | vfree((void __force *)info->screen_base); | 759 | vfree((void __force *)info->screen_base); |
743 | par->board->free_irq(info); | ||
744 | module_put(par->board->owner); | 760 | module_put(par->board->owner); |
761 | dev_dbg(&dev->dev, "calling release\n"); | ||
745 | framebuffer_release(info); | 762 | framebuffer_release(info); |
746 | } | 763 | } |
747 | return 0; | 764 | return 0; |
@@ -766,6 +783,9 @@ static void __exit metronomefb_exit(void) | |||
766 | platform_driver_unregister(&metronomefb_driver); | 783 | platform_driver_unregister(&metronomefb_driver); |
767 | } | 784 | } |
768 | 785 | ||
786 | module_param(user_wfm_size, uint, 0); | ||
787 | MODULE_PARM_DESC(user_wfm_size, "Set custom waveform size"); | ||
788 | |||
769 | module_init(metronomefb_init); | 789 | module_init(metronomefb_init); |
770 | module_exit(metronomefb_exit); | 790 | module_exit(metronomefb_exit); |
771 | 791 | ||
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 25172b2a2a94..bfb802d26d5a 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c | |||
@@ -426,11 +426,11 @@ static void vgaHWProtect(int on) | |||
426 | { | 426 | { |
427 | unsigned char tmp; | 427 | unsigned char tmp; |
428 | 428 | ||
429 | tmp = vga_rseq(NULL, 0x01); | ||
429 | if (on) { | 430 | if (on) { |
430 | /* | 431 | /* |
431 | * Turn off screen and disable sequencer. | 432 | * Turn off screen and disable sequencer. |
432 | */ | 433 | */ |
433 | tmp = vga_rseq(NULL, 0x01); | ||
434 | vga_wseq(NULL, 0x00, 0x01); /* Synchronous Reset */ | 434 | vga_wseq(NULL, 0x00, 0x01); /* Synchronous Reset */ |
435 | vga_wseq(NULL, 0x01, tmp | 0x20); /* disable the display */ | 435 | vga_wseq(NULL, 0x01, tmp | 0x20); /* disable the display */ |
436 | 436 | ||
@@ -439,7 +439,6 @@ static void vgaHWProtect(int on) | |||
439 | /* | 439 | /* |
440 | * Reenable sequencer, then turn on screen. | 440 | * Reenable sequencer, then turn on screen. |
441 | */ | 441 | */ |
442 | tmp = vga_rseq(NULL, 0x01); | ||
443 | vga_wseq(NULL, 0x01, tmp & ~0x20); /* reenable display */ | 442 | vga_wseq(NULL, 0x01, tmp & ~0x20); /* reenable display */ |
444 | vga_wseq(NULL, 0x00, 0x03); /* clear synchronousreset */ | 443 | vga_wseq(NULL, 0x00, 0x03); /* clear synchronousreset */ |
445 | 444 | ||
@@ -558,14 +557,12 @@ neofb_open(struct fb_info *info, int user) | |||
558 | { | 557 | { |
559 | struct neofb_par *par = info->par; | 558 | struct neofb_par *par = info->par; |
560 | 559 | ||
561 | mutex_lock(&par->open_lock); | ||
562 | if (!par->ref_count) { | 560 | if (!par->ref_count) { |
563 | memset(&par->state, 0, sizeof(struct vgastate)); | 561 | memset(&par->state, 0, sizeof(struct vgastate)); |
564 | par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS; | 562 | par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS; |
565 | save_vga(&par->state); | 563 | save_vga(&par->state); |
566 | } | 564 | } |
567 | par->ref_count++; | 565 | par->ref_count++; |
568 | mutex_unlock(&par->open_lock); | ||
569 | 566 | ||
570 | return 0; | 567 | return 0; |
571 | } | 568 | } |
@@ -575,16 +572,13 @@ neofb_release(struct fb_info *info, int user) | |||
575 | { | 572 | { |
576 | struct neofb_par *par = info->par; | 573 | struct neofb_par *par = info->par; |
577 | 574 | ||
578 | mutex_lock(&par->open_lock); | 575 | if (!par->ref_count) |
579 | if (!par->ref_count) { | ||
580 | mutex_unlock(&par->open_lock); | ||
581 | return -EINVAL; | 576 | return -EINVAL; |
582 | } | 577 | |
583 | if (par->ref_count == 1) { | 578 | if (par->ref_count == 1) { |
584 | restore_vga(&par->state); | 579 | restore_vga(&par->state); |
585 | } | 580 | } |
586 | par->ref_count--; | 581 | par->ref_count--; |
587 | mutex_unlock(&par->open_lock); | ||
588 | 582 | ||
589 | return 0; | 583 | return 0; |
590 | } | 584 | } |
@@ -648,10 +642,10 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
648 | var->blue.msb_right = 0; | 642 | var->blue.msb_right = 0; |
649 | var->transp.msb_right = 0; | 643 | var->transp.msb_right = 0; |
650 | 644 | ||
645 | var->transp.offset = 0; | ||
646 | var->transp.length = 0; | ||
651 | switch (var->bits_per_pixel) { | 647 | switch (var->bits_per_pixel) { |
652 | case 8: /* PSEUDOCOLOUR, 256 */ | 648 | case 8: /* PSEUDOCOLOUR, 256 */ |
653 | var->transp.offset = 0; | ||
654 | var->transp.length = 0; | ||
655 | var->red.offset = 0; | 649 | var->red.offset = 0; |
656 | var->red.length = 8; | 650 | var->red.length = 8; |
657 | var->green.offset = 0; | 651 | var->green.offset = 0; |
@@ -661,8 +655,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
661 | break; | 655 | break; |
662 | 656 | ||
663 | case 16: /* DIRECTCOLOUR, 64k */ | 657 | case 16: /* DIRECTCOLOUR, 64k */ |
664 | var->transp.offset = 0; | ||
665 | var->transp.length = 0; | ||
666 | var->red.offset = 11; | 658 | var->red.offset = 11; |
667 | var->red.length = 5; | 659 | var->red.length = 5; |
668 | var->green.offset = 5; | 660 | var->green.offset = 5; |
@@ -672,8 +664,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
672 | break; | 664 | break; |
673 | 665 | ||
674 | case 24: /* TRUECOLOUR, 16m */ | 666 | case 24: /* TRUECOLOUR, 16m */ |
675 | var->transp.offset = 0; | ||
676 | var->transp.length = 0; | ||
677 | var->red.offset = 16; | 667 | var->red.offset = 16; |
678 | var->red.length = 8; | 668 | var->red.length = 8; |
679 | var->green.offset = 8; | 669 | var->green.offset = 8; |
@@ -704,8 +694,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
704 | if (vramlen > 4 * 1024 * 1024) | 694 | if (vramlen > 4 * 1024 * 1024) |
705 | vramlen = 4 * 1024 * 1024; | 695 | vramlen = 4 * 1024 * 1024; |
706 | 696 | ||
707 | if (var->yres_virtual < var->yres) | ||
708 | var->yres_virtual = var->yres; | ||
709 | if (var->xres_virtual < var->xres) | 697 | if (var->xres_virtual < var->xres) |
710 | var->xres_virtual = var->xres; | 698 | var->xres_virtual = var->xres; |
711 | 699 | ||
@@ -722,8 +710,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
722 | if it was possible. We should return -EINVAL, but I disagree */ | 710 | if it was possible. We should return -EINVAL, but I disagree */ |
723 | if (var->yres_virtual < var->yres) | 711 | if (var->yres_virtual < var->yres) |
724 | var->yres = var->yres_virtual; | 712 | var->yres = var->yres_virtual; |
725 | if (var->xres_virtual < var->xres) | ||
726 | var->xres = var->xres_virtual; | ||
727 | if (var->xoffset + var->xres > var->xres_virtual) | 713 | if (var->xoffset + var->xres > var->xres_virtual) |
728 | var->xoffset = var->xres_virtual - var->xres; | 714 | var->xoffset = var->xres_virtual - var->xres; |
729 | if (var->yoffset + var->yres > var->yres_virtual) | 715 | if (var->yoffset + var->yres > var->yres_virtual) |
@@ -1186,8 +1172,11 @@ static int neofb_set_par(struct fb_info *info) | |||
1186 | return 0; | 1172 | return 0; |
1187 | } | 1173 | } |
1188 | 1174 | ||
1189 | static void neofb_update_start(struct fb_info *info, | 1175 | /* |
1190 | struct fb_var_screeninfo *var) | 1176 | * Pan or Wrap the Display |
1177 | */ | ||
1178 | static int neofb_pan_display(struct fb_var_screeninfo *var, | ||
1179 | struct fb_info *info) | ||
1191 | { | 1180 | { |
1192 | struct neofb_par *par = info->par; | 1181 | struct neofb_par *par = info->par; |
1193 | struct vgastate *state = &par->state; | 1182 | struct vgastate *state = &par->state; |
@@ -1216,35 +1205,7 @@ static void neofb_update_start(struct fb_info *info, | |||
1216 | vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0))); | 1205 | vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0))); |
1217 | 1206 | ||
1218 | neoLock(state); | 1207 | neoLock(state); |
1219 | } | ||
1220 | |||
1221 | /* | ||
1222 | * Pan or Wrap the Display | ||
1223 | */ | ||
1224 | static int neofb_pan_display(struct fb_var_screeninfo *var, | ||
1225 | struct fb_info *info) | ||
1226 | { | ||
1227 | u_int y_bottom; | ||
1228 | |||
1229 | y_bottom = var->yoffset; | ||
1230 | |||
1231 | if (!(var->vmode & FB_VMODE_YWRAP)) | ||
1232 | y_bottom += var->yres; | ||
1233 | 1208 | ||
1234 | if (var->xoffset > (var->xres_virtual - var->xres)) | ||
1235 | return -EINVAL; | ||
1236 | if (y_bottom > info->var.yres_virtual) | ||
1237 | return -EINVAL; | ||
1238 | |||
1239 | neofb_update_start(info, var); | ||
1240 | |||
1241 | info->var.xoffset = var->xoffset; | ||
1242 | info->var.yoffset = var->yoffset; | ||
1243 | |||
1244 | if (var->vmode & FB_VMODE_YWRAP) | ||
1245 | info->var.vmode |= FB_VMODE_YWRAP; | ||
1246 | else | ||
1247 | info->var.vmode &= ~FB_VMODE_YWRAP; | ||
1248 | return 0; | 1209 | return 0; |
1249 | } | 1210 | } |
1250 | 1211 | ||
@@ -1992,7 +1953,6 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st | |||
1992 | 1953 | ||
1993 | info->fix.accel = id->driver_data; | 1954 | info->fix.accel = id->driver_data; |
1994 | 1955 | ||
1995 | mutex_init(&par->open_lock); | ||
1996 | par->pci_burst = !nopciburst; | 1956 | par->pci_burst = !nopciburst; |
1997 | par->lcd_stretch = !nostretch; | 1957 | par->lcd_stretch = !nostretch; |
1998 | par->libretto = libretto; | 1958 | par->libretto = libretto; |
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index 6efcf89e7fbe..dfb72f5e4c96 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c | |||
@@ -156,7 +156,7 @@ struct resmap { | |||
156 | }; | 156 | }; |
157 | 157 | ||
158 | static struct { | 158 | static struct { |
159 | u32 base; | 159 | void __iomem *base; |
160 | 160 | ||
161 | struct omapfb_mem_desc mem_desc; | 161 | struct omapfb_mem_desc mem_desc; |
162 | struct resmap *res_map[DISPC_MEMTYPE_NUM]; | 162 | struct resmap *res_map[DISPC_MEMTYPE_NUM]; |
@@ -212,9 +212,9 @@ static void enable_rfbi_mode(int enable) | |||
212 | dispc_write_reg(DISPC_CONTROL, l); | 212 | dispc_write_reg(DISPC_CONTROL, l); |
213 | 213 | ||
214 | /* Set bypass mode in RFBI module */ | 214 | /* Set bypass mode in RFBI module */ |
215 | l = __raw_readl(io_p2v(RFBI_CONTROL)); | 215 | l = __raw_readl(IO_ADDRESS(RFBI_CONTROL)); |
216 | l |= enable ? 0 : (1 << 1); | 216 | l |= enable ? 0 : (1 << 1); |
217 | __raw_writel(l, io_p2v(RFBI_CONTROL)); | 217 | __raw_writel(l, IO_ADDRESS(RFBI_CONTROL)); |
218 | } | 218 | } |
219 | 219 | ||
220 | static void set_lcd_data_lines(int data_lines) | 220 | static void set_lcd_data_lines(int data_lines) |
@@ -1349,14 +1349,19 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, | |||
1349 | 1349 | ||
1350 | memset(&dispc, 0, sizeof(dispc)); | 1350 | memset(&dispc, 0, sizeof(dispc)); |
1351 | 1351 | ||
1352 | dispc.base = io_p2v(DISPC_BASE); | 1352 | dispc.base = ioremap(DISPC_BASE, SZ_1K); |
1353 | if (!dispc.base) { | ||
1354 | dev_err(fbdev->dev, "can't ioremap DISPC\n"); | ||
1355 | return -ENOMEM; | ||
1356 | } | ||
1357 | |||
1353 | dispc.fbdev = fbdev; | 1358 | dispc.fbdev = fbdev; |
1354 | dispc.ext_mode = ext_mode; | 1359 | dispc.ext_mode = ext_mode; |
1355 | 1360 | ||
1356 | init_completion(&dispc.frame_done); | 1361 | init_completion(&dispc.frame_done); |
1357 | 1362 | ||
1358 | if ((r = get_dss_clocks()) < 0) | 1363 | if ((r = get_dss_clocks()) < 0) |
1359 | return r; | 1364 | goto fail0; |
1360 | 1365 | ||
1361 | enable_interface_clocks(1); | 1366 | enable_interface_clocks(1); |
1362 | enable_lcd_clocks(1); | 1367 | enable_lcd_clocks(1); |
@@ -1414,7 +1419,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, | |||
1414 | } | 1419 | } |
1415 | 1420 | ||
1416 | /* L3 firewall setting: enable access to OCM RAM */ | 1421 | /* L3 firewall setting: enable access to OCM RAM */ |
1417 | __raw_writel(0x402000b0, io_p2v(0x680050a0)); | 1422 | __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0)); |
1418 | 1423 | ||
1419 | if ((r = alloc_palette_ram()) < 0) | 1424 | if ((r = alloc_palette_ram()) < 0) |
1420 | goto fail2; | 1425 | goto fail2; |
@@ -1464,7 +1469,8 @@ fail1: | |||
1464 | enable_lcd_clocks(0); | 1469 | enable_lcd_clocks(0); |
1465 | enable_interface_clocks(0); | 1470 | enable_interface_clocks(0); |
1466 | put_dss_clocks(); | 1471 | put_dss_clocks(); |
1467 | 1472 | fail0: | |
1473 | iounmap(dispc.base); | ||
1468 | return r; | 1474 | return r; |
1469 | } | 1475 | } |
1470 | 1476 | ||
@@ -1481,6 +1487,7 @@ static void omap_dispc_cleanup(void) | |||
1481 | free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); | 1487 | free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); |
1482 | enable_interface_clocks(0); | 1488 | enable_interface_clocks(0); |
1483 | put_dss_clocks(); | 1489 | put_dss_clocks(); |
1490 | iounmap(dispc.base); | ||
1484 | } | 1491 | } |
1485 | 1492 | ||
1486 | const struct lcd_ctrl omap2_int_ctrl = { | 1493 | const struct lcd_ctrl omap2_int_ctrl = { |
diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h index eb1512b56ce8..ef720a78f6d5 100644 --- a/drivers/video/omap/dispc.h +++ b/drivers/video/omap/dispc.h | |||
@@ -40,4 +40,6 @@ extern void omap_dispc_enable_digit_out(int enable); | |||
40 | extern int omap_dispc_request_irq(void (*callback)(void *data), void *data); | 40 | extern int omap_dispc_request_irq(void (*callback)(void *data), void *data); |
41 | extern void omap_dispc_free_irq(void); | 41 | extern void omap_dispc_free_irq(void); |
42 | 42 | ||
43 | extern const struct lcd_ctrl omap2_int_ctrl; | ||
44 | |||
43 | #endif | 45 | #endif |
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c index 88c19d424ef7..6ff56430341b 100644 --- a/drivers/video/omap/lcd_h4.c +++ b/drivers/video/omap/lcd_h4.c | |||
@@ -47,7 +47,7 @@ static unsigned long h4_panel_get_caps(struct lcd_panel *panel) | |||
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | struct lcd_panel h4_panel = { | 50 | static struct lcd_panel h4_panel = { |
51 | .name = "h4", | 51 | .name = "h4", |
52 | .config = OMAP_LCDC_PANEL_TFT, | 52 | .config = OMAP_LCDC_PANEL_TFT, |
53 | 53 | ||
@@ -91,7 +91,7 @@ static int h4_panel_resume(struct platform_device *pdev) | |||
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | 93 | ||
94 | struct platform_driver h4_panel_driver = { | 94 | static struct platform_driver h4_panel_driver = { |
95 | .probe = h4_panel_probe, | 95 | .probe = h4_panel_probe, |
96 | .remove = h4_panel_remove, | 96 | .remove = h4_panel_remove, |
97 | .suspend = h4_panel_suspend, | 97 | .suspend = h4_panel_suspend, |
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c index 6a42c6a0cd99..4c4f7ee6d733 100644 --- a/drivers/video/omap/lcd_inn1610.c +++ b/drivers/video/omap/lcd_inn1610.c | |||
@@ -32,43 +32,43 @@ static int innovator1610_panel_init(struct lcd_panel *panel, | |||
32 | { | 32 | { |
33 | int r = 0; | 33 | int r = 0; |
34 | 34 | ||
35 | if (omap_request_gpio(14)) { | 35 | if (gpio_request(14, "lcd_en0")) { |
36 | pr_err(MODULE_NAME ": can't request GPIO 14\n"); | 36 | pr_err(MODULE_NAME ": can't request GPIO 14\n"); |
37 | r = -1; | 37 | r = -1; |
38 | goto exit; | 38 | goto exit; |
39 | } | 39 | } |
40 | if (omap_request_gpio(15)) { | 40 | if (gpio_request(15, "lcd_en1")) { |
41 | pr_err(MODULE_NAME ": can't request GPIO 15\n"); | 41 | pr_err(MODULE_NAME ": can't request GPIO 15\n"); |
42 | omap_free_gpio(14); | 42 | gpio_free(14); |
43 | r = -1; | 43 | r = -1; |
44 | goto exit; | 44 | goto exit; |
45 | } | 45 | } |
46 | /* configure GPIO(14, 15) as outputs */ | 46 | /* configure GPIO(14, 15) as outputs */ |
47 | omap_set_gpio_direction(14, 0); | 47 | gpio_direction_output(14, 0); |
48 | omap_set_gpio_direction(15, 0); | 48 | gpio_direction_output(15, 0); |
49 | exit: | 49 | exit: |
50 | return r; | 50 | return r; |
51 | } | 51 | } |
52 | 52 | ||
53 | static void innovator1610_panel_cleanup(struct lcd_panel *panel) | 53 | static void innovator1610_panel_cleanup(struct lcd_panel *panel) |
54 | { | 54 | { |
55 | omap_free_gpio(15); | 55 | gpio_free(15); |
56 | omap_free_gpio(14); | 56 | gpio_free(14); |
57 | } | 57 | } |
58 | 58 | ||
59 | static int innovator1610_panel_enable(struct lcd_panel *panel) | 59 | static int innovator1610_panel_enable(struct lcd_panel *panel) |
60 | { | 60 | { |
61 | /* set GPIO14 and GPIO15 high */ | 61 | /* set GPIO14 and GPIO15 high */ |
62 | omap_set_gpio_dataout(14, 1); | 62 | gpio_set_value(14, 1); |
63 | omap_set_gpio_dataout(15, 1); | 63 | gpio_set_value(15, 1); |
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | static void innovator1610_panel_disable(struct lcd_panel *panel) | 67 | static void innovator1610_panel_disable(struct lcd_panel *panel) |
68 | { | 68 | { |
69 | /* set GPIO13, GPIO14 and GPIO15 low */ | 69 | /* set GPIO13, GPIO14 and GPIO15 low */ |
70 | omap_set_gpio_dataout(14, 0); | 70 | gpio_set_value(14, 0); |
71 | omap_set_gpio_dataout(15, 0); | 71 | gpio_set_value(15, 0); |
72 | } | 72 | } |
73 | 73 | ||
74 | static unsigned long innovator1610_panel_get_caps(struct lcd_panel *panel) | 74 | static unsigned long innovator1610_panel_get_caps(struct lcd_panel *panel) |
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c index a4a725f427a4..379c96d36da5 100644 --- a/drivers/video/omap/lcd_osk.c +++ b/drivers/video/omap/lcd_osk.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) | 30 | static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) |
31 | { | 31 | { |
32 | /* gpio2 was allocated in board init */ | ||
32 | return 0; | 33 | return 0; |
33 | } | 34 | } |
34 | 35 | ||
@@ -47,11 +48,8 @@ static int osk_panel_enable(struct lcd_panel *panel) | |||
47 | /* Set PWL level */ | 48 | /* Set PWL level */ |
48 | omap_writeb(0xFF, OMAP_PWL_ENABLE); | 49 | omap_writeb(0xFF, OMAP_PWL_ENABLE); |
49 | 50 | ||
50 | /* configure GPIO2 as output */ | 51 | /* set GPIO2 high (lcd power enabled) */ |
51 | omap_set_gpio_direction(2, 0); | 52 | gpio_set_value(2, 1); |
52 | |||
53 | /* set GPIO2 high */ | ||
54 | omap_set_gpio_dataout(2, 1); | ||
55 | 53 | ||
56 | return 0; | 54 | return 0; |
57 | } | 55 | } |
@@ -65,7 +63,7 @@ static void osk_panel_disable(struct lcd_panel *panel) | |||
65 | omap_writeb(0x00, OMAP_PWL_CLK_ENABLE); | 63 | omap_writeb(0x00, OMAP_PWL_CLK_ENABLE); |
66 | 64 | ||
67 | /* set GPIO2 low */ | 65 | /* set GPIO2 low */ |
68 | omap_set_gpio_dataout(2, 0); | 66 | gpio_set_value(2, 0); |
69 | } | 67 | } |
70 | 68 | ||
71 | static unsigned long osk_panel_get_caps(struct lcd_panel *panel) | 69 | static unsigned long osk_panel_get_caps(struct lcd_panel *panel) |
diff --git a/drivers/video/omap/lcd_sx1.c b/drivers/video/omap/lcd_sx1.c index caa6a896cb8b..e55de201b8ff 100644 --- a/drivers/video/omap/lcd_sx1.c +++ b/drivers/video/omap/lcd_sx1.c | |||
@@ -81,21 +81,21 @@ static void epson_sendbyte(int flag, unsigned char byte) | |||
81 | int i, shifter = 0x80; | 81 | int i, shifter = 0x80; |
82 | 82 | ||
83 | if (!flag) | 83 | if (!flag) |
84 | omap_set_gpio_dataout(_A_LCD_SSC_A0, 0); | 84 | gpio_set_value(_A_LCD_SSC_A0, 0); |
85 | mdelay(2); | 85 | mdelay(2); |
86 | omap_set_gpio_dataout(A_LCD_SSC_RD, 1); | 86 | gpio_set_value(A_LCD_SSC_RD, 1); |
87 | 87 | ||
88 | omap_set_gpio_dataout(A_LCD_SSC_SD, flag); | 88 | gpio_set_value(A_LCD_SSC_SD, flag); |
89 | 89 | ||
90 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200); | 90 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200); |
91 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202); | 91 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202); |
92 | for (i = 0; i < 8; i++) { | 92 | for (i = 0; i < 8; i++) { |
93 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200); | 93 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200); |
94 | omap_set_gpio_dataout(A_LCD_SSC_SD, shifter & byte); | 94 | gpio_set_value(A_LCD_SSC_SD, shifter & byte); |
95 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202); | 95 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202); |
96 | shifter >>= 1; | 96 | shifter >>= 1; |
97 | } | 97 | } |
98 | omap_set_gpio_dataout(_A_LCD_SSC_A0, 1); | 98 | gpio_set_value(_A_LCD_SSC_A0, 1); |
99 | } | 99 | } |
100 | 100 | ||
101 | static void init_system(void) | 101 | static void init_system(void) |
@@ -107,25 +107,18 @@ static void init_system(void) | |||
107 | static void setup_GPIO(void) | 107 | static void setup_GPIO(void) |
108 | { | 108 | { |
109 | /* new wave */ | 109 | /* new wave */ |
110 | omap_request_gpio(A_LCD_SSC_RD); | 110 | gpio_request(A_LCD_SSC_RD, "lcd_ssc_rd"); |
111 | omap_request_gpio(A_LCD_SSC_SD); | 111 | gpio_request(A_LCD_SSC_SD, "lcd_ssc_sd"); |
112 | omap_request_gpio(_A_LCD_RESET); | 112 | gpio_request(_A_LCD_RESET, "lcd_reset"); |
113 | omap_request_gpio(_A_LCD_SSC_CS); | 113 | gpio_request(_A_LCD_SSC_CS, "lcd_ssc_cs"); |
114 | omap_request_gpio(_A_LCD_SSC_A0); | 114 | gpio_request(_A_LCD_SSC_A0, "lcd_ssc_a0"); |
115 | 115 | ||
116 | /* set all GPIOs to output */ | 116 | /* set GPIOs to output, with initial data */ |
117 | omap_set_gpio_direction(A_LCD_SSC_RD, 0); | 117 | gpio_direction_output(A_LCD_SSC_RD, 1); |
118 | omap_set_gpio_direction(A_LCD_SSC_SD, 0); | 118 | gpio_direction_output(A_LCD_SSC_SD, 0); |
119 | omap_set_gpio_direction(_A_LCD_RESET, 0); | 119 | gpio_direction_output(_A_LCD_RESET, 0); |
120 | omap_set_gpio_direction(_A_LCD_SSC_CS, 0); | 120 | gpio_direction_output(_A_LCD_SSC_CS, 1); |
121 | omap_set_gpio_direction(_A_LCD_SSC_A0, 0); | 121 | gpio_direction_output(_A_LCD_SSC_A0, 1); |
122 | |||
123 | /* set GPIO data */ | ||
124 | omap_set_gpio_dataout(A_LCD_SSC_RD, 1); | ||
125 | omap_set_gpio_dataout(A_LCD_SSC_SD, 0); | ||
126 | omap_set_gpio_dataout(_A_LCD_RESET, 0); | ||
127 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | ||
128 | omap_set_gpio_dataout(_A_LCD_SSC_A0, 1); | ||
129 | } | 122 | } |
130 | 123 | ||
131 | static void display_init(void) | 124 | static void display_init(void) |
@@ -139,61 +132,61 @@ static void display_init(void) | |||
139 | mdelay(2); | 132 | mdelay(2); |
140 | 133 | ||
141 | /* reset LCD */ | 134 | /* reset LCD */ |
142 | omap_set_gpio_dataout(A_LCD_SSC_SD, 1); | 135 | gpio_set_value(A_LCD_SSC_SD, 1); |
143 | epson_sendbyte(0, 0x25); | 136 | epson_sendbyte(0, 0x25); |
144 | 137 | ||
145 | omap_set_gpio_dataout(_A_LCD_RESET, 0); | 138 | gpio_set_value(_A_LCD_RESET, 0); |
146 | mdelay(10); | 139 | mdelay(10); |
147 | omap_set_gpio_dataout(_A_LCD_RESET, 1); | 140 | gpio_set_value(_A_LCD_RESET, 1); |
148 | 141 | ||
149 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 142 | gpio_set_value(_A_LCD_SSC_CS, 1); |
150 | mdelay(2); | 143 | mdelay(2); |
151 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 144 | gpio_set_value(_A_LCD_SSC_CS, 0); |
152 | 145 | ||
153 | /* init LCD, phase 1 */ | 146 | /* init LCD, phase 1 */ |
154 | epson_sendbyte(0, 0xCA); | 147 | epson_sendbyte(0, 0xCA); |
155 | for (i = 0; i < 10; i++) | 148 | for (i = 0; i < 10; i++) |
156 | epson_sendbyte(1, INIT_1[i]); | 149 | epson_sendbyte(1, INIT_1[i]); |
157 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 150 | gpio_set_value(_A_LCD_SSC_CS, 1); |
158 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 151 | gpio_set_value(_A_LCD_SSC_CS, 0); |
159 | 152 | ||
160 | /* init LCD phase 2 */ | 153 | /* init LCD phase 2 */ |
161 | epson_sendbyte(0, 0xCB); | 154 | epson_sendbyte(0, 0xCB); |
162 | for (i = 0; i < 125; i++) | 155 | for (i = 0; i < 125; i++) |
163 | epson_sendbyte(1, INIT_2[i]); | 156 | epson_sendbyte(1, INIT_2[i]); |
164 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 157 | gpio_set_value(_A_LCD_SSC_CS, 1); |
165 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 158 | gpio_set_value(_A_LCD_SSC_CS, 0); |
166 | 159 | ||
167 | /* init LCD phase 2a */ | 160 | /* init LCD phase 2a */ |
168 | epson_sendbyte(0, 0xCC); | 161 | epson_sendbyte(0, 0xCC); |
169 | for (i = 0; i < 14; i++) | 162 | for (i = 0; i < 14; i++) |
170 | epson_sendbyte(1, INIT_3[i]); | 163 | epson_sendbyte(1, INIT_3[i]); |
171 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 164 | gpio_set_value(_A_LCD_SSC_CS, 1); |
172 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 165 | gpio_set_value(_A_LCD_SSC_CS, 0); |
173 | 166 | ||
174 | /* init LCD phase 3 */ | 167 | /* init LCD phase 3 */ |
175 | epson_sendbyte(0, 0xBC); | 168 | epson_sendbyte(0, 0xBC); |
176 | epson_sendbyte(1, 0x08); | 169 | epson_sendbyte(1, 0x08); |
177 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 170 | gpio_set_value(_A_LCD_SSC_CS, 1); |
178 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 171 | gpio_set_value(_A_LCD_SSC_CS, 0); |
179 | 172 | ||
180 | /* init LCD phase 4 */ | 173 | /* init LCD phase 4 */ |
181 | epson_sendbyte(0, 0x07); | 174 | epson_sendbyte(0, 0x07); |
182 | epson_sendbyte(1, 0x05); | 175 | epson_sendbyte(1, 0x05); |
183 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 176 | gpio_set_value(_A_LCD_SSC_CS, 1); |
184 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 177 | gpio_set_value(_A_LCD_SSC_CS, 0); |
185 | 178 | ||
186 | /* init LCD phase 5 */ | 179 | /* init LCD phase 5 */ |
187 | epson_sendbyte(0, 0x94); | 180 | epson_sendbyte(0, 0x94); |
188 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 181 | gpio_set_value(_A_LCD_SSC_CS, 1); |
189 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 182 | gpio_set_value(_A_LCD_SSC_CS, 0); |
190 | 183 | ||
191 | /* init LCD phase 6 */ | 184 | /* init LCD phase 6 */ |
192 | epson_sendbyte(0, 0xC6); | 185 | epson_sendbyte(0, 0xC6); |
193 | epson_sendbyte(1, 0x80); | 186 | epson_sendbyte(1, 0x80); |
194 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 187 | gpio_set_value(_A_LCD_SSC_CS, 1); |
195 | mdelay(100); /* used to be 1000 */ | 188 | mdelay(100); /* used to be 1000 */ |
196 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 189 | gpio_set_value(_A_LCD_SSC_CS, 0); |
197 | 190 | ||
198 | /* init LCD phase 7 */ | 191 | /* init LCD phase 7 */ |
199 | epson_sendbyte(0, 0x16); | 192 | epson_sendbyte(0, 0x16); |
@@ -201,8 +194,8 @@ static void display_init(void) | |||
201 | epson_sendbyte(1, 0x00); | 194 | epson_sendbyte(1, 0x00); |
202 | epson_sendbyte(1, 0xB1); | 195 | epson_sendbyte(1, 0xB1); |
203 | epson_sendbyte(1, 0x00); | 196 | epson_sendbyte(1, 0x00); |
204 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 197 | gpio_set_value(_A_LCD_SSC_CS, 1); |
205 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 198 | gpio_set_value(_A_LCD_SSC_CS, 0); |
206 | 199 | ||
207 | /* init LCD phase 8 */ | 200 | /* init LCD phase 8 */ |
208 | epson_sendbyte(0, 0x76); | 201 | epson_sendbyte(0, 0x76); |
@@ -210,12 +203,12 @@ static void display_init(void) | |||
210 | epson_sendbyte(1, 0x00); | 203 | epson_sendbyte(1, 0x00); |
211 | epson_sendbyte(1, 0xDB); | 204 | epson_sendbyte(1, 0xDB); |
212 | epson_sendbyte(1, 0x00); | 205 | epson_sendbyte(1, 0x00); |
213 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 206 | gpio_set_value(_A_LCD_SSC_CS, 1); |
214 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 207 | gpio_set_value(_A_LCD_SSC_CS, 0); |
215 | 208 | ||
216 | /* init LCD phase 9 */ | 209 | /* init LCD phase 9 */ |
217 | epson_sendbyte(0, 0xAF); | 210 | epson_sendbyte(0, 0xAF); |
218 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 211 | gpio_set_value(_A_LCD_SSC_CS, 1); |
219 | } | 212 | } |
220 | 213 | ||
221 | static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) | 214 | static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) |
@@ -231,18 +224,18 @@ static void sx1_panel_disable(struct lcd_panel *panel) | |||
231 | { | 224 | { |
232 | printk(KERN_INFO "SX1: LCD panel disable\n"); | 225 | printk(KERN_INFO "SX1: LCD panel disable\n"); |
233 | sx1_setmmipower(0); | 226 | sx1_setmmipower(0); |
234 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 227 | gpio_set_value(_A_LCD_SSC_CS, 1); |
235 | 228 | ||
236 | epson_sendbyte(0, 0x25); | 229 | epson_sendbyte(0, 0x25); |
237 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 230 | gpio_set_value(_A_LCD_SSC_CS, 0); |
238 | 231 | ||
239 | epson_sendbyte(0, 0xAE); | 232 | epson_sendbyte(0, 0xAE); |
240 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 233 | gpio_set_value(_A_LCD_SSC_CS, 1); |
241 | mdelay(100); | 234 | mdelay(100); |
242 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 0); | 235 | gpio_set_value(_A_LCD_SSC_CS, 0); |
243 | 236 | ||
244 | epson_sendbyte(0, 0x95); | 237 | epson_sendbyte(0, 0x95); |
245 | omap_set_gpio_dataout(_A_LCD_SSC_CS, 1); | 238 | gpio_set_value(_A_LCD_SSC_CS, 1); |
246 | } | 239 | } |
247 | 240 | ||
248 | static int sx1_panel_enable(struct lcd_panel *panel) | 241 | static int sx1_panel_enable(struct lcd_panel *panel) |
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c index 83514f066712..6e2ea7518761 100644 --- a/drivers/video/omap/lcdc.c +++ b/drivers/video/omap/lcdc.c | |||
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
35 | #include <asm/mach-types.h> | 35 | #include <asm/mach-types.h> |
36 | 36 | ||
37 | #include "lcdc.h" | ||
38 | |||
37 | #define MODULE_NAME "lcdc" | 39 | #define MODULE_NAME "lcdc" |
38 | 40 | ||
39 | #define OMAP_LCDC_BASE 0xfffec000 | 41 | #define OMAP_LCDC_BASE 0xfffec000 |
diff --git a/drivers/video/omap/lcdc.h b/drivers/video/omap/lcdc.h index adb731e5314a..845222270db3 100644 --- a/drivers/video/omap/lcdc.h +++ b/drivers/video/omap/lcdc.h | |||
@@ -4,4 +4,6 @@ | |||
4 | int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data); | 4 | int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data); |
5 | void omap_lcdc_free_dma_callback(void); | 5 | void omap_lcdc_free_dma_callback(void); |
6 | 6 | ||
7 | extern const struct lcd_ctrl omap1_int_ctrl; | ||
8 | |||
7 | #endif | 9 | #endif |
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 51a138bd113c..5a5e407dc45f 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
@@ -31,11 +31,14 @@ | |||
31 | #include <mach/dma.h> | 31 | #include <mach/dma.h> |
32 | #include <mach/omapfb.h> | 32 | #include <mach/omapfb.h> |
33 | 33 | ||
34 | #include "lcdc.h" | ||
35 | #include "dispc.h" | ||
36 | |||
34 | #define MODULE_NAME "omapfb" | 37 | #define MODULE_NAME "omapfb" |
35 | 38 | ||
36 | static unsigned int def_accel; | 39 | static unsigned int def_accel; |
37 | static unsigned long def_vram[OMAPFB_PLANE_NUM]; | 40 | static unsigned long def_vram[OMAPFB_PLANE_NUM]; |
38 | static int def_vram_cnt; | 41 | static unsigned int def_vram_cnt; |
39 | static unsigned long def_vxres; | 42 | static unsigned long def_vxres; |
40 | static unsigned long def_vyres; | 43 | static unsigned long def_vyres; |
41 | static unsigned int def_rotate; | 44 | static unsigned int def_rotate; |
@@ -84,12 +87,10 @@ static struct caps_table_struct color_caps[] = { | |||
84 | * LCD panel | 87 | * LCD panel |
85 | * --------------------------------------------------------------------------- | 88 | * --------------------------------------------------------------------------- |
86 | */ | 89 | */ |
87 | extern struct lcd_ctrl omap1_int_ctrl; | ||
88 | extern struct lcd_ctrl omap2_int_ctrl; | ||
89 | extern struct lcd_ctrl hwa742_ctrl; | 90 | extern struct lcd_ctrl hwa742_ctrl; |
90 | extern struct lcd_ctrl blizzard_ctrl; | 91 | extern struct lcd_ctrl blizzard_ctrl; |
91 | 92 | ||
92 | static struct lcd_ctrl *ctrls[] = { | 93 | static const struct lcd_ctrl *ctrls[] = { |
93 | #ifdef CONFIG_ARCH_OMAP1 | 94 | #ifdef CONFIG_ARCH_OMAP1 |
94 | &omap1_int_ctrl, | 95 | &omap1_int_ctrl, |
95 | #else | 96 | #else |
@@ -740,7 +741,7 @@ static int omapfb_update_win(struct fb_info *fbi, | |||
740 | int ret; | 741 | int ret; |
741 | 742 | ||
742 | omapfb_rqueue_lock(plane->fbdev); | 743 | omapfb_rqueue_lock(plane->fbdev); |
743 | ret = omapfb_update_window_async(fbi, win, NULL, 0); | 744 | ret = omapfb_update_window_async(fbi, win, NULL, NULL); |
744 | omapfb_rqueue_unlock(plane->fbdev); | 745 | omapfb_rqueue_unlock(plane->fbdev); |
745 | 746 | ||
746 | return ret; | 747 | return ret; |
@@ -768,7 +769,7 @@ static int omapfb_update_full_screen(struct fb_info *fbi) | |||
768 | win.format = 0; | 769 | win.format = 0; |
769 | 770 | ||
770 | omapfb_rqueue_lock(fbdev); | 771 | omapfb_rqueue_lock(fbdev); |
771 | r = fbdev->ctrl->update_window(fbi, &win, NULL, 0); | 772 | r = fbdev->ctrl->update_window(fbi, &win, NULL, NULL); |
772 | omapfb_rqueue_unlock(fbdev); | 773 | omapfb_rqueue_unlock(fbdev); |
773 | 774 | ||
774 | return r; | 775 | return r; |
@@ -1047,7 +1048,7 @@ void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval) | |||
1047 | win.height = 2; | 1048 | win.height = 2; |
1048 | win.out_width = 2; | 1049 | win.out_width = 2; |
1049 | win.out_height = 2; | 1050 | win.out_height = 2; |
1050 | fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, 0); | 1051 | fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, NULL); |
1051 | } | 1052 | } |
1052 | omapfb_rqueue_unlock(fbdev); | 1053 | omapfb_rqueue_unlock(fbdev); |
1053 | } | 1054 | } |
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index 4a6f13d3facf..a13c8dcad2a8 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c | |||
@@ -59,7 +59,7 @@ | |||
59 | #define DISPC_CONTROL 0x0040 | 59 | #define DISPC_CONTROL 0x0040 |
60 | 60 | ||
61 | static struct { | 61 | static struct { |
62 | u32 base; | 62 | void __iomem *base; |
63 | void (*lcdc_callback)(void *data); | 63 | void (*lcdc_callback)(void *data); |
64 | void *lcdc_callback_data; | 64 | void *lcdc_callback_data; |
65 | unsigned long l4_khz; | 65 | unsigned long l4_khz; |
@@ -518,7 +518,11 @@ static int rfbi_init(struct omapfb_device *fbdev) | |||
518 | int r; | 518 | int r; |
519 | 519 | ||
520 | rfbi.fbdev = fbdev; | 520 | rfbi.fbdev = fbdev; |
521 | rfbi.base = io_p2v(RFBI_BASE); | 521 | rfbi.base = ioremap(RFBI_BASE, SZ_1K); |
522 | if (!rfbi.base) { | ||
523 | dev_err(fbdev->dev, "can't ioremap RFBI\n"); | ||
524 | return -ENOMEM; | ||
525 | } | ||
522 | 526 | ||
523 | if ((r = rfbi_get_clocks()) < 0) | 527 | if ((r = rfbi_get_clocks()) < 0) |
524 | return r; | 528 | return r; |
@@ -566,6 +570,7 @@ static void rfbi_cleanup(void) | |||
566 | { | 570 | { |
567 | omap_dispc_free_irq(); | 571 | omap_dispc_free_irq(); |
568 | rfbi_put_clocks(); | 572 | rfbi_put_clocks(); |
573 | iounmap(rfbi.base); | ||
569 | } | 574 | } |
570 | 575 | ||
571 | const struct lcd_ctrl_extif omap2_ext_if = { | 576 | const struct lcd_ctrl_extif omap2_ext_if = { |
diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c index 6359353c2c67..a76946220249 100644 --- a/drivers/video/omap/sossi.c +++ b/drivers/video/omap/sossi.c | |||
@@ -574,7 +574,12 @@ static int sossi_init(struct omapfb_device *fbdev) | |||
574 | struct clk *dpll1out_ck; | 574 | struct clk *dpll1out_ck; |
575 | int r; | 575 | int r; |
576 | 576 | ||
577 | sossi.base = (void __iomem *)IO_ADDRESS(OMAP_SOSSI_BASE); | 577 | sossi.base = ioremap(OMAP_SOSSI_BASE, SZ_1K); |
578 | if (!sossi.base) { | ||
579 | dev_err(fbdev->dev, "can't ioremap SoSSI\n"); | ||
580 | return -ENOMEM; | ||
581 | } | ||
582 | |||
578 | sossi.fbdev = fbdev; | 583 | sossi.fbdev = fbdev; |
579 | spin_lock_init(&sossi.lock); | 584 | spin_lock_init(&sossi.lock); |
580 | 585 | ||
@@ -665,6 +670,7 @@ static void sossi_cleanup(void) | |||
665 | { | 670 | { |
666 | omap_lcdc_free_dma_callback(); | 671 | omap_lcdc_free_dma_callback(); |
667 | clk_put(sossi.fck); | 672 | clk_put(sossi.fck); |
673 | iounmap(sossi.base); | ||
668 | } | 674 | } |
669 | 675 | ||
670 | struct lcd_ctrl_extif omap1_ext_if = { | 676 | struct lcd_ctrl_extif omap1_ext_if = { |
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 9e903454ffc1..7000f2cd5854 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c | |||
@@ -349,7 +349,7 @@ static int __devexit p9100_remove(struct of_device *op) | |||
349 | return 0; | 349 | return 0; |
350 | } | 350 | } |
351 | 351 | ||
352 | static struct of_device_id p9100_match[] = { | 352 | static const struct of_device_id p9100_match[] = { |
353 | { | 353 | { |
354 | .name = "p9100", | 354 | .name = "p9100", |
355 | }, | 355 | }, |
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index b829dc7c5edf..a7b01d2724b5 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c | |||
@@ -50,6 +50,11 @@ | |||
50 | #define dbg(fmt, args...) do { } while (0) | 50 | #define dbg(fmt, args...) do { } while (0) |
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | static const int __devinitconst s1d13xxxfb_revisions[] = { | ||
54 | S1D13506_CHIP_REV, /* Rev.4 on HP Jornada 7xx S1D13506 */ | ||
55 | S1D13806_CHIP_REV, /* Rev.7 on .. */ | ||
56 | }; | ||
57 | |||
53 | /* | 58 | /* |
54 | * Here we define the default struct fb_fix_screeninfo | 59 | * Here we define the default struct fb_fix_screeninfo |
55 | */ | 60 | */ |
@@ -538,6 +543,7 @@ s1d13xxxfb_probe(struct platform_device *pdev) | |||
538 | struct fb_info *info; | 543 | struct fb_info *info; |
539 | struct s1d13xxxfb_pdata *pdata = NULL; | 544 | struct s1d13xxxfb_pdata *pdata = NULL; |
540 | int ret = 0; | 545 | int ret = 0; |
546 | int i; | ||
541 | u8 revision; | 547 | u8 revision; |
542 | 548 | ||
543 | dbg("probe called: device is %p\n", pdev); | 549 | dbg("probe called: device is %p\n", pdev); |
@@ -607,10 +613,19 @@ s1d13xxxfb_probe(struct platform_device *pdev) | |||
607 | goto bail; | 613 | goto bail; |
608 | } | 614 | } |
609 | 615 | ||
610 | revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE); | 616 | revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2; |
611 | if ((revision >> 2) != S1D_CHIP_REV) { | 617 | |
612 | printk(KERN_INFO PFX "chip not found: %i\n", (revision >> 2)); | 618 | ret = -ENODEV; |
613 | ret = -ENODEV; | 619 | |
620 | for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) { | ||
621 | if (revision == s1d13xxxfb_revisions[i]) | ||
622 | ret = 0; | ||
623 | } | ||
624 | |||
625 | if (!ret) | ||
626 | printk(KERN_INFO PFX "chip revision %i\n", revision); | ||
627 | else { | ||
628 | printk(KERN_INFO PFX "unknown chip revision %i\n", revision); | ||
614 | goto bail; | 629 | goto bail; |
615 | } | 630 | } |
616 | 631 | ||
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index 2a03f78bbb0d..643afbfe8277 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c | |||
@@ -505,7 +505,7 @@ static int __devexit tcx_remove(struct of_device *op) | |||
505 | return 0; | 505 | return 0; |
506 | } | 506 | } |
507 | 507 | ||
508 | static struct of_device_id tcx_match[] = { | 508 | static const struct of_device_id tcx_match[] = { |
509 | { | 509 | { |
510 | .name = "SUNW,tcx", | 510 | .name = "SUNW,tcx", |
511 | }, | 511 | }, |
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 4599a4385bc9..14bd3f3680b8 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c | |||
@@ -1195,57 +1195,58 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, | |||
1195 | return -ENOMEM; | 1195 | return -ENOMEM; |
1196 | 1196 | ||
1197 | default_par = info->par; | 1197 | default_par = info->par; |
1198 | info->fix = tdfx_fix; | ||
1198 | 1199 | ||
1199 | /* Configure the default fb_fix_screeninfo first */ | 1200 | /* Configure the default fb_fix_screeninfo first */ |
1200 | switch (pdev->device) { | 1201 | switch (pdev->device) { |
1201 | case PCI_DEVICE_ID_3DFX_BANSHEE: | 1202 | case PCI_DEVICE_ID_3DFX_BANSHEE: |
1202 | strcpy(tdfx_fix.id, "3Dfx Banshee"); | 1203 | strcpy(info->fix.id, "3Dfx Banshee"); |
1203 | default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK; | 1204 | default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK; |
1204 | break; | 1205 | break; |
1205 | case PCI_DEVICE_ID_3DFX_VOODOO3: | 1206 | case PCI_DEVICE_ID_3DFX_VOODOO3: |
1206 | strcpy(tdfx_fix.id, "3Dfx Voodoo3"); | 1207 | strcpy(info->fix.id, "3Dfx Voodoo3"); |
1207 | default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK; | 1208 | default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK; |
1208 | break; | 1209 | break; |
1209 | case PCI_DEVICE_ID_3DFX_VOODOO5: | 1210 | case PCI_DEVICE_ID_3DFX_VOODOO5: |
1210 | strcpy(tdfx_fix.id, "3Dfx Voodoo5"); | 1211 | strcpy(info->fix.id, "3Dfx Voodoo5"); |
1211 | default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK; | 1212 | default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK; |
1212 | break; | 1213 | break; |
1213 | } | 1214 | } |
1214 | 1215 | ||
1215 | tdfx_fix.mmio_start = pci_resource_start(pdev, 0); | 1216 | info->fix.mmio_start = pci_resource_start(pdev, 0); |
1216 | tdfx_fix.mmio_len = pci_resource_len(pdev, 0); | 1217 | info->fix.mmio_len = pci_resource_len(pdev, 0); |
1217 | if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len, | 1218 | if (!request_mem_region(info->fix.mmio_start, info->fix.mmio_len, |
1218 | "tdfx regbase")) { | 1219 | "tdfx regbase")) { |
1219 | printk(KERN_ERR "tdfxfb: Can't reserve regbase\n"); | 1220 | printk(KERN_ERR "tdfxfb: Can't reserve regbase\n"); |
1220 | goto out_err; | 1221 | goto out_err; |
1221 | } | 1222 | } |
1222 | 1223 | ||
1223 | default_par->regbase_virt = | 1224 | default_par->regbase_virt = |
1224 | ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len); | 1225 | ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); |
1225 | if (!default_par->regbase_virt) { | 1226 | if (!default_par->regbase_virt) { |
1226 | printk(KERN_ERR "fb: Can't remap %s register area.\n", | 1227 | printk(KERN_ERR "fb: Can't remap %s register area.\n", |
1227 | tdfx_fix.id); | 1228 | info->fix.id); |
1228 | goto out_err_regbase; | 1229 | goto out_err_regbase; |
1229 | } | 1230 | } |
1230 | 1231 | ||
1231 | tdfx_fix.smem_start = pci_resource_start(pdev, 1); | 1232 | info->fix.smem_start = pci_resource_start(pdev, 1); |
1232 | tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device); | 1233 | info->fix.smem_len = do_lfb_size(default_par, pdev->device); |
1233 | if (!tdfx_fix.smem_len) { | 1234 | if (!info->fix.smem_len) { |
1234 | printk(KERN_ERR "fb: Can't count %s memory.\n", tdfx_fix.id); | 1235 | printk(KERN_ERR "fb: Can't count %s memory.\n", info->fix.id); |
1235 | goto out_err_regbase; | 1236 | goto out_err_regbase; |
1236 | } | 1237 | } |
1237 | 1238 | ||
1238 | if (!request_mem_region(tdfx_fix.smem_start, | 1239 | if (!request_mem_region(info->fix.smem_start, |
1239 | pci_resource_len(pdev, 1), "tdfx smem")) { | 1240 | pci_resource_len(pdev, 1), "tdfx smem")) { |
1240 | printk(KERN_ERR "tdfxfb: Can't reserve smem\n"); | 1241 | printk(KERN_ERR "tdfxfb: Can't reserve smem\n"); |
1241 | goto out_err_regbase; | 1242 | goto out_err_regbase; |
1242 | } | 1243 | } |
1243 | 1244 | ||
1244 | info->screen_base = ioremap_nocache(tdfx_fix.smem_start, | 1245 | info->screen_base = ioremap_nocache(info->fix.smem_start, |
1245 | tdfx_fix.smem_len); | 1246 | info->fix.smem_len); |
1246 | if (!info->screen_base) { | 1247 | if (!info->screen_base) { |
1247 | printk(KERN_ERR "fb: Can't remap %s framebuffer.\n", | 1248 | printk(KERN_ERR "fb: Can't remap %s framebuffer.\n", |
1248 | tdfx_fix.id); | 1249 | info->fix.id); |
1249 | goto out_err_screenbase; | 1250 | goto out_err_screenbase; |
1250 | } | 1251 | } |
1251 | 1252 | ||
@@ -1257,20 +1258,19 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, | |||
1257 | goto out_err_screenbase; | 1258 | goto out_err_screenbase; |
1258 | } | 1259 | } |
1259 | 1260 | ||
1260 | printk(KERN_INFO "fb: %s memory = %dK\n", tdfx_fix.id, | 1261 | printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id, |
1261 | tdfx_fix.smem_len >> 10); | 1262 | info->fix.smem_len >> 10); |
1262 | 1263 | ||
1263 | default_par->mtrr_handle = -1; | 1264 | default_par->mtrr_handle = -1; |
1264 | if (!nomtrr) | 1265 | if (!nomtrr) |
1265 | default_par->mtrr_handle = | 1266 | default_par->mtrr_handle = |
1266 | mtrr_add(tdfx_fix.smem_start, tdfx_fix.smem_len, | 1267 | mtrr_add(info->fix.smem_start, info->fix.smem_len, |
1267 | MTRR_TYPE_WRCOMB, 1); | 1268 | MTRR_TYPE_WRCOMB, 1); |
1268 | 1269 | ||
1269 | tdfx_fix.ypanstep = nopan ? 0 : 1; | 1270 | info->fix.ypanstep = nopan ? 0 : 1; |
1270 | tdfx_fix.ywrapstep = nowrap ? 0 : 1; | 1271 | info->fix.ywrapstep = nowrap ? 0 : 1; |
1271 | 1272 | ||
1272 | info->fbops = &tdfxfb_ops; | 1273 | info->fbops = &tdfxfb_ops; |
1273 | info->fix = tdfx_fix; | ||
1274 | info->pseudo_palette = default_par->palette; | 1274 | info->pseudo_palette = default_par->palette; |
1275 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 1275 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
1276 | #ifdef CONFIG_FB_3DFX_ACCEL | 1276 | #ifdef CONFIG_FB_3DFX_ACCEL |
@@ -1323,14 +1323,14 @@ out_err_iobase: | |||
1323 | out_err_screenbase: | 1323 | out_err_screenbase: |
1324 | if (info->screen_base) | 1324 | if (info->screen_base) |
1325 | iounmap(info->screen_base); | 1325 | iounmap(info->screen_base); |
1326 | release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1)); | 1326 | release_mem_region(info->fix.smem_start, pci_resource_len(pdev, 1)); |
1327 | out_err_regbase: | 1327 | out_err_regbase: |
1328 | /* | 1328 | /* |
1329 | * Cleanup after anything that was remapped/allocated. | 1329 | * Cleanup after anything that was remapped/allocated. |
1330 | */ | 1330 | */ |
1331 | if (default_par->regbase_virt) | 1331 | if (default_par->regbase_virt) |
1332 | iounmap(default_par->regbase_virt); | 1332 | iounmap(default_par->regbase_virt); |
1333 | release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len); | 1333 | release_mem_region(info->fix.mmio_start, info->fix.mmio_len); |
1334 | out_err: | 1334 | out_err: |
1335 | framebuffer_release(info); | 1335 | framebuffer_release(info); |
1336 | return -ENXIO; | 1336 | return -ENXIO; |
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c new file mode 100644 index 000000000000..2a380011e9ba --- /dev/null +++ b/drivers/video/tmiofb.c | |||
@@ -0,0 +1,1050 @@ | |||
1 | /* | ||
2 | * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller | ||
3 | * | ||
4 | * Copyright(C) 2005-2006 Chris Humbert | ||
5 | * Copyright(C) 2005 Dirk Opfer | ||
6 | * Copytight(C) 2007,2008 Dmitry Baryshkov | ||
7 | * | ||
8 | * Based on: | ||
9 | * drivers/video/w100fb.c | ||
10 | * code written by Sharp/Lineo for 2.4 kernels | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 | ||
14 | * as published by the Free Software Foundation; | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/fb.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/delay.h> | ||
28 | /* Why should fb driver call console functions? because acquire_console_sem() */ | ||
29 | #include <linux/console.h> | ||
30 | #include <linux/mfd/core.h> | ||
31 | #include <linux/mfd/tmio.h> | ||
32 | #include <linux/uaccess.h> | ||
33 | |||
34 | /* | ||
35 | * accelerator commands | ||
36 | */ | ||
37 | #define TMIOFB_ACC_CSADR(x) (0x00000000 | ((x) & 0x001ffffe)) | ||
38 | #define TMIOFB_ACC_CHPIX(x) (0x01000000 | ((x) & 0x000003ff)) | ||
39 | #define TMIOFB_ACC_CVPIX(x) (0x02000000 | ((x) & 0x000003ff)) | ||
40 | #define TMIOFB_ACC_PSADR(x) (0x03000000 | ((x) & 0x00fffffe)) | ||
41 | #define TMIOFB_ACC_PHPIX(x) (0x04000000 | ((x) & 0x000003ff)) | ||
42 | #define TMIOFB_ACC_PVPIX(x) (0x05000000 | ((x) & 0x000003ff)) | ||
43 | #define TMIOFB_ACC_PHOFS(x) (0x06000000 | ((x) & 0x000003ff)) | ||
44 | #define TMIOFB_ACC_PVOFS(x) (0x07000000 | ((x) & 0x000003ff)) | ||
45 | #define TMIOFB_ACC_POADR(x) (0x08000000 | ((x) & 0x00fffffe)) | ||
46 | #define TMIOFB_ACC_RSTR(x) (0x09000000 | ((x) & 0x000000ff)) | ||
47 | #define TMIOFB_ACC_TCLOR(x) (0x0A000000 | ((x) & 0x0000ffff)) | ||
48 | #define TMIOFB_ACC_FILL(x) (0x0B000000 | ((x) & 0x0000ffff)) | ||
49 | #define TMIOFB_ACC_DSADR(x) (0x0C000000 | ((x) & 0x00fffffe)) | ||
50 | #define TMIOFB_ACC_SSADR(x) (0x0D000000 | ((x) & 0x00fffffe)) | ||
51 | #define TMIOFB_ACC_DHPIX(x) (0x0E000000 | ((x) & 0x000003ff)) | ||
52 | #define TMIOFB_ACC_DVPIX(x) (0x0F000000 | ((x) & 0x000003ff)) | ||
53 | #define TMIOFB_ACC_SHPIX(x) (0x10000000 | ((x) & 0x000003ff)) | ||
54 | #define TMIOFB_ACC_SVPIX(x) (0x11000000 | ((x) & 0x000003ff)) | ||
55 | #define TMIOFB_ACC_LBINI(x) (0x12000000 | ((x) & 0x0000ffff)) | ||
56 | #define TMIOFB_ACC_LBK2(x) (0x13000000 | ((x) & 0x0000ffff)) | ||
57 | #define TMIOFB_ACC_SHBINI(x) (0x14000000 | ((x) & 0x0000ffff)) | ||
58 | #define TMIOFB_ACC_SHBK2(x) (0x15000000 | ((x) & 0x0000ffff)) | ||
59 | #define TMIOFB_ACC_SVBINI(x) (0x16000000 | ((x) & 0x0000ffff)) | ||
60 | #define TMIOFB_ACC_SVBK2(x) (0x17000000 | ((x) & 0x0000ffff)) | ||
61 | |||
62 | #define TMIOFB_ACC_CMGO 0x20000000 | ||
63 | #define TMIOFB_ACC_CMGO_CEND 0x00000001 | ||
64 | #define TMIOFB_ACC_CMGO_INT 0x00000002 | ||
65 | #define TMIOFB_ACC_CMGO_CMOD 0x00000010 | ||
66 | #define TMIOFB_ACC_CMGO_CDVRV 0x00000020 | ||
67 | #define TMIOFB_ACC_CMGO_CDHRV 0x00000040 | ||
68 | #define TMIOFB_ACC_CMGO_RUND 0x00008000 | ||
69 | #define TMIOFB_ACC_SCGO 0x21000000 | ||
70 | #define TMIOFB_ACC_SCGO_CEND 0x00000001 | ||
71 | #define TMIOFB_ACC_SCGO_INT 0x00000002 | ||
72 | #define TMIOFB_ACC_SCGO_ROP3 0x00000004 | ||
73 | #define TMIOFB_ACC_SCGO_TRNS 0x00000008 | ||
74 | #define TMIOFB_ACC_SCGO_DVRV 0x00000010 | ||
75 | #define TMIOFB_ACC_SCGO_DHRV 0x00000020 | ||
76 | #define TMIOFB_ACC_SCGO_SVRV 0x00000040 | ||
77 | #define TMIOFB_ACC_SCGO_SHRV 0x00000080 | ||
78 | #define TMIOFB_ACC_SCGO_DSTXY 0x00008000 | ||
79 | #define TMIOFB_ACC_SBGO 0x22000000 | ||
80 | #define TMIOFB_ACC_SBGO_CEND 0x00000001 | ||
81 | #define TMIOFB_ACC_SBGO_INT 0x00000002 | ||
82 | #define TMIOFB_ACC_SBGO_DVRV 0x00000010 | ||
83 | #define TMIOFB_ACC_SBGO_DHRV 0x00000020 | ||
84 | #define TMIOFB_ACC_SBGO_SVRV 0x00000040 | ||
85 | #define TMIOFB_ACC_SBGO_SHRV 0x00000080 | ||
86 | #define TMIOFB_ACC_SBGO_SBMD 0x00000100 | ||
87 | #define TMIOFB_ACC_FLGO 0x23000000 | ||
88 | #define TMIOFB_ACC_FLGO_CEND 0x00000001 | ||
89 | #define TMIOFB_ACC_FLGO_INT 0x00000002 | ||
90 | #define TMIOFB_ACC_FLGO_ROP3 0x00000004 | ||
91 | #define TMIOFB_ACC_LDGO 0x24000000 | ||
92 | #define TMIOFB_ACC_LDGO_CEND 0x00000001 | ||
93 | #define TMIOFB_ACC_LDGO_INT 0x00000002 | ||
94 | #define TMIOFB_ACC_LDGO_ROP3 0x00000004 | ||
95 | #define TMIOFB_ACC_LDGO_ENDPX 0x00000008 | ||
96 | #define TMIOFB_ACC_LDGO_LVRV 0x00000010 | ||
97 | #define TMIOFB_ACC_LDGO_LHRV 0x00000020 | ||
98 | #define TMIOFB_ACC_LDGO_LDMOD 0x00000040 | ||
99 | |||
100 | /* a FIFO is always allocated, even if acceleration is not used */ | ||
101 | #define TMIOFB_FIFO_SIZE 512 | ||
102 | |||
103 | /* | ||
104 | * LCD Host Controller Configuration Register | ||
105 | * | ||
106 | * This iomem area supports only 16-bit IO. | ||
107 | */ | ||
108 | #define CCR_CMD 0x04 /* Command */ | ||
109 | #define CCR_REVID 0x08 /* Revision ID */ | ||
110 | #define CCR_BASEL 0x10 /* LCD Control Reg Base Addr Low */ | ||
111 | #define CCR_BASEH 0x12 /* LCD Control Reg Base Addr High */ | ||
112 | #define CCR_UGCC 0x40 /* Unified Gated Clock Control */ | ||
113 | #define CCR_GCC 0x42 /* Gated Clock Control */ | ||
114 | #define CCR_USC 0x50 /* Unified Software Clear */ | ||
115 | #define CCR_VRAMRTC 0x60 /* VRAM Timing Control */ | ||
116 | /* 0x61 VRAM Refresh Control */ | ||
117 | #define CCR_VRAMSAC 0x62 /* VRAM Access Control */ | ||
118 | /* 0x63 VRAM Status */ | ||
119 | #define CCR_VRAMBC 0x64 /* VRAM Block Control */ | ||
120 | |||
121 | /* | ||
122 | * LCD Control Register | ||
123 | * | ||
124 | * This iomem area supports only 16-bit IO. | ||
125 | */ | ||
126 | #define LCR_UIS 0x000 /* Unified Interrupt Status */ | ||
127 | #define LCR_VHPN 0x008 /* VRAM Horizontal Pixel Number */ | ||
128 | #define LCR_CFSAL 0x00a /* Command FIFO Start Address Low */ | ||
129 | #define LCR_CFSAH 0x00c /* Command FIFO Start Address High */ | ||
130 | #define LCR_CFS 0x00e /* Command FIFO Size */ | ||
131 | #define LCR_CFWS 0x010 /* Command FIFO Writeable Size */ | ||
132 | #define LCR_BBIE 0x012 /* BitBLT Interrupt Enable */ | ||
133 | #define LCR_BBISC 0x014 /* BitBLT Interrupt Status and Clear */ | ||
134 | #define LCR_CCS 0x016 /* Command Count Status */ | ||
135 | #define LCR_BBES 0x018 /* BitBLT Execution Status */ | ||
136 | #define LCR_CMDL 0x01c /* Command Low */ | ||
137 | #define LCR_CMDH 0x01e /* Command High */ | ||
138 | #define LCR_CFC 0x022 /* Command FIFO Clear */ | ||
139 | #define LCR_CCIFC 0x024 /* CMOS Camera IF Control */ | ||
140 | #define LCR_HWT 0x026 /* Hardware Test */ | ||
141 | #define LCR_LCDCCRC 0x100 /* LCDC Clock and Reset Control */ | ||
142 | #define LCR_LCDCC 0x102 /* LCDC Control */ | ||
143 | #define LCR_LCDCOPC 0x104 /* LCDC Output Pin Control */ | ||
144 | #define LCR_LCDIS 0x108 /* LCD Interrupt Status */ | ||
145 | #define LCR_LCDIM 0x10a /* LCD Interrupt Mask */ | ||
146 | #define LCR_LCDIE 0x10c /* LCD Interrupt Enable */ | ||
147 | #define LCR_GDSAL 0x122 /* Graphics Display Start Address Low */ | ||
148 | #define LCR_GDSAH 0x124 /* Graphics Display Start Address High */ | ||
149 | #define LCR_VHPCL 0x12a /* VRAM Horizontal Pixel Count Low */ | ||
150 | #define LCR_VHPCH 0x12c /* VRAM Horizontal Pixel Count High */ | ||
151 | #define LCR_GM 0x12e /* Graphic Mode(VRAM access enable) */ | ||
152 | #define LCR_HT 0x140 /* Horizontal Total */ | ||
153 | #define LCR_HDS 0x142 /* Horizontal Display Start */ | ||
154 | #define LCR_HSS 0x144 /* H-Sync Start */ | ||
155 | #define LCR_HSE 0x146 /* H-Sync End */ | ||
156 | #define LCR_HNP 0x14c /* Horizontal Number of Pixels */ | ||
157 | #define LCR_VT 0x150 /* Vertical Total */ | ||
158 | #define LCR_VDS 0x152 /* Vertical Display Start */ | ||
159 | #define LCR_VSS 0x154 /* V-Sync Start */ | ||
160 | #define LCR_VSE 0x156 /* V-Sync End */ | ||
161 | #define LCR_CDLN 0x160 /* Current Display Line Number */ | ||
162 | #define LCR_ILN 0x162 /* Interrupt Line Number */ | ||
163 | #define LCR_SP 0x164 /* Sync Polarity */ | ||
164 | #define LCR_MISC 0x166 /* MISC(RGB565 mode) */ | ||
165 | #define LCR_VIHSS 0x16a /* Video Interface H-Sync Start */ | ||
166 | #define LCR_VIVS 0x16c /* Video Interface Vertical Start */ | ||
167 | #define LCR_VIVE 0x16e /* Video Interface Vertical End */ | ||
168 | #define LCR_VIVSS 0x170 /* Video Interface V-Sync Start */ | ||
169 | #define LCR_VCCIS 0x17e /* Video / CMOS Camera Interface Select */ | ||
170 | #define LCR_VIDWSAL 0x180 /* VI Data Write Start Address Low */ | ||
171 | #define LCR_VIDWSAH 0x182 /* VI Data Write Start Address High */ | ||
172 | #define LCR_VIDRSAL 0x184 /* VI Data Read Start Address Low */ | ||
173 | #define LCR_VIDRSAH 0x186 /* VI Data Read Start Address High */ | ||
174 | #define LCR_VIPDDST 0x188 /* VI Picture Data Display Start Timing */ | ||
175 | #define LCR_VIPDDET 0x186 /* VI Picture Data Display End Timing */ | ||
176 | #define LCR_VIE 0x18c /* Video Interface Enable */ | ||
177 | #define LCR_VCS 0x18e /* Video/Camera Select */ | ||
178 | #define LCR_VPHWC 0x194 /* Video Picture Horizontal Wait Count */ | ||
179 | #define LCR_VPHS 0x196 /* Video Picture Horizontal Size */ | ||
180 | #define LCR_VPVWC 0x198 /* Video Picture Vertical Wait Count */ | ||
181 | #define LCR_VPVS 0x19a /* Video Picture Vertical Size */ | ||
182 | #define LCR_PLHPIX 0x1a0 /* PLHPIX */ | ||
183 | #define LCR_XS 0x1a2 /* XStart */ | ||
184 | #define LCR_XCKHW 0x1a4 /* XCK High Width */ | ||
185 | #define LCR_STHS 0x1a8 /* STH Start */ | ||
186 | #define LCR_VT2 0x1aa /* Vertical Total */ | ||
187 | #define LCR_YCKSW 0x1ac /* YCK Start Wait */ | ||
188 | #define LCR_YSTS 0x1ae /* YST Start */ | ||
189 | #define LCR_PPOLS 0x1b0 /* #PPOL Start */ | ||
190 | #define LCR_PRECW 0x1b2 /* PREC Width */ | ||
191 | #define LCR_VCLKHW 0x1b4 /* VCLK High Width */ | ||
192 | #define LCR_OC 0x1b6 /* Output Control */ | ||
193 | |||
194 | static char *mode_option __devinitdata; | ||
195 | |||
196 | struct tmiofb_par { | ||
197 | u32 pseudo_palette[16]; | ||
198 | |||
199 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
200 | wait_queue_head_t wait_acc; | ||
201 | bool use_polling; | ||
202 | #endif | ||
203 | |||
204 | void __iomem *ccr; | ||
205 | void __iomem *lcr; | ||
206 | }; | ||
207 | |||
208 | /*--------------------------------------------------------------------------*/ | ||
209 | |||
210 | /* | ||
211 | * reasons for an interrupt: | ||
212 | * uis bbisc lcdis | ||
213 | * 0100 0001 accelerator command completed | ||
214 | * 2000 0001 vsync start | ||
215 | * 2000 0002 display start | ||
216 | * 2000 0004 line number match(0x1ff mask???) | ||
217 | */ | ||
218 | static irqreturn_t tmiofb_irq(int irq, void *__info) | ||
219 | { | ||
220 | struct fb_info *info = __info; | ||
221 | struct tmiofb_par *par = info->par; | ||
222 | unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC); | ||
223 | |||
224 | |||
225 | /* | ||
226 | * We were in polling mode and now we got correct irq. | ||
227 | * Switch back to IRQ-based sync of command FIFO | ||
228 | */ | ||
229 | if (unlikely(par->use_polling && irq != -1)) { | ||
230 | printk(KERN_INFO "tmiofb: switching to waitq\n"); | ||
231 | par->use_polling = false; | ||
232 | } | ||
233 | |||
234 | tmio_iowrite16(bbisc, par->lcr + LCR_BBISC); | ||
235 | |||
236 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
237 | if (bbisc & 1) | ||
238 | wake_up(&par->wait_acc); | ||
239 | #endif | ||
240 | |||
241 | return IRQ_HANDLED; | ||
242 | } | ||
243 | |||
244 | |||
245 | /*--------------------------------------------------------------------------*/ | ||
246 | |||
247 | |||
248 | /* | ||
249 | * Turns off the LCD controller and LCD host controller. | ||
250 | */ | ||
251 | static int tmiofb_hw_stop(struct platform_device *dev) | ||
252 | { | ||
253 | struct mfd_cell *cell = dev->dev.platform_data; | ||
254 | struct tmio_fb_data *data = cell->driver_data; | ||
255 | struct fb_info *info = platform_get_drvdata(dev); | ||
256 | struct tmiofb_par *par = info->par; | ||
257 | |||
258 | tmio_iowrite16(0, par->ccr + CCR_UGCC); | ||
259 | tmio_iowrite16(0, par->lcr + LCR_GM); | ||
260 | data->lcd_set_power(dev, 0); | ||
261 | tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * Initializes the LCD host controller. | ||
268 | */ | ||
269 | static int tmiofb_hw_init(struct platform_device *dev) | ||
270 | { | ||
271 | struct mfd_cell *cell = dev->dev.platform_data; | ||
272 | struct fb_info *info = platform_get_drvdata(dev); | ||
273 | struct tmiofb_par *par = info->par; | ||
274 | const struct resource *nlcr = &cell->resources[0]; | ||
275 | const struct resource *vram = &cell->resources[2]; | ||
276 | unsigned long base; | ||
277 | |||
278 | if (nlcr == NULL || vram == NULL) | ||
279 | return -EINVAL; | ||
280 | |||
281 | base = nlcr->start; | ||
282 | |||
283 | tmio_iowrite16(0x003a, par->ccr + CCR_UGCC); | ||
284 | tmio_iowrite16(0x003a, par->ccr + CCR_GCC); | ||
285 | tmio_iowrite16(0x3f00, par->ccr + CCR_USC); | ||
286 | |||
287 | msleep(2); /* wait for device to settle */ | ||
288 | |||
289 | tmio_iowrite16(0x0000, par->ccr + CCR_USC); | ||
290 | tmio_iowrite16(base >> 16, par->ccr + CCR_BASEH); | ||
291 | tmio_iowrite16(base, par->ccr + CCR_BASEL); | ||
292 | tmio_iowrite16(0x0002, par->ccr + CCR_CMD); /* base address enable */ | ||
293 | tmio_iowrite16(0x40a8, par->ccr + CCR_VRAMRTC); /* VRAMRC, VRAMTC */ | ||
294 | tmio_iowrite16(0x0018, par->ccr + CCR_VRAMSAC); /* VRAMSTS, VRAMAC */ | ||
295 | tmio_iowrite16(0x0002, par->ccr + CCR_VRAMBC); | ||
296 | msleep(2); /* wait for device to settle */ | ||
297 | tmio_iowrite16(0x000b, par->ccr + CCR_VRAMBC); | ||
298 | |||
299 | base = vram->start + info->screen_size; | ||
300 | tmio_iowrite16(base >> 16, par->lcr + LCR_CFSAH); | ||
301 | tmio_iowrite16(base, par->lcr + LCR_CFSAL); | ||
302 | tmio_iowrite16(TMIOFB_FIFO_SIZE - 1, par->lcr + LCR_CFS); | ||
303 | tmio_iowrite16(1, par->lcr + LCR_CFC); | ||
304 | tmio_iowrite16(1, par->lcr + LCR_BBIE); | ||
305 | tmio_iowrite16(0, par->lcr + LCR_CFWS); | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * Sets the LCD controller's output resolution and pixel clock | ||
312 | */ | ||
313 | static void tmiofb_hw_mode(struct platform_device *dev) | ||
314 | { | ||
315 | struct mfd_cell *cell = dev->dev.platform_data; | ||
316 | struct tmio_fb_data *data = cell->driver_data; | ||
317 | struct fb_info *info = platform_get_drvdata(dev); | ||
318 | struct fb_videomode *mode = info->mode; | ||
319 | struct tmiofb_par *par = info->par; | ||
320 | unsigned int i; | ||
321 | |||
322 | tmio_iowrite16(0, par->lcr + LCR_GM); | ||
323 | data->lcd_set_power(dev, 0); | ||
324 | tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); | ||
325 | data->lcd_mode(dev, mode); | ||
326 | data->lcd_set_power(dev, 1); | ||
327 | |||
328 | tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPN); | ||
329 | tmio_iowrite16(0, par->lcr + LCR_GDSAH); | ||
330 | tmio_iowrite16(0, par->lcr + LCR_GDSAL); | ||
331 | tmio_iowrite16(info->fix.line_length >> 16, par->lcr + LCR_VHPCH); | ||
332 | tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPCL); | ||
333 | tmio_iowrite16(i = 0, par->lcr + LCR_HSS); | ||
334 | tmio_iowrite16(i += mode->hsync_len, par->lcr + LCR_HSE); | ||
335 | tmio_iowrite16(i += mode->left_margin, par->lcr + LCR_HDS); | ||
336 | tmio_iowrite16(i += mode->xres + mode->right_margin, par->lcr + LCR_HT); | ||
337 | tmio_iowrite16(mode->xres, par->lcr + LCR_HNP); | ||
338 | tmio_iowrite16(i = 0, par->lcr + LCR_VSS); | ||
339 | tmio_iowrite16(i += mode->vsync_len, par->lcr + LCR_VSE); | ||
340 | tmio_iowrite16(i += mode->upper_margin, par->lcr + LCR_VDS); | ||
341 | tmio_iowrite16(i += mode->yres, par->lcr + LCR_ILN); | ||
342 | tmio_iowrite16(i += mode->lower_margin, par->lcr + LCR_VT); | ||
343 | tmio_iowrite16(3, par->lcr + LCR_MISC); /* RGB565 mode */ | ||
344 | tmio_iowrite16(1, par->lcr + LCR_GM); /* VRAM enable */ | ||
345 | tmio_iowrite16(0x4007, par->lcr + LCR_LCDCC); | ||
346 | tmio_iowrite16(3, par->lcr + LCR_SP); /* sync polarity */ | ||
347 | |||
348 | tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); | ||
349 | msleep(5); /* wait for device to settle */ | ||
350 | tmio_iowrite16(0x0014, par->lcr + LCR_LCDCCRC); /* STOP_CKP */ | ||
351 | msleep(5); /* wait for device to settle */ | ||
352 | tmio_iowrite16(0x0015, par->lcr + LCR_LCDCCRC); /* STOP_CKP|SOFT_RESET*/ | ||
353 | tmio_iowrite16(0xfffa, par->lcr + LCR_VCS); | ||
354 | } | ||
355 | |||
356 | /*--------------------------------------------------------------------------*/ | ||
357 | |||
358 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
359 | static int __must_check | ||
360 | tmiofb_acc_wait(struct fb_info *info, unsigned int ccs) | ||
361 | { | ||
362 | struct tmiofb_par *par = info->par; | ||
363 | /* | ||
364 | * This code can be called whith interrupts disabled. | ||
365 | * So instead of relaying on irq to trigger the event, | ||
366 | * poll the state till the necessary command is executed. | ||
367 | */ | ||
368 | if (irqs_disabled() || par->use_polling) { | ||
369 | int i = 0; | ||
370 | while (tmio_ioread16(par->lcr + LCR_CCS) > ccs) { | ||
371 | udelay(1); | ||
372 | i++; | ||
373 | if (i > 10000) { | ||
374 | pr_err("tmiofb: timeout waiting for %d\n", | ||
375 | ccs); | ||
376 | return -ETIMEDOUT; | ||
377 | } | ||
378 | tmiofb_irq(-1, info); | ||
379 | } | ||
380 | } else { | ||
381 | if (!wait_event_interruptible_timeout(par->wait_acc, | ||
382 | tmio_ioread16(par->lcr + LCR_CCS) <= ccs, | ||
383 | 1000)) { | ||
384 | pr_err("tmiofb: timeout waiting for %d\n", ccs); | ||
385 | return -ETIMEDOUT; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * Writes an accelerator command to the accelerator's FIFO. | ||
394 | */ | ||
395 | static int | ||
396 | tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count) | ||
397 | { | ||
398 | struct tmiofb_par *par = info->par; | ||
399 | int ret; | ||
400 | |||
401 | ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count); | ||
402 | if (ret) | ||
403 | return ret; | ||
404 | |||
405 | for (; count; count--, cmd++) { | ||
406 | tmio_iowrite16(*cmd >> 16, par->lcr + LCR_CMDH); | ||
407 | tmio_iowrite16(*cmd, par->lcr + LCR_CMDL); | ||
408 | } | ||
409 | |||
410 | return ret; | ||
411 | } | ||
412 | |||
413 | /* | ||
414 | * Wait for the accelerator to finish its operations before writing | ||
415 | * to the framebuffer for consistent display output. | ||
416 | */ | ||
417 | static int tmiofb_sync(struct fb_info *fbi) | ||
418 | { | ||
419 | struct tmiofb_par *par = fbi->par; | ||
420 | |||
421 | int ret; | ||
422 | int i = 0; | ||
423 | |||
424 | ret = tmiofb_acc_wait(fbi, 0); | ||
425 | |||
426 | while (tmio_ioread16(par->lcr + LCR_BBES) & 2) { /* blit active */ | ||
427 | udelay(1); | ||
428 | i++ ; | ||
429 | if (i > 10000) { | ||
430 | printk(KERN_ERR "timeout waiting for blit to end!\n"); | ||
431 | return -ETIMEDOUT; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | static void | ||
439 | tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect) | ||
440 | { | ||
441 | const u32 cmd[] = { | ||
442 | TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2), | ||
443 | TMIOFB_ACC_DHPIX(rect->width - 1), | ||
444 | TMIOFB_ACC_DVPIX(rect->height - 1), | ||
445 | TMIOFB_ACC_FILL(rect->color), | ||
446 | TMIOFB_ACC_FLGO, | ||
447 | }; | ||
448 | |||
449 | if (fbi->state != FBINFO_STATE_RUNNING || | ||
450 | fbi->flags & FBINFO_HWACCEL_DISABLED) { | ||
451 | cfb_fillrect(fbi, rect); | ||
452 | return; | ||
453 | } | ||
454 | |||
455 | tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd)); | ||
456 | } | ||
457 | |||
458 | static void | ||
459 | tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area) | ||
460 | { | ||
461 | const u32 cmd[] = { | ||
462 | TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2), | ||
463 | TMIOFB_ACC_DHPIX(area->width - 1), | ||
464 | TMIOFB_ACC_DVPIX(area->height - 1), | ||
465 | TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2), | ||
466 | TMIOFB_ACC_SCGO, | ||
467 | }; | ||
468 | |||
469 | if (fbi->state != FBINFO_STATE_RUNNING || | ||
470 | fbi->flags & FBINFO_HWACCEL_DISABLED) { | ||
471 | cfb_copyarea(fbi, area); | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd)); | ||
476 | } | ||
477 | #endif | ||
478 | |||
479 | static void tmiofb_clearscreen(struct fb_info *info) | ||
480 | { | ||
481 | const struct fb_fillrect rect = { | ||
482 | .dx = 0, | ||
483 | .dy = 0, | ||
484 | .width = info->mode->xres, | ||
485 | .height = info->mode->yres, | ||
486 | .color = 0, | ||
487 | .rop = ROP_COPY, | ||
488 | }; | ||
489 | |||
490 | info->fbops->fb_fillrect(info, &rect); | ||
491 | } | ||
492 | |||
493 | static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank) | ||
494 | { | ||
495 | struct tmiofb_par *par = fbi->par; | ||
496 | struct fb_videomode *mode = fbi->mode; | ||
497 | unsigned int vcount = tmio_ioread16(par->lcr + LCR_CDLN); | ||
498 | unsigned int vds = mode->vsync_len + mode->upper_margin; | ||
499 | |||
500 | vblank->vcount = vcount; | ||
501 | vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT | ||
502 | | FB_VBLANK_HAVE_VSYNC; | ||
503 | |||
504 | if (vcount < mode->vsync_len) | ||
505 | vblank->flags |= FB_VBLANK_VSYNCING; | ||
506 | |||
507 | if (vcount < vds || vcount > vds + mode->yres) | ||
508 | vblank->flags |= FB_VBLANK_VBLANKING; | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | |||
514 | static int tmiofb_ioctl(struct fb_info *fbi, | ||
515 | unsigned int cmd, unsigned long arg) | ||
516 | { | ||
517 | switch (cmd) { | ||
518 | case FBIOGET_VBLANK: { | ||
519 | struct fb_vblank vblank = {0}; | ||
520 | void __user *argp = (void __user *) arg; | ||
521 | |||
522 | tmiofb_vblank(fbi, &vblank); | ||
523 | if (copy_to_user(argp, &vblank, sizeof vblank)) | ||
524 | return -EFAULT; | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
529 | case FBIO_TMIO_ACC_SYNC: | ||
530 | tmiofb_sync(fbi); | ||
531 | return 0; | ||
532 | |||
533 | case FBIO_TMIO_ACC_WRITE: { | ||
534 | u32 __user *argp = (void __user *) arg; | ||
535 | u32 len; | ||
536 | u32 acc[16]; | ||
537 | |||
538 | if (get_user(len, argp)) | ||
539 | return -EFAULT; | ||
540 | if (len > ARRAY_SIZE(acc)) | ||
541 | return -EINVAL; | ||
542 | if (copy_from_user(acc, argp + 1, sizeof(u32) * len)) | ||
543 | return -EFAULT; | ||
544 | |||
545 | return tmiofb_acc_write(fbi, acc, len); | ||
546 | } | ||
547 | #endif | ||
548 | } | ||
549 | |||
550 | return -ENOTTY; | ||
551 | } | ||
552 | |||
553 | /*--------------------------------------------------------------------------*/ | ||
554 | |||
555 | /* Select the smallest mode that allows the desired resolution to be | ||
556 | * displayed. If desired, the x and y parameters can be rounded up to | ||
557 | * match the selected mode. | ||
558 | */ | ||
559 | static struct fb_videomode * | ||
560 | tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) | ||
561 | { | ||
562 | struct mfd_cell *cell = | ||
563 | info->device->platform_data; | ||
564 | struct tmio_fb_data *data = cell->driver_data; | ||
565 | struct fb_videomode *best = NULL; | ||
566 | int i; | ||
567 | |||
568 | for (i = 0; i < data->num_modes; i++) { | ||
569 | struct fb_videomode *mode = data->modes + i; | ||
570 | |||
571 | if (mode->xres >= var->xres && mode->yres >= var->yres | ||
572 | && (!best || (mode->xres < best->xres | ||
573 | && mode->yres < best->yres))) | ||
574 | best = mode; | ||
575 | } | ||
576 | |||
577 | return best; | ||
578 | } | ||
579 | |||
580 | static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
581 | { | ||
582 | |||
583 | struct fb_videomode *mode; | ||
584 | struct mfd_cell *cell = | ||
585 | info->device->platform_data; | ||
586 | struct tmio_fb_data *data = cell->driver_data; | ||
587 | |||
588 | mode = tmiofb_find_mode(info, var); | ||
589 | if (!mode || var->bits_per_pixel > 16) | ||
590 | return -EINVAL; | ||
591 | |||
592 | fb_videomode_to_var(var, mode); | ||
593 | |||
594 | var->xres_virtual = mode->xres; | ||
595 | var->yres_virtual = info->screen_size / (mode->xres * 2); | ||
596 | |||
597 | if (var->yres_virtual < var->yres) | ||
598 | return -EINVAL; | ||
599 | |||
600 | var->xoffset = 0; | ||
601 | var->yoffset = 0; | ||
602 | var->bits_per_pixel = 16; | ||
603 | var->grayscale = 0; | ||
604 | var->red.offset = 11; | ||
605 | var->red.length = 5; | ||
606 | var->green.offset = 5; | ||
607 | var->green.length = 6; | ||
608 | var->blue.offset = 0; | ||
609 | var->blue.length = 5; | ||
610 | var->transp.offset = 0; | ||
611 | var->transp.length = 0; | ||
612 | var->nonstd = 0; | ||
613 | var->height = data->height; /* mm */ | ||
614 | var->width = data->width; /* mm */ | ||
615 | var->rotate = 0; | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static int tmiofb_set_par(struct fb_info *info) | ||
620 | { | ||
621 | struct fb_var_screeninfo *var = &info->var; | ||
622 | struct fb_videomode *mode; | ||
623 | |||
624 | mode = tmiofb_find_mode(info, var); | ||
625 | if (!mode) | ||
626 | return -EINVAL; | ||
627 | |||
628 | info->mode = mode; | ||
629 | info->fix.line_length = info->mode->xres * | ||
630 | var->bits_per_pixel / 8; | ||
631 | |||
632 | tmiofb_hw_mode(to_platform_device(info->device)); | ||
633 | tmiofb_clearscreen(info); | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
638 | unsigned blue, unsigned transp, | ||
639 | struct fb_info *info) | ||
640 | { | ||
641 | struct tmiofb_par *par = info->par; | ||
642 | |||
643 | if (regno < ARRAY_SIZE(par->pseudo_palette)) { | ||
644 | par->pseudo_palette[regno] = | ||
645 | ((red & 0xf800)) | | ||
646 | ((green & 0xfc00) >> 5) | | ||
647 | ((blue & 0xf800) >> 11); | ||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | return -EINVAL; | ||
652 | } | ||
653 | |||
654 | static int tmiofb_blank(int blank, struct fb_info *info) | ||
655 | { | ||
656 | /* | ||
657 | * everything is done in lcd/bl drivers. | ||
658 | * this is purely to make sysfs happy and work. | ||
659 | */ | ||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | static struct fb_ops tmiofb_ops = { | ||
664 | .owner = THIS_MODULE, | ||
665 | |||
666 | .fb_ioctl = tmiofb_ioctl, | ||
667 | .fb_check_var = tmiofb_check_var, | ||
668 | .fb_set_par = tmiofb_set_par, | ||
669 | .fb_setcolreg = tmiofb_setcolreg, | ||
670 | .fb_blank = tmiofb_blank, | ||
671 | .fb_imageblit = cfb_imageblit, | ||
672 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
673 | .fb_sync = tmiofb_sync, | ||
674 | .fb_fillrect = tmiofb_fillrect, | ||
675 | .fb_copyarea = tmiofb_copyarea, | ||
676 | #else | ||
677 | .fb_fillrect = cfb_fillrect, | ||
678 | .fb_copyarea = cfb_copyarea, | ||
679 | #endif | ||
680 | }; | ||
681 | |||
682 | /*--------------------------------------------------------------------------*/ | ||
683 | |||
684 | static int __devinit tmiofb_probe(struct platform_device *dev) | ||
685 | { | ||
686 | struct mfd_cell *cell = dev->dev.platform_data; | ||
687 | struct tmio_fb_data *data = cell->driver_data; | ||
688 | struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); | ||
689 | struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
690 | struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); | ||
691 | int irq = platform_get_irq(dev, 0); | ||
692 | struct fb_info *info; | ||
693 | struct tmiofb_par *par; | ||
694 | int retval; | ||
695 | |||
696 | /* | ||
697 | * This is the only way ATM to disable the fb | ||
698 | */ | ||
699 | if (data == NULL) { | ||
700 | dev_err(&dev->dev, "NULL platform data!\n"); | ||
701 | return -EINVAL; | ||
702 | } | ||
703 | |||
704 | info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev); | ||
705 | |||
706 | if (!info) | ||
707 | return -ENOMEM; | ||
708 | |||
709 | par = info->par; | ||
710 | |||
711 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
712 | init_waitqueue_head(&par->wait_acc); | ||
713 | |||
714 | par->use_polling = true; | ||
715 | |||
716 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | ||
717 | | FBINFO_HWACCEL_FILLRECT; | ||
718 | #else | ||
719 | info->flags = FBINFO_DEFAULT; | ||
720 | #endif | ||
721 | |||
722 | info->fbops = &tmiofb_ops; | ||
723 | |||
724 | strcpy(info->fix.id, "tmio-fb"); | ||
725 | info->fix.smem_start = vram->start; | ||
726 | info->fix.smem_len = resource_size(vram); | ||
727 | info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
728 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
729 | info->fix.mmio_start = lcr->start; | ||
730 | info->fix.mmio_len = resource_size(lcr); | ||
731 | info->fix.accel = FB_ACCEL_NONE; | ||
732 | info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE); | ||
733 | info->pseudo_palette = par->pseudo_palette; | ||
734 | |||
735 | par->ccr = ioremap(ccr->start, resource_size(ccr)); | ||
736 | if (!par->ccr) { | ||
737 | retval = -ENOMEM; | ||
738 | goto err_ioremap_ccr; | ||
739 | } | ||
740 | |||
741 | par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len); | ||
742 | if (!par->lcr) { | ||
743 | retval = -ENOMEM; | ||
744 | goto err_ioremap_lcr; | ||
745 | } | ||
746 | |||
747 | info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); | ||
748 | if (!info->screen_base) { | ||
749 | retval = -ENOMEM; | ||
750 | goto err_ioremap_vram; | ||
751 | } | ||
752 | |||
753 | retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED, | ||
754 | dev->dev.bus_id, info); | ||
755 | |||
756 | if (retval) | ||
757 | goto err_request_irq; | ||
758 | |||
759 | platform_set_drvdata(dev, info); | ||
760 | |||
761 | retval = fb_find_mode(&info->var, info, mode_option, | ||
762 | data->modes, data->num_modes, | ||
763 | data->modes, 16); | ||
764 | if (!retval) { | ||
765 | retval = -EINVAL; | ||
766 | goto err_find_mode; | ||
767 | } | ||
768 | |||
769 | if (cell->enable) { | ||
770 | retval = cell->enable(dev); | ||
771 | if (retval) | ||
772 | goto err_enable; | ||
773 | } | ||
774 | |||
775 | retval = tmiofb_hw_init(dev); | ||
776 | if (retval) | ||
777 | goto err_hw_init; | ||
778 | |||
779 | fb_videomode_to_modelist(data->modes, data->num_modes, | ||
780 | &info->modelist); | ||
781 | |||
782 | retval = register_framebuffer(info); | ||
783 | if (retval < 0) | ||
784 | goto err_register_framebuffer; | ||
785 | |||
786 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | ||
787 | info->node, info->fix.id); | ||
788 | |||
789 | return 0; | ||
790 | |||
791 | err_register_framebuffer: | ||
792 | /*err_set_par:*/ | ||
793 | tmiofb_hw_stop(dev); | ||
794 | err_hw_init: | ||
795 | if (cell->disable) | ||
796 | cell->disable(dev); | ||
797 | err_enable: | ||
798 | err_find_mode: | ||
799 | platform_set_drvdata(dev, NULL); | ||
800 | free_irq(irq, info); | ||
801 | err_request_irq: | ||
802 | iounmap(info->screen_base); | ||
803 | err_ioremap_vram: | ||
804 | iounmap(par->lcr); | ||
805 | err_ioremap_lcr: | ||
806 | iounmap(par->ccr); | ||
807 | err_ioremap_ccr: | ||
808 | framebuffer_release(info); | ||
809 | return retval; | ||
810 | } | ||
811 | |||
812 | static int __devexit tmiofb_remove(struct platform_device *dev) | ||
813 | { | ||
814 | struct mfd_cell *cell = dev->dev.platform_data; | ||
815 | struct fb_info *info = platform_get_drvdata(dev); | ||
816 | int irq = platform_get_irq(dev, 0); | ||
817 | struct tmiofb_par *par; | ||
818 | |||
819 | if (info) { | ||
820 | par = info->par; | ||
821 | unregister_framebuffer(info); | ||
822 | |||
823 | tmiofb_hw_stop(dev); | ||
824 | |||
825 | if (cell->disable) | ||
826 | cell->disable(dev); | ||
827 | |||
828 | platform_set_drvdata(dev, NULL); | ||
829 | |||
830 | free_irq(irq, info); | ||
831 | |||
832 | iounmap(info->screen_base); | ||
833 | iounmap(par->lcr); | ||
834 | iounmap(par->ccr); | ||
835 | |||
836 | framebuffer_release(info); | ||
837 | } | ||
838 | |||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | #ifdef DEBUG | ||
843 | static void tmiofb_dump_regs(struct platform_device *dev) | ||
844 | { | ||
845 | struct fb_info *info = platform_get_drvdata(dev); | ||
846 | struct tmiofb_par *par = info->par; | ||
847 | |||
848 | printk(KERN_DEBUG "lhccr:\n"); | ||
849 | #define CCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\ | ||
850 | tmio_ioread16(par->ccr + CCR_ ## n)); | ||
851 | CCR_PR(CMD); | ||
852 | CCR_PR(REVID); | ||
853 | CCR_PR(BASEL); | ||
854 | CCR_PR(BASEH); | ||
855 | CCR_PR(UGCC); | ||
856 | CCR_PR(GCC); | ||
857 | CCR_PR(USC); | ||
858 | CCR_PR(VRAMRTC); | ||
859 | CCR_PR(VRAMSAC); | ||
860 | CCR_PR(VRAMBC); | ||
861 | #undef CCR_PR | ||
862 | |||
863 | printk(KERN_DEBUG "lcr: \n"); | ||
864 | #define LCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\ | ||
865 | tmio_ioread16(par->lcr + LCR_ ## n)); | ||
866 | LCR_PR(UIS); | ||
867 | LCR_PR(VHPN); | ||
868 | LCR_PR(CFSAL); | ||
869 | LCR_PR(CFSAH); | ||
870 | LCR_PR(CFS); | ||
871 | LCR_PR(CFWS); | ||
872 | LCR_PR(BBIE); | ||
873 | LCR_PR(BBISC); | ||
874 | LCR_PR(CCS); | ||
875 | LCR_PR(BBES); | ||
876 | LCR_PR(CMDL); | ||
877 | LCR_PR(CMDH); | ||
878 | LCR_PR(CFC); | ||
879 | LCR_PR(CCIFC); | ||
880 | LCR_PR(HWT); | ||
881 | LCR_PR(LCDCCRC); | ||
882 | LCR_PR(LCDCC); | ||
883 | LCR_PR(LCDCOPC); | ||
884 | LCR_PR(LCDIS); | ||
885 | LCR_PR(LCDIM); | ||
886 | LCR_PR(LCDIE); | ||
887 | LCR_PR(GDSAL); | ||
888 | LCR_PR(GDSAH); | ||
889 | LCR_PR(VHPCL); | ||
890 | LCR_PR(VHPCH); | ||
891 | LCR_PR(GM); | ||
892 | LCR_PR(HT); | ||
893 | LCR_PR(HDS); | ||
894 | LCR_PR(HSS); | ||
895 | LCR_PR(HSE); | ||
896 | LCR_PR(HNP); | ||
897 | LCR_PR(VT); | ||
898 | LCR_PR(VDS); | ||
899 | LCR_PR(VSS); | ||
900 | LCR_PR(VSE); | ||
901 | LCR_PR(CDLN); | ||
902 | LCR_PR(ILN); | ||
903 | LCR_PR(SP); | ||
904 | LCR_PR(MISC); | ||
905 | LCR_PR(VIHSS); | ||
906 | LCR_PR(VIVS); | ||
907 | LCR_PR(VIVE); | ||
908 | LCR_PR(VIVSS); | ||
909 | LCR_PR(VCCIS); | ||
910 | LCR_PR(VIDWSAL); | ||
911 | LCR_PR(VIDWSAH); | ||
912 | LCR_PR(VIDRSAL); | ||
913 | LCR_PR(VIDRSAH); | ||
914 | LCR_PR(VIPDDST); | ||
915 | LCR_PR(VIPDDET); | ||
916 | LCR_PR(VIE); | ||
917 | LCR_PR(VCS); | ||
918 | LCR_PR(VPHWC); | ||
919 | LCR_PR(VPHS); | ||
920 | LCR_PR(VPVWC); | ||
921 | LCR_PR(VPVS); | ||
922 | LCR_PR(PLHPIX); | ||
923 | LCR_PR(XS); | ||
924 | LCR_PR(XCKHW); | ||
925 | LCR_PR(STHS); | ||
926 | LCR_PR(VT2); | ||
927 | LCR_PR(YCKSW); | ||
928 | LCR_PR(YSTS); | ||
929 | LCR_PR(PPOLS); | ||
930 | LCR_PR(PRECW); | ||
931 | LCR_PR(VCLKHW); | ||
932 | LCR_PR(OC); | ||
933 | #undef LCR_PR | ||
934 | } | ||
935 | #endif | ||
936 | |||
937 | #ifdef CONFIG_PM | ||
938 | static int tmiofb_suspend(struct platform_device *dev, pm_message_t state) | ||
939 | { | ||
940 | struct fb_info *info = platform_get_drvdata(dev); | ||
941 | struct tmiofb_par *par = info->par; | ||
942 | struct mfd_cell *cell = dev->dev.platform_data; | ||
943 | int retval = 0; | ||
944 | |||
945 | acquire_console_sem(); | ||
946 | |||
947 | fb_set_suspend(info, 1); | ||
948 | |||
949 | if (info->fbops->fb_sync) | ||
950 | info->fbops->fb_sync(info); | ||
951 | |||
952 | |||
953 | /* | ||
954 | * The fb should be usable even if interrupts are disabled (and they are | ||
955 | * during suspend/resume). Switch temporary to forced polling. | ||
956 | */ | ||
957 | printk(KERN_INFO "tmiofb: switching to polling\n"); | ||
958 | par->use_polling = true; | ||
959 | tmiofb_hw_stop(dev); | ||
960 | |||
961 | if (cell->suspend) | ||
962 | retval = cell->suspend(dev); | ||
963 | |||
964 | release_console_sem(); | ||
965 | |||
966 | return retval; | ||
967 | } | ||
968 | |||
969 | static int tmiofb_resume(struct platform_device *dev) | ||
970 | { | ||
971 | struct fb_info *info = platform_get_drvdata(dev); | ||
972 | struct mfd_cell *cell = dev->dev.platform_data; | ||
973 | int retval; | ||
974 | |||
975 | acquire_console_sem(); | ||
976 | |||
977 | if (cell->resume) { | ||
978 | retval = cell->resume(dev); | ||
979 | if (retval) | ||
980 | goto out; | ||
981 | } | ||
982 | |||
983 | tmiofb_irq(-1, info); | ||
984 | |||
985 | tmiofb_hw_init(dev); | ||
986 | |||
987 | tmiofb_hw_mode(dev); | ||
988 | |||
989 | fb_set_suspend(info, 0); | ||
990 | out: | ||
991 | release_console_sem(); | ||
992 | return retval; | ||
993 | } | ||
994 | #else | ||
995 | #define tmiofb_suspend NULL | ||
996 | #define tmiofb_resume NULL | ||
997 | #endif | ||
998 | |||
999 | static struct platform_driver tmiofb_driver = { | ||
1000 | .driver.name = "tmio-fb", | ||
1001 | .driver.owner = THIS_MODULE, | ||
1002 | .probe = tmiofb_probe, | ||
1003 | .remove = __devexit_p(tmiofb_remove), | ||
1004 | .suspend = tmiofb_suspend, | ||
1005 | .resume = tmiofb_resume, | ||
1006 | }; | ||
1007 | |||
1008 | /*--------------------------------------------------------------------------*/ | ||
1009 | |||
1010 | #ifndef MODULE | ||
1011 | static void __init tmiofb_setup(char *options) | ||
1012 | { | ||
1013 | char *this_opt; | ||
1014 | |||
1015 | if (!options || !*options) | ||
1016 | return; | ||
1017 | |||
1018 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
1019 | if (!*this_opt) | ||
1020 | continue; | ||
1021 | /* | ||
1022 | * FIXME | ||
1023 | */ | ||
1024 | } | ||
1025 | } | ||
1026 | #endif | ||
1027 | |||
1028 | static int __init tmiofb_init(void) | ||
1029 | { | ||
1030 | #ifndef MODULE | ||
1031 | char *option = NULL; | ||
1032 | |||
1033 | if (fb_get_options("tmiofb", &option)) | ||
1034 | return -ENODEV; | ||
1035 | tmiofb_setup(option); | ||
1036 | #endif | ||
1037 | return platform_driver_register(&tmiofb_driver); | ||
1038 | } | ||
1039 | |||
1040 | static void __exit tmiofb_cleanup(void) | ||
1041 | { | ||
1042 | platform_driver_unregister(&tmiofb_driver); | ||
1043 | } | ||
1044 | |||
1045 | module_init(tmiofb_init); | ||
1046 | module_exit(tmiofb_cleanup); | ||
1047 | |||
1048 | MODULE_DESCRIPTION("TMIO framebuffer driver"); | ||
1049 | MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov"); | ||
1050 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index 50744229c7a9..6c2d37fdd3b9 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c | |||
@@ -516,10 +516,12 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task, | |||
516 | 516 | ||
517 | err = uvesafb_exec(task); | 517 | err = uvesafb_exec(task); |
518 | if (err || (task->t.regs.eax & 0xffff) != 0x004f) { | 518 | if (err || (task->t.regs.eax & 0xffff) != 0x004f) { |
519 | printk(KERN_ERR "uvesafb: Getting mode info block " | 519 | printk(KERN_WARNING "uvesafb: Getting mode info block " |
520 | "for mode 0x%x failed (eax=0x%x, err=%d)\n", | 520 | "for mode 0x%x failed (eax=0x%x, err=%d)\n", |
521 | *mode, (u32)task->t.regs.eax, err); | 521 | *mode, (u32)task->t.regs.eax, err); |
522 | return -EINVAL; | 522 | mode++; |
523 | par->vbe_modes_cnt--; | ||
524 | continue; | ||
523 | } | 525 | } |
524 | 526 | ||
525 | mib = task->buf; | 527 | mib = task->buf; |
@@ -548,7 +550,10 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task, | |||
548 | mib->depth = mib->bits_per_pixel; | 550 | mib->depth = mib->bits_per_pixel; |
549 | } | 551 | } |
550 | 552 | ||
551 | return 0; | 553 | if (par->vbe_modes_cnt > 0) |
554 | return 0; | ||
555 | else | ||
556 | return -EINVAL; | ||
552 | } | 557 | } |
553 | 558 | ||
554 | /* | 559 | /* |
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index e31bca8a0cb2..5b2938903ac2 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c | |||
@@ -58,7 +58,6 @@ struct vga16fb_par { | |||
58 | unsigned char ClockingMode; /* Seq-Controller:01h */ | 58 | unsigned char ClockingMode; /* Seq-Controller:01h */ |
59 | } vga_state; | 59 | } vga_state; |
60 | struct vgastate state; | 60 | struct vgastate state; |
61 | struct mutex open_lock; | ||
62 | unsigned int ref_count; | 61 | unsigned int ref_count; |
63 | int palette_blanked, vesa_blanked, mode, isVGA; | 62 | int palette_blanked, vesa_blanked, mode, isVGA; |
64 | u8 misc, pel_msk, vss, clkdiv; | 63 | u8 misc, pel_msk, vss, clkdiv; |
@@ -286,7 +285,6 @@ static int vga16fb_open(struct fb_info *info, int user) | |||
286 | { | 285 | { |
287 | struct vga16fb_par *par = info->par; | 286 | struct vga16fb_par *par = info->par; |
288 | 287 | ||
289 | mutex_lock(&par->open_lock); | ||
290 | if (!par->ref_count) { | 288 | if (!par->ref_count) { |
291 | memset(&par->state, 0, sizeof(struct vgastate)); | 289 | memset(&par->state, 0, sizeof(struct vgastate)); |
292 | par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE | | 290 | par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE | |
@@ -294,7 +292,6 @@ static int vga16fb_open(struct fb_info *info, int user) | |||
294 | save_vga(&par->state); | 292 | save_vga(&par->state); |
295 | } | 293 | } |
296 | par->ref_count++; | 294 | par->ref_count++; |
297 | mutex_unlock(&par->open_lock); | ||
298 | 295 | ||
299 | return 0; | 296 | return 0; |
300 | } | 297 | } |
@@ -303,15 +300,12 @@ static int vga16fb_release(struct fb_info *info, int user) | |||
303 | { | 300 | { |
304 | struct vga16fb_par *par = info->par; | 301 | struct vga16fb_par *par = info->par; |
305 | 302 | ||
306 | mutex_lock(&par->open_lock); | 303 | if (!par->ref_count) |
307 | if (!par->ref_count) { | ||
308 | mutex_unlock(&par->open_lock); | ||
309 | return -EINVAL; | 304 | return -EINVAL; |
310 | } | 305 | |
311 | if (par->ref_count == 1) | 306 | if (par->ref_count == 1) |
312 | restore_vga(&par->state); | 307 | restore_vga(&par->state); |
313 | par->ref_count--; | 308 | par->ref_count--; |
314 | mutex_unlock(&par->open_lock); | ||
315 | 309 | ||
316 | return 0; | 310 | return 0; |
317 | } | 311 | } |
@@ -1326,7 +1320,6 @@ static int __init vga16fb_probe(struct platform_device *dev) | |||
1326 | printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base); | 1320 | printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base); |
1327 | par = info->par; | 1321 | par = info->par; |
1328 | 1322 | ||
1329 | mutex_init(&par->open_lock); | ||
1330 | par->isVGA = screen_info.orig_video_isVGA; | 1323 | par->isVGA = screen_info.orig_video_isVGA; |
1331 | par->palette_blanked = 0; | 1324 | par->palette_blanked = 0; |
1332 | par->vesa_blanked = 0; | 1325 | par->vesa_blanked = 0; |
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile new file mode 100644 index 000000000000..e533b4b6aba4 --- /dev/null +++ b/drivers/video/via/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for the VIA framebuffer driver (for Linux Kernel 2.6) | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_FB_VIA) += viafb.o | ||
6 | |||
7 | viafb-y :=viafbdev.o hw.o iface.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o | ||
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c new file mode 100644 index 000000000000..632523ff1fb7 --- /dev/null +++ b/drivers/video/via/accel.c | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #include "global.h" | ||
22 | |||
23 | void viafb_init_accel(void) | ||
24 | { | ||
25 | viaparinfo->fbmem_free -= CURSOR_SIZE; | ||
26 | viaparinfo->cursor_start = viaparinfo->fbmem_free; | ||
27 | viaparinfo->fbmem_used += CURSOR_SIZE; | ||
28 | |||
29 | /* Reverse 8*1024 memory space for cursor image */ | ||
30 | viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE); | ||
31 | viaparinfo->VQ_start = viaparinfo->fbmem_free; | ||
32 | viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1; | ||
33 | viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); } | ||
34 | |||
35 | void viafb_init_2d_engine(void) | ||
36 | { | ||
37 | u32 dwVQStartAddr, dwVQEndAddr; | ||
38 | u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH; | ||
39 | |||
40 | /* init 2D engine regs to reset 2D engine */ | ||
41 | writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE); | ||
42 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); | ||
43 | writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS); | ||
44 | writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION); | ||
45 | writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR); | ||
46 | writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR); | ||
47 | writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR); | ||
48 | writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL); | ||
49 | writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR); | ||
50 | writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET); | ||
51 | writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL); | ||
52 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
53 | writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
54 | writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH); | ||
55 | writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1); | ||
56 | |||
57 | /* Init AGP and VQ regs */ | ||
58 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
59 | case UNICHROME_K8M890: | ||
60 | case UNICHROME_P4M900: | ||
61 | writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET); | ||
62 | writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
63 | writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
64 | break; | ||
65 | |||
66 | default: | ||
67 | writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET); | ||
68 | writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
69 | writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
70 | writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
71 | writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
72 | writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
73 | writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
74 | writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
75 | writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
76 | |||
77 | writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET); | ||
78 | writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
79 | break; | ||
80 | } | ||
81 | if (viaparinfo->VQ_start != 0) { | ||
82 | /* Enable VQ */ | ||
83 | dwVQStartAddr = viaparinfo->VQ_start; | ||
84 | dwVQEndAddr = viaparinfo->VQ_end; | ||
85 | |||
86 | dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); | ||
87 | dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); | ||
88 | dwVQStartEndH = 0x52000000 | | ||
89 | ((dwVQStartAddr & 0xFF000000) >> 24) | | ||
90 | ((dwVQEndAddr & 0xFF000000) >> 16); | ||
91 | dwVQLen = 0x53000000 | (VQ_SIZE >> 3); | ||
92 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
93 | case UNICHROME_K8M890: | ||
94 | case UNICHROME_P4M900: | ||
95 | dwVQStartL |= 0x20000000; | ||
96 | dwVQEndL |= 0x20000000; | ||
97 | dwVQStartEndH |= 0x20000000; | ||
98 | dwVQLen |= 0x20000000; | ||
99 | break; | ||
100 | default: | ||
101 | break; | ||
102 | } | ||
103 | |||
104 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
105 | case UNICHROME_K8M890: | ||
106 | case UNICHROME_P4M900: | ||
107 | writel(0x00100000, | ||
108 | viaparinfo->io_virt + VIA_REG_CR_TRANSET); | ||
109 | writel(dwVQStartEndH, | ||
110 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
111 | writel(dwVQStartL, | ||
112 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
113 | writel(dwVQEndL, | ||
114 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
115 | writel(dwVQLen, | ||
116 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
117 | writel(0x74301001, | ||
118 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
119 | writel(0x00000000, | ||
120 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
121 | break; | ||
122 | default: | ||
123 | writel(0x00FE0000, | ||
124 | viaparinfo->io_virt + VIA_REG_TRANSET); | ||
125 | writel(0x080003FE, | ||
126 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
127 | writel(0x0A00027C, | ||
128 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
129 | writel(0x0B000260, | ||
130 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
131 | writel(0x0C000274, | ||
132 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
133 | writel(0x0D000264, | ||
134 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
135 | writel(0x0E000000, | ||
136 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
137 | writel(0x0F000020, | ||
138 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
139 | writel(0x1000027E, | ||
140 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
141 | writel(0x110002FE, | ||
142 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
143 | writel(0x200F0060, | ||
144 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
145 | |||
146 | writel(0x00000006, | ||
147 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
148 | writel(0x40008C0F, | ||
149 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
150 | writel(0x44000000, | ||
151 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
152 | writel(0x45080C04, | ||
153 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
154 | writel(0x46800408, | ||
155 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
156 | |||
157 | writel(dwVQStartEndH, | ||
158 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
159 | writel(dwVQStartL, | ||
160 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
161 | writel(dwVQEndL, | ||
162 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
163 | writel(dwVQLen, | ||
164 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
165 | break; | ||
166 | } | ||
167 | } else { | ||
168 | /* Disable VQ */ | ||
169 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
170 | case UNICHROME_K8M890: | ||
171 | case UNICHROME_P4M900: | ||
172 | writel(0x00100000, | ||
173 | viaparinfo->io_virt + VIA_REG_CR_TRANSET); | ||
174 | writel(0x74301000, | ||
175 | viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); | ||
176 | break; | ||
177 | default: | ||
178 | writel(0x00FE0000, | ||
179 | viaparinfo->io_virt + VIA_REG_TRANSET); | ||
180 | writel(0x00000004, | ||
181 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
182 | writel(0x40008C0F, | ||
183 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
184 | writel(0x44000000, | ||
185 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
186 | writel(0x45080C04, | ||
187 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
188 | writel(0x46800408, | ||
189 | viaparinfo->io_virt + VIA_REG_TRANSPACE); | ||
190 | break; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | viafb_set_2d_color_depth(viaparinfo->bpp); | ||
195 | |||
196 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
197 | writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
198 | |||
199 | writel(VIA_PITCH_ENABLE | | ||
200 | (((viaparinfo->hres * | ||
201 | viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres * | ||
202 | viaparinfo-> | ||
203 | bpp >> 3) >> 3) << 16)), | ||
204 | viaparinfo->io_virt + VIA_REG_PITCH); | ||
205 | } | ||
206 | |||
207 | void viafb_set_2d_color_depth(int bpp) | ||
208 | { | ||
209 | u32 dwGEMode; | ||
210 | |||
211 | dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF; | ||
212 | |||
213 | switch (bpp) { | ||
214 | case 16: | ||
215 | dwGEMode |= VIA_GEM_16bpp; | ||
216 | break; | ||
217 | case 32: | ||
218 | dwGEMode |= VIA_GEM_32bpp; | ||
219 | break; | ||
220 | default: | ||
221 | dwGEMode |= VIA_GEM_8bpp; | ||
222 | break; | ||
223 | } | ||
224 | |||
225 | /* Set BPP and Pitch */ | ||
226 | writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE); | ||
227 | } | ||
228 | |||
229 | void viafb_hw_cursor_init(void) | ||
230 | { | ||
231 | /* Set Cursor Image Base Address */ | ||
232 | writel(viaparinfo->cursor_start, | ||
233 | viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | ||
234 | writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS); | ||
235 | writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); | ||
236 | writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG); | ||
237 | writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG); | ||
238 | } | ||
239 | |||
240 | void viafb_show_hw_cursor(struct fb_info *info, int Status) | ||
241 | { | ||
242 | u32 temp; | ||
243 | u32 iga_path = ((struct viafb_par *)(info->par))->iga_path; | ||
244 | |||
245 | temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | ||
246 | switch (Status) { | ||
247 | case HW_Cursor_ON: | ||
248 | temp |= 0x1; | ||
249 | break; | ||
250 | case HW_Cursor_OFF: | ||
251 | temp &= 0xFFFFFFFE; | ||
252 | break; | ||
253 | } | ||
254 | switch (iga_path) { | ||
255 | case IGA2: | ||
256 | temp |= 0x80000000; | ||
257 | break; | ||
258 | case IGA1: | ||
259 | default: | ||
260 | temp &= 0x7FFFFFFF; | ||
261 | } | ||
262 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | ||
263 | } | ||
264 | |||
265 | int viafb_wait_engine_idle(void) | ||
266 | { | ||
267 | int loop = 0; | ||
268 | |||
269 | while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) & | ||
270 | VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)) | ||
271 | cpu_relax(); | ||
272 | |||
273 | while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) & | ||
274 | (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && | ||
275 | (loop++ < MAXLOOP)) | ||
276 | cpu_relax(); | ||
277 | |||
278 | return loop >= MAXLOOP; | ||
279 | } | ||
diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h new file mode 100644 index 000000000000..29bf854e8ccf --- /dev/null +++ b/drivers/video/via/accel.h | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __ACCEL_H__ | ||
23 | #define __ACCEL_H__ | ||
24 | |||
25 | #define FB_ACCEL_VIA_UNICHROME 50 | ||
26 | |||
27 | /* MMIO Base Address Definition */ | ||
28 | #define MMIO_VGABASE 0x8000 | ||
29 | #define MMIO_CR_READ (MMIO_VGABASE + 0x3D4) | ||
30 | #define MMIO_CR_WRITE (MMIO_VGABASE + 0x3D5) | ||
31 | #define MMIO_SR_READ (MMIO_VGABASE + 0x3C4) | ||
32 | #define MMIO_SR_WRITE (MMIO_VGABASE + 0x3C5) | ||
33 | |||
34 | /* HW Cursor Status Define */ | ||
35 | #define HW_Cursor_ON 0 | ||
36 | #define HW_Cursor_OFF 1 | ||
37 | |||
38 | #define CURSOR_SIZE (8 * 1024) | ||
39 | #define VQ_SIZE (256 * 1024) | ||
40 | |||
41 | #define VIA_MMIO_BLTBASE 0x200000 | ||
42 | #define VIA_MMIO_BLTSIZE 0x200000 | ||
43 | |||
44 | /* Defines for 2D registers */ | ||
45 | #define VIA_REG_GECMD 0x000 | ||
46 | #define VIA_REG_GEMODE 0x004 | ||
47 | #define VIA_REG_SRCPOS 0x008 | ||
48 | #define VIA_REG_DSTPOS 0x00C | ||
49 | /* width and height */ | ||
50 | #define VIA_REG_DIMENSION 0x010 | ||
51 | #define VIA_REG_PATADDR 0x014 | ||
52 | #define VIA_REG_FGCOLOR 0x018 | ||
53 | #define VIA_REG_BGCOLOR 0x01C | ||
54 | /* top and left of clipping */ | ||
55 | #define VIA_REG_CLIPTL 0x020 | ||
56 | /* bottom and right of clipping */ | ||
57 | #define VIA_REG_CLIPBR 0x024 | ||
58 | #define VIA_REG_OFFSET 0x028 | ||
59 | /* color key control */ | ||
60 | #define VIA_REG_KEYCONTROL 0x02C | ||
61 | #define VIA_REG_SRCBASE 0x030 | ||
62 | #define VIA_REG_DSTBASE 0x034 | ||
63 | /* pitch of src and dst */ | ||
64 | #define VIA_REG_PITCH 0x038 | ||
65 | #define VIA_REG_MONOPAT0 0x03C | ||
66 | #define VIA_REG_MONOPAT1 0x040 | ||
67 | /* from 0x100 to 0x1ff */ | ||
68 | #define VIA_REG_COLORPAT 0x100 | ||
69 | |||
70 | /* VIA_REG_PITCH(0x38): Pitch Setting */ | ||
71 | #define VIA_PITCH_ENABLE 0x80000000 | ||
72 | |||
73 | /* defines for VIA HW cursor registers */ | ||
74 | #define VIA_REG_CURSOR_MODE 0x2D0 | ||
75 | #define VIA_REG_CURSOR_POS 0x2D4 | ||
76 | #define VIA_REG_CURSOR_ORG 0x2D8 | ||
77 | #define VIA_REG_CURSOR_BG 0x2DC | ||
78 | #define VIA_REG_CURSOR_FG 0x2E0 | ||
79 | |||
80 | /* VIA_REG_GEMODE(0x04): GE mode */ | ||
81 | #define VIA_GEM_8bpp 0x00000000 | ||
82 | #define VIA_GEM_16bpp 0x00000100 | ||
83 | #define VIA_GEM_32bpp 0x00000300 | ||
84 | |||
85 | /* VIA_REG_GECMD(0x00): 2D Engine Command */ | ||
86 | #define VIA_GEC_NOOP 0x00000000 | ||
87 | #define VIA_GEC_BLT 0x00000001 | ||
88 | #define VIA_GEC_LINE 0x00000005 | ||
89 | |||
90 | /* Rotate Command */ | ||
91 | #define VIA_GEC_ROT 0x00000008 | ||
92 | |||
93 | #define VIA_GEC_SRC_XY 0x00000000 | ||
94 | #define VIA_GEC_SRC_LINEAR 0x00000010 | ||
95 | #define VIA_GEC_DST_XY 0x00000000 | ||
96 | #define VIA_GEC_DST_LINRAT 0x00000020 | ||
97 | |||
98 | #define VIA_GEC_SRC_FB 0x00000000 | ||
99 | #define VIA_GEC_SRC_SYS 0x00000040 | ||
100 | #define VIA_GEC_DST_FB 0x00000000 | ||
101 | #define VIA_GEC_DST_SYS 0x00000080 | ||
102 | |||
103 | /* source is mono */ | ||
104 | #define VIA_GEC_SRC_MONO 0x00000100 | ||
105 | /* pattern is mono */ | ||
106 | #define VIA_GEC_PAT_MONO 0x00000200 | ||
107 | /* mono src is opaque */ | ||
108 | #define VIA_GEC_MSRC_OPAQUE 0x00000000 | ||
109 | /* mono src is transparent */ | ||
110 | #define VIA_GEC_MSRC_TRANS 0x00000400 | ||
111 | /* pattern is in frame buffer */ | ||
112 | #define VIA_GEC_PAT_FB 0x00000000 | ||
113 | /* pattern is from reg setting */ | ||
114 | #define VIA_GEC_PAT_REG 0x00000800 | ||
115 | |||
116 | #define VIA_GEC_CLIP_DISABLE 0x00000000 | ||
117 | #define VIA_GEC_CLIP_ENABLE 0x00001000 | ||
118 | |||
119 | #define VIA_GEC_FIXCOLOR_PAT 0x00002000 | ||
120 | |||
121 | #define VIA_GEC_INCX 0x00000000 | ||
122 | #define VIA_GEC_DECY 0x00004000 | ||
123 | #define VIA_GEC_INCY 0x00000000 | ||
124 | #define VIA_GEC_DECX 0x00008000 | ||
125 | /* mono pattern is opaque */ | ||
126 | #define VIA_GEC_MPAT_OPAQUE 0x00000000 | ||
127 | /* mono pattern is transparent */ | ||
128 | #define VIA_GEC_MPAT_TRANS 0x00010000 | ||
129 | |||
130 | #define VIA_GEC_MONO_UNPACK 0x00000000 | ||
131 | #define VIA_GEC_MONO_PACK 0x00020000 | ||
132 | #define VIA_GEC_MONO_DWORD 0x00000000 | ||
133 | #define VIA_GEC_MONO_WORD 0x00040000 | ||
134 | #define VIA_GEC_MONO_BYTE 0x00080000 | ||
135 | |||
136 | #define VIA_GEC_LASTPIXEL_ON 0x00000000 | ||
137 | #define VIA_GEC_LASTPIXEL_OFF 0x00100000 | ||
138 | #define VIA_GEC_X_MAJOR 0x00000000 | ||
139 | #define VIA_GEC_Y_MAJOR 0x00200000 | ||
140 | #define VIA_GEC_QUICK_START 0x00800000 | ||
141 | |||
142 | /* defines for VIA 3D registers */ | ||
143 | #define VIA_REG_STATUS 0x400 | ||
144 | #define VIA_REG_CR_TRANSET 0x41C | ||
145 | #define VIA_REG_CR_TRANSPACE 0x420 | ||
146 | #define VIA_REG_TRANSET 0x43C | ||
147 | #define VIA_REG_TRANSPACE 0x440 | ||
148 | |||
149 | /* VIA_REG_STATUS(0x400): Engine Status */ | ||
150 | |||
151 | /* Command Regulator is busy */ | ||
152 | #define VIA_CMD_RGTR_BUSY 0x00000080 | ||
153 | /* 2D Engine is busy */ | ||
154 | #define VIA_2D_ENG_BUSY 0x00000002 | ||
155 | /* 3D Engine is busy */ | ||
156 | #define VIA_3D_ENG_BUSY 0x00000001 | ||
157 | /* Virtual Queue is busy */ | ||
158 | #define VIA_VR_QUEUE_BUSY 0x00020000 | ||
159 | |||
160 | #define MAXLOOP 0xFFFFFF | ||
161 | |||
162 | void viafb_init_accel(void); | ||
163 | void viafb_init_2d_engine(void); | ||
164 | void set_2d_color_depth(int); | ||
165 | void viafb_hw_cursor_init(void); | ||
166 | void viafb_show_hw_cursor(struct fb_info *info, int Status); int | ||
167 | viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp); | ||
168 | |||
169 | #endif /* __ACCEL_H__ */ | ||
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h new file mode 100644 index 000000000000..dde95edc387a --- /dev/null +++ b/drivers/video/via/chip.h | |||
@@ -0,0 +1,190 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #ifndef __CHIP_H__ | ||
22 | #define __CHIP_H__ | ||
23 | |||
24 | #include "global.h" | ||
25 | |||
26 | /***************************************/ | ||
27 | /* Definition Graphic Chip Information */ | ||
28 | /***************************************/ | ||
29 | |||
30 | #define PCI_VIA_VENDOR_ID 0x1106 | ||
31 | |||
32 | /* Define VIA Graphic Chip Name */ | ||
33 | #define UNICHROME_CLE266 1 | ||
34 | #define UNICHROME_CLE266_DID 0x3122 | ||
35 | #define CLE266_REVISION_AX 0x0A | ||
36 | #define CLE266_REVISION_CX 0x0C | ||
37 | |||
38 | #define UNICHROME_K400 2 | ||
39 | #define UNICHROME_K400_DID 0x7205 | ||
40 | |||
41 | #define UNICHROME_K800 3 | ||
42 | #define UNICHROME_K800_DID 0x3108 | ||
43 | |||
44 | #define UNICHROME_PM800 4 | ||
45 | #define UNICHROME_PM800_DID 0x3118 | ||
46 | |||
47 | #define UNICHROME_CN700 5 | ||
48 | #define UNICHROME_CN700_DID 0x3344 | ||
49 | |||
50 | #define UNICHROME_CX700 6 | ||
51 | #define UNICHROME_CX700_DID 0x3157 | ||
52 | #define CX700_REVISION_700 0x0 | ||
53 | #define CX700_REVISION_700M 0x1 | ||
54 | #define CX700_REVISION_700M2 0x2 | ||
55 | |||
56 | #define UNICHROME_CN750 7 | ||
57 | #define UNICHROME_CN750_DID 0x3225 | ||
58 | |||
59 | #define UNICHROME_K8M890 8 | ||
60 | #define UNICHROME_K8M890_DID 0x3230 | ||
61 | |||
62 | #define UNICHROME_P4M890 9 | ||
63 | #define UNICHROME_P4M890_DID 0x3343 | ||
64 | |||
65 | #define UNICHROME_P4M900 10 | ||
66 | #define UNICHROME_P4M900_DID 0x3371 | ||
67 | |||
68 | #define UNICHROME_VX800 11 | ||
69 | #define UNICHROME_VX800_DID 0x1122 | ||
70 | |||
71 | /**************************************************/ | ||
72 | /* Definition TMDS Trasmitter Information */ | ||
73 | /**************************************************/ | ||
74 | |||
75 | /* Definition TMDS Trasmitter Index */ | ||
76 | #define NON_TMDS_TRANSMITTER 0x00 | ||
77 | #define VT1632_TMDS 0x01 | ||
78 | #define INTEGRATED_TMDS 0x42 | ||
79 | |||
80 | /* Definition TMDS Trasmitter I2C Slave Address */ | ||
81 | #define VT1632_TMDS_I2C_ADDR 0x10 | ||
82 | |||
83 | /**************************************************/ | ||
84 | /* Definition LVDS Trasmitter Information */ | ||
85 | /**************************************************/ | ||
86 | |||
87 | /* Definition LVDS Trasmitter Index */ | ||
88 | #define NON_LVDS_TRANSMITTER 0x00 | ||
89 | #define VT1631_LVDS 0x01 | ||
90 | #define VT1636_LVDS 0x0E | ||
91 | #define INTEGRATED_LVDS 0x41 | ||
92 | |||
93 | /* Definition Digital Transmitter Mode */ | ||
94 | #define TX_DATA_12_BITS 0x01 | ||
95 | #define TX_DATA_24_BITS 0x02 | ||
96 | #define TX_DATA_DDR_MODE 0x04 | ||
97 | #define TX_DATA_SDR_MODE 0x08 | ||
98 | |||
99 | /* Definition LVDS Trasmitter I2C Slave Address */ | ||
100 | #define VT1631_LVDS_I2C_ADDR 0x70 | ||
101 | #define VT3271_LVDS_I2C_ADDR 0x80 | ||
102 | #define VT1636_LVDS_I2C_ADDR 0x80 | ||
103 | |||
104 | struct tmds_chip_information { | ||
105 | int tmds_chip_name; | ||
106 | int tmds_chip_slave_addr; | ||
107 | int dvi_panel_id; | ||
108 | int data_mode; | ||
109 | int output_interface; | ||
110 | int i2c_port; | ||
111 | int device_type; | ||
112 | }; | ||
113 | |||
114 | struct lvds_chip_information { | ||
115 | int lvds_chip_name; | ||
116 | int lvds_chip_slave_addr; | ||
117 | int data_mode; | ||
118 | int output_interface; | ||
119 | int i2c_port; | ||
120 | }; | ||
121 | |||
122 | struct chip_information { | ||
123 | int gfx_chip_name; | ||
124 | int gfx_chip_revision; | ||
125 | int chip_on_slot; | ||
126 | struct tmds_chip_information tmds_chip_info; | ||
127 | struct lvds_chip_information lvds_chip_info; | ||
128 | struct lvds_chip_information lvds_chip_info2; | ||
129 | }; | ||
130 | |||
131 | struct crt_setting_information { | ||
132 | int iga_path; | ||
133 | int h_active; | ||
134 | int v_active; | ||
135 | int bpp; | ||
136 | int refresh_rate; | ||
137 | }; | ||
138 | |||
139 | struct tmds_setting_information { | ||
140 | int iga_path; | ||
141 | int h_active; | ||
142 | int v_active; | ||
143 | int bpp; | ||
144 | int refresh_rate; | ||
145 | int get_dvi_size_method; | ||
146 | int max_pixel_clock; | ||
147 | int dvi_panel_size; | ||
148 | int dvi_panel_hres; | ||
149 | int dvi_panel_vres; | ||
150 | int native_size; | ||
151 | }; | ||
152 | |||
153 | struct lvds_setting_information { | ||
154 | int iga_path; | ||
155 | int h_active; | ||
156 | int v_active; | ||
157 | int bpp; | ||
158 | int refresh_rate; | ||
159 | int get_lcd_size_method; | ||
160 | int lcd_panel_id; | ||
161 | int lcd_panel_size; | ||
162 | int lcd_panel_hres; | ||
163 | int lcd_panel_vres; | ||
164 | int display_method; | ||
165 | int device_lcd_dualedge; | ||
166 | int LCDDithering; | ||
167 | int lcd_mode; | ||
168 | u32 vclk; /*panel mode clock value */ | ||
169 | }; | ||
170 | |||
171 | struct GFX_DPA_SETTING { | ||
172 | int ClkRangeIndex; | ||
173 | u8 DVP0; /* CR96[3:0] */ | ||
174 | u8 DVP0DataDri_S1; /* SR2A[5] */ | ||
175 | u8 DVP0DataDri_S; /* SR1B[1] */ | ||
176 | u8 DVP0ClockDri_S1; /* SR2A[4] */ | ||
177 | u8 DVP0ClockDri_S; /* SR1E[2] */ | ||
178 | u8 DVP1; /* CR9B[3:0] */ | ||
179 | u8 DVP1Driving; /* SR65[3:0], Data and Clock driving */ | ||
180 | u8 DFPHigh; /* CR97[3:0] */ | ||
181 | u8 DFPLow; /* CR99[3:0] */ | ||
182 | |||
183 | }; | ||
184 | |||
185 | struct VT1636_DPA_SETTING { | ||
186 | int PanelSizeID; | ||
187 | u8 CLK_SEL_ST1; | ||
188 | u8 CLK_SEL_ST2; | ||
189 | }; | ||
190 | #endif /* __CHIP_H__ */ | ||
diff --git a/drivers/video/via/debug.h b/drivers/video/via/debug.h new file mode 100644 index 000000000000..86eacc2017f3 --- /dev/null +++ b/drivers/video/via/debug.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #ifndef __DEBUG_H__ | ||
22 | #define __DEBUG_H__ | ||
23 | |||
24 | #ifndef VIAFB_DEBUG | ||
25 | #define VIAFB_DEBUG 0 | ||
26 | #endif | ||
27 | |||
28 | #if VIAFB_DEBUG | ||
29 | #define DEBUG_MSG(f, a...) printk(f, ## a) | ||
30 | #else | ||
31 | #define DEBUG_MSG(f, a...) | ||
32 | #endif | ||
33 | |||
34 | #define VIAFB_WARN 0 | ||
35 | #if VIAFB_WARN | ||
36 | #define WARN_MSG(f, a...) printk(f, ## a) | ||
37 | #else | ||
38 | #define WARN_MSG(f, a...) | ||
39 | #endif | ||
40 | |||
41 | #endif /* __DEBUG_H__ */ | ||
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c new file mode 100644 index 000000000000..d6965447ca69 --- /dev/null +++ b/drivers/video/via/dvi.c | |||
@@ -0,0 +1,682 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #include "global.h" | ||
22 | |||
23 | static void tmds_register_write(int index, u8 data); | ||
24 | static int tmds_register_read(int index); | ||
25 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); | ||
26 | static int check_reduce_blanking_mode(int mode_index, | ||
27 | int refresh_rate); | ||
28 | static int dvi_get_panel_size_from_DDCv1(void); | ||
29 | static int dvi_get_panel_size_from_DDCv2(void); | ||
30 | static unsigned char dvi_get_panel_info(void); | ||
31 | static int viafb_dvi_query_EDID(void); | ||
32 | |||
33 | static int check_tmds_chip(int device_id_subaddr, int device_id) | ||
34 | { | ||
35 | if (tmds_register_read(device_id_subaddr) == device_id) | ||
36 | return OK; | ||
37 | else | ||
38 | return FAIL; | ||
39 | } | ||
40 | |||
41 | void viafb_init_dvi_size(void) | ||
42 | { | ||
43 | DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); | ||
44 | DEBUG_MSG(KERN_INFO | ||
45 | "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n", | ||
46 | viaparinfo->tmds_setting_info->get_dvi_size_method); | ||
47 | |||
48 | switch (viaparinfo->tmds_setting_info->get_dvi_size_method) { | ||
49 | case GET_DVI_SIZE_BY_SYSTEM_BIOS: | ||
50 | break; | ||
51 | case GET_DVI_SZIE_BY_HW_STRAPPING: | ||
52 | break; | ||
53 | case GET_DVI_SIZE_BY_VGA_BIOS: | ||
54 | default: | ||
55 | dvi_get_panel_info(); | ||
56 | break; | ||
57 | } | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | int viafb_tmds_trasmitter_identify(void) | ||
62 | { | ||
63 | unsigned char sr2a = 0, sr1e = 0, sr3e = 0; | ||
64 | |||
65 | /* Turn on ouputting pad */ | ||
66 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
67 | case UNICHROME_K8M890: | ||
68 | /*=* DFP Low Pad on *=*/ | ||
69 | sr2a = viafb_read_reg(VIASR, SR2A); | ||
70 | viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); | ||
71 | break; | ||
72 | |||
73 | case UNICHROME_P4M900: | ||
74 | case UNICHROME_P4M890: | ||
75 | /* DFP Low Pad on */ | ||
76 | sr2a = viafb_read_reg(VIASR, SR2A); | ||
77 | viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); | ||
78 | /* DVP0 Pad on */ | ||
79 | sr1e = viafb_read_reg(VIASR, SR1E); | ||
80 | viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7); | ||
81 | break; | ||
82 | |||
83 | default: | ||
84 | /* DVP0/DVP1 Pad on */ | ||
85 | sr1e = viafb_read_reg(VIASR, SR1E); | ||
86 | viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 + | ||
87 | BIT5 + BIT6 + BIT7); | ||
88 | /* SR3E[1]Multi-function selection: | ||
89 | 0 = Emulate I2C and DDC bus by GPIO2/3/4. */ | ||
90 | sr3e = viafb_read_reg(VIASR, SR3E); | ||
91 | viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5); | ||
92 | break; | ||
93 | } | ||
94 | |||
95 | /* Check for VT1632: */ | ||
96 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; | ||
97 | viaparinfo->chip_info-> | ||
98 | tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; | ||
99 | viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX; | ||
100 | if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { | ||
101 | /* | ||
102 | * Currently only support 12bits,dual edge,add 24bits mode later | ||
103 | */ | ||
104 | tmds_register_write(0x08, 0x3b); | ||
105 | |||
106 | DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); | ||
107 | DEBUG_MSG(KERN_INFO "\n %2d", | ||
108 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); | ||
109 | DEBUG_MSG(KERN_INFO "\n %2d", | ||
110 | viaparinfo->chip_info->tmds_chip_info.i2c_port); | ||
111 | return OK; | ||
112 | } else { | ||
113 | viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX; | ||
114 | if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) | ||
115 | != FAIL) { | ||
116 | tmds_register_write(0x08, 0x3b); | ||
117 | DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); | ||
118 | DEBUG_MSG(KERN_INFO "\n %2d", | ||
119 | viaparinfo->chip_info-> | ||
120 | tmds_chip_info.tmds_chip_name); | ||
121 | DEBUG_MSG(KERN_INFO "\n %2d", | ||
122 | viaparinfo->chip_info-> | ||
123 | tmds_chip_info.i2c_port); | ||
124 | return OK; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS; | ||
129 | |||
130 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) && | ||
131 | ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) || | ||
132 | (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) { | ||
133 | DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n"); | ||
134 | return OK; | ||
135 | } | ||
136 | |||
137 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
138 | case UNICHROME_K8M890: | ||
139 | viafb_write_reg(SR2A, VIASR, sr2a); | ||
140 | break; | ||
141 | |||
142 | case UNICHROME_P4M900: | ||
143 | case UNICHROME_P4M890: | ||
144 | viafb_write_reg(SR2A, VIASR, sr2a); | ||
145 | viafb_write_reg(SR1E, VIASR, sr1e); | ||
146 | break; | ||
147 | |||
148 | default: | ||
149 | viafb_write_reg(SR1E, VIASR, sr1e); | ||
150 | viafb_write_reg(SR3E, VIASR, sr3e); | ||
151 | break; | ||
152 | } | ||
153 | |||
154 | viaparinfo->chip_info-> | ||
155 | tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER; | ||
156 | viaparinfo->chip_info->tmds_chip_info. | ||
157 | tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; | ||
158 | return FAIL; | ||
159 | } | ||
160 | |||
161 | static void tmds_register_write(int index, u8 data) | ||
162 | { | ||
163 | viaparinfo->i2c_stuff.i2c_port = | ||
164 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | ||
165 | |||
166 | viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info. | ||
167 | tmds_chip_slave_addr, index, | ||
168 | data); | ||
169 | } | ||
170 | |||
171 | static int tmds_register_read(int index) | ||
172 | { | ||
173 | u8 data; | ||
174 | |||
175 | viaparinfo->i2c_stuff.i2c_port = | ||
176 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | ||
177 | viafb_i2c_readbyte((u8) viaparinfo->chip_info-> | ||
178 | tmds_chip_info.tmds_chip_slave_addr, | ||
179 | (u8) index, &data); | ||
180 | return data; | ||
181 | } | ||
182 | |||
183 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) | ||
184 | { | ||
185 | viaparinfo->i2c_stuff.i2c_port = | ||
186 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | ||
187 | viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info. | ||
188 | tmds_chip_slave_addr, (u8) index, buff, buff_len); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int check_reduce_blanking_mode(int mode_index, | ||
193 | int refresh_rate) | ||
194 | { | ||
195 | if (refresh_rate != 60) | ||
196 | return false; | ||
197 | |||
198 | switch (mode_index) { | ||
199 | /* Following modes have reduce blanking mode. */ | ||
200 | case VIA_RES_1360X768: | ||
201 | case VIA_RES_1400X1050: | ||
202 | case VIA_RES_1440X900: | ||
203 | case VIA_RES_1600X900: | ||
204 | case VIA_RES_1680X1050: | ||
205 | case VIA_RES_1920X1080: | ||
206 | case VIA_RES_1920X1200: | ||
207 | break; | ||
208 | |||
209 | default: | ||
210 | DEBUG_MSG(KERN_INFO | ||
211 | "This dvi mode %d have no reduce blanking mode!\n", | ||
212 | mode_index); | ||
213 | return false; | ||
214 | } | ||
215 | |||
216 | return true; | ||
217 | } | ||
218 | |||
219 | /* DVI Set Mode */ | ||
220 | void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga) | ||
221 | { | ||
222 | struct VideoModeTable *videoMode = NULL; | ||
223 | struct crt_mode_table *pDviTiming; | ||
224 | unsigned long desirePixelClock, maxPixelClock; | ||
225 | int status = 0; | ||
226 | videoMode = viafb_get_modetbl_pointer(video_index); | ||
227 | pDviTiming = videoMode->crtc; | ||
228 | desirePixelClock = pDviTiming->clk / 1000000; | ||
229 | maxPixelClock = (unsigned long)viaparinfo-> | ||
230 | tmds_setting_info->max_pixel_clock; | ||
231 | |||
232 | DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n"); | ||
233 | |||
234 | if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) { | ||
235 | /*Check if reduce-blanking mode is exist */ | ||
236 | status = | ||
237 | check_reduce_blanking_mode(video_index, | ||
238 | pDviTiming->refresh_rate); | ||
239 | if (status) { | ||
240 | video_index += 100; /*Use reduce-blanking mode */ | ||
241 | videoMode = viafb_get_modetbl_pointer(video_index); | ||
242 | pDviTiming = videoMode->crtc; | ||
243 | DEBUG_MSG(KERN_INFO | ||
244 | "DVI use reduce blanking mode %d!!\n", | ||
245 | video_index); | ||
246 | } | ||
247 | } | ||
248 | viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga); | ||
249 | viafb_set_output_path(DEVICE_DVI, set_iga, | ||
250 | viaparinfo->chip_info->tmds_chip_info.output_interface); | ||
251 | } | ||
252 | |||
253 | /* Sense DVI Connector */ | ||
254 | int viafb_dvi_sense(void) | ||
255 | { | ||
256 | u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0, | ||
257 | RegCR93 = 0, RegCR9B = 0, data; | ||
258 | int ret = false; | ||
259 | |||
260 | DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n"); | ||
261 | |||
262 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | ||
263 | /* DI1 Pad on */ | ||
264 | RegSR1E = viafb_read_reg(VIASR, SR1E); | ||
265 | viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30); | ||
266 | |||
267 | /* CR6B[0]VCK Input Selection: 1 = External clock. */ | ||
268 | RegCR6B = viafb_read_reg(VIACR, CR6B); | ||
269 | viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08); | ||
270 | |||
271 | /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off | ||
272 | [0] Software Control Power Sequence */ | ||
273 | RegCR91 = viafb_read_reg(VIACR, CR91); | ||
274 | viafb_write_reg(CR91, VIACR, 0x1D); | ||
275 | |||
276 | /* CR93[7] DI1 Data Source Selection: 1 = DSP2. | ||
277 | CR93[5] DI1 Clock Source: 1 = internal. | ||
278 | CR93[4] DI1 Clock Polarity. | ||
279 | CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */ | ||
280 | RegCR93 = viafb_read_reg(VIACR, CR93); | ||
281 | viafb_write_reg(CR93, VIACR, 0x01); | ||
282 | } else { | ||
283 | /* DVP0/DVP1 Pad on */ | ||
284 | RegSR1E = viafb_read_reg(VIASR, SR1E); | ||
285 | viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0); | ||
286 | |||
287 | /* SR3E[1]Multi-function selection: | ||
288 | 0 = Emulate I2C and DDC bus by GPIO2/3/4. */ | ||
289 | RegSR3E = viafb_read_reg(VIASR, SR3E); | ||
290 | viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20)); | ||
291 | |||
292 | /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off | ||
293 | [0] Software Control Power Sequence */ | ||
294 | RegCR91 = viafb_read_reg(VIACR, CR91); | ||
295 | viafb_write_reg(CR91, VIACR, 0x1D); | ||
296 | |||
297 | /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary | ||
298 | display.CR9B[2:0] DVP1 Clock Adjust */ | ||
299 | RegCR9B = viafb_read_reg(VIACR, CR9B); | ||
300 | viafb_write_reg(CR9B, VIACR, 0x01); | ||
301 | } | ||
302 | |||
303 | data = (u8) tmds_register_read(0x09); | ||
304 | if (data & 0x04) | ||
305 | ret = true; | ||
306 | |||
307 | if (ret == false) { | ||
308 | if (viafb_dvi_query_EDID()) | ||
309 | ret = true; | ||
310 | } | ||
311 | |||
312 | /* Restore status */ | ||
313 | viafb_write_reg(SR1E, VIASR, RegSR1E); | ||
314 | viafb_write_reg(CR91, VIACR, RegCR91); | ||
315 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | ||
316 | viafb_write_reg(CR6B, VIACR, RegCR6B); | ||
317 | viafb_write_reg(CR93, VIACR, RegCR93); | ||
318 | } else { | ||
319 | viafb_write_reg(SR3E, VIASR, RegSR3E); | ||
320 | viafb_write_reg(CR9B, VIACR, RegCR9B); | ||
321 | } | ||
322 | |||
323 | return ret; | ||
324 | } | ||
325 | |||
326 | /* Query Flat Panel's EDID Table Version Through DVI Connector */ | ||
327 | static int viafb_dvi_query_EDID(void) | ||
328 | { | ||
329 | u8 data0, data1; | ||
330 | int restore; | ||
331 | |||
332 | DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n"); | ||
333 | |||
334 | restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; | ||
335 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0; | ||
336 | |||
337 | data0 = (u8) tmds_register_read(0x00); | ||
338 | data1 = (u8) tmds_register_read(0x01); | ||
339 | if ((data0 == 0) && (data1 == 0xFF)) { | ||
340 | viaparinfo->chip_info-> | ||
341 | tmds_chip_info.tmds_chip_slave_addr = restore; | ||
342 | return EDID_VERSION_1; /* Found EDID1 Table */ | ||
343 | } | ||
344 | |||
345 | data0 = (u8) tmds_register_read(0x00); | ||
346 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; | ||
347 | if (data0 == 0x20) | ||
348 | return EDID_VERSION_2; /* Found EDID2 Table */ | ||
349 | else | ||
350 | return false; | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | * | ||
355 | * int dvi_get_panel_size_from_DDCv1(void) | ||
356 | * | ||
357 | * - Get Panel Size Using EDID1 Table | ||
358 | * | ||
359 | * Return Type: int | ||
360 | * | ||
361 | */ | ||
362 | static int dvi_get_panel_size_from_DDCv1(void) | ||
363 | { | ||
364 | int i, max_h = 0, max_v = 0, tmp, restore; | ||
365 | unsigned char rData; | ||
366 | unsigned char EDID_DATA[18]; | ||
367 | |||
368 | DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n"); | ||
369 | |||
370 | restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; | ||
371 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0; | ||
372 | |||
373 | rData = tmds_register_read(0x23); | ||
374 | if (rData & 0x3C) | ||
375 | max_h = 640; | ||
376 | if (rData & 0xC0) | ||
377 | max_h = 720; | ||
378 | if (rData & 0x03) | ||
379 | max_h = 800; | ||
380 | |||
381 | rData = tmds_register_read(0x24); | ||
382 | if (rData & 0xC0) | ||
383 | max_h = 800; | ||
384 | if (rData & 0x1E) | ||
385 | max_h = 1024; | ||
386 | if (rData & 0x01) | ||
387 | max_h = 1280; | ||
388 | |||
389 | for (i = 0x25; i < 0x6D; i++) { | ||
390 | switch (i) { | ||
391 | case 0x26: | ||
392 | case 0x28: | ||
393 | case 0x2A: | ||
394 | case 0x2C: | ||
395 | case 0x2E: | ||
396 | case 0x30: | ||
397 | case 0x32: | ||
398 | case 0x34: | ||
399 | rData = tmds_register_read(i); | ||
400 | if (rData == 1) | ||
401 | break; | ||
402 | /* data = (data + 31) * 8 */ | ||
403 | tmp = (rData + 31) << 3; | ||
404 | if (tmp > max_h) | ||
405 | max_h = tmp; | ||
406 | break; | ||
407 | |||
408 | case 0x36: | ||
409 | case 0x48: | ||
410 | case 0x5A: | ||
411 | case 0x6C: | ||
412 | tmds_register_read_bytes(i, EDID_DATA, 10); | ||
413 | if (!(EDID_DATA[0] || EDID_DATA[1])) { | ||
414 | /* The first two byte must be zero. */ | ||
415 | if (EDID_DATA[3] == 0xFD) { | ||
416 | /* To get max pixel clock. */ | ||
417 | viaparinfo->tmds_setting_info-> | ||
418 | max_pixel_clock = EDID_DATA[9] * 10; | ||
419 | } | ||
420 | } | ||
421 | break; | ||
422 | |||
423 | default: | ||
424 | break; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | switch (max_h) { | ||
429 | case 640: | ||
430 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
431 | VIA_RES_640X480; | ||
432 | break; | ||
433 | case 800: | ||
434 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
435 | VIA_RES_800X600; | ||
436 | break; | ||
437 | case 1024: | ||
438 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
439 | VIA_RES_1024X768; | ||
440 | break; | ||
441 | case 1280: | ||
442 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
443 | VIA_RES_1280X1024; | ||
444 | break; | ||
445 | case 1400: | ||
446 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
447 | VIA_RES_1400X1050; | ||
448 | break; | ||
449 | case 1440: | ||
450 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
451 | VIA_RES_1440X1050; | ||
452 | break; | ||
453 | case 1600: | ||
454 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
455 | VIA_RES_1600X1200; | ||
456 | break; | ||
457 | case 1920: | ||
458 | if (max_v == 1200) { | ||
459 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
460 | VIA_RES_1920X1200; | ||
461 | } else { | ||
462 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
463 | VIA_RES_1920X1080; | ||
464 | } | ||
465 | |||
466 | break; | ||
467 | default: | ||
468 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
469 | VIA_RES_1024X768; | ||
470 | DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\ | ||
471 | set default panel size.\n", max_h); | ||
472 | break; | ||
473 | } | ||
474 | |||
475 | DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n", | ||
476 | viaparinfo->tmds_setting_info->max_pixel_clock); | ||
477 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; | ||
478 | return viaparinfo->tmds_setting_info->dvi_panel_size; | ||
479 | } | ||
480 | |||
481 | /* | ||
482 | * | ||
483 | * int dvi_get_panel_size_from_DDCv2(void) | ||
484 | * | ||
485 | * - Get Panel Size Using EDID2 Table | ||
486 | * | ||
487 | * Return Type: int | ||
488 | * | ||
489 | */ | ||
490 | static int dvi_get_panel_size_from_DDCv2(void) | ||
491 | { | ||
492 | int HSize = 0, restore; | ||
493 | unsigned char R_Buffer[2]; | ||
494 | |||
495 | DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n"); | ||
496 | |||
497 | restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; | ||
498 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2; | ||
499 | |||
500 | /* Horizontal: 0x76, 0x77 */ | ||
501 | tmds_register_read_bytes(0x76, R_Buffer, 2); | ||
502 | HSize = R_Buffer[0]; | ||
503 | HSize += R_Buffer[1] << 8; | ||
504 | |||
505 | switch (HSize) { | ||
506 | case 640: | ||
507 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
508 | VIA_RES_640X480; | ||
509 | break; | ||
510 | case 800: | ||
511 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
512 | VIA_RES_800X600; | ||
513 | break; | ||
514 | case 1024: | ||
515 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
516 | VIA_RES_1024X768; | ||
517 | break; | ||
518 | case 1280: | ||
519 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
520 | VIA_RES_1280X1024; | ||
521 | break; | ||
522 | case 1400: | ||
523 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
524 | VIA_RES_1400X1050; | ||
525 | break; | ||
526 | case 1440: | ||
527 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
528 | VIA_RES_1440X1050; | ||
529 | break; | ||
530 | case 1600: | ||
531 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
532 | VIA_RES_1600X1200; | ||
533 | break; | ||
534 | default: | ||
535 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
536 | VIA_RES_1024X768; | ||
537 | DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\ | ||
538 | set default panel size.\n", HSize); | ||
539 | break; | ||
540 | } | ||
541 | |||
542 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; | ||
543 | return viaparinfo->tmds_setting_info->dvi_panel_size; | ||
544 | } | ||
545 | |||
546 | /* | ||
547 | * | ||
548 | * unsigned char dvi_get_panel_info(void) | ||
549 | * | ||
550 | * - Get Panel Size | ||
551 | * | ||
552 | * Return Type: unsigned char | ||
553 | */ | ||
554 | static unsigned char dvi_get_panel_info(void) | ||
555 | { | ||
556 | unsigned char dvipanelsize; | ||
557 | DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n"); | ||
558 | |||
559 | viafb_dvi_sense(); | ||
560 | switch (viafb_dvi_query_EDID()) { | ||
561 | case 1: | ||
562 | dvi_get_panel_size_from_DDCv1(); | ||
563 | break; | ||
564 | case 2: | ||
565 | dvi_get_panel_size_from_DDCv2(); | ||
566 | break; | ||
567 | default: | ||
568 | break; | ||
569 | } | ||
570 | |||
571 | DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n", | ||
572 | viaparinfo->tmds_setting_info->dvi_panel_size); | ||
573 | dvipanelsize = (unsigned char)(viaparinfo-> | ||
574 | tmds_setting_info->dvi_panel_size); | ||
575 | return dvipanelsize; | ||
576 | } | ||
577 | |||
578 | /* If Disable DVI, turn off pad */ | ||
579 | void viafb_dvi_disable(void) | ||
580 | { | ||
581 | if (viaparinfo->chip_info-> | ||
582 | tmds_chip_info.output_interface == INTERFACE_DVP0) | ||
583 | viafb_write_reg(SR1E, VIASR, | ||
584 | viafb_read_reg(VIASR, SR1E) & (~0xC0)); | ||
585 | |||
586 | if (viaparinfo->chip_info-> | ||
587 | tmds_chip_info.output_interface == INTERFACE_DVP1) | ||
588 | viafb_write_reg(SR1E, VIASR, | ||
589 | viafb_read_reg(VIASR, SR1E) & (~0x30)); | ||
590 | |||
591 | if (viaparinfo->chip_info-> | ||
592 | tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) | ||
593 | viafb_write_reg(SR2A, VIASR, | ||
594 | viafb_read_reg(VIASR, SR2A) & (~0x0C)); | ||
595 | |||
596 | if (viaparinfo->chip_info-> | ||
597 | tmds_chip_info.output_interface == INTERFACE_DFP_LOW) | ||
598 | viafb_write_reg(SR2A, VIASR, | ||
599 | viafb_read_reg(VIASR, SR2A) & (~0x03)); | ||
600 | |||
601 | if (viaparinfo->chip_info-> | ||
602 | tmds_chip_info.output_interface == INTERFACE_TMDS) | ||
603 | /* Turn off TMDS power. */ | ||
604 | viafb_write_reg(CRD2, VIACR, | ||
605 | viafb_read_reg(VIACR, CRD2) | 0x08); | ||
606 | } | ||
607 | |||
608 | /* If Enable DVI, turn off pad */ | ||
609 | void viafb_dvi_enable(void) | ||
610 | { | ||
611 | u8 data; | ||
612 | |||
613 | if (viaparinfo->chip_info-> | ||
614 | tmds_chip_info.output_interface == INTERFACE_DVP0) { | ||
615 | viafb_write_reg(SR1E, VIASR, | ||
616 | viafb_read_reg(VIASR, SR1E) | 0xC0); | ||
617 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
618 | tmds_register_write(0x88, 0x3b); | ||
619 | else | ||
620 | /*clear CR91[5] to direct on display period | ||
621 | in the secondary diplay path */ | ||
622 | viafb_write_reg(CR91, VIACR, | ||
623 | viafb_read_reg(VIACR, CR91) & 0xDF); | ||
624 | } | ||
625 | |||
626 | if (viaparinfo->chip_info-> | ||
627 | tmds_chip_info.output_interface == INTERFACE_DVP1) { | ||
628 | viafb_write_reg(SR1E, VIASR, | ||
629 | viafb_read_reg(VIASR, SR1E) | 0x30); | ||
630 | |||
631 | /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */ | ||
632 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | ||
633 | tmds_register_write(0x88, 0x3b); | ||
634 | } else { | ||
635 | /*clear CR91[5] to direct on display period | ||
636 | in the secondary diplay path */ | ||
637 | viafb_write_reg(CR91, VIACR, | ||
638 | viafb_read_reg(VIACR, CR91) & 0xDF); | ||
639 | } | ||
640 | |||
641 | /*fix DVI cannot enable on EPIA-M board */ | ||
642 | if (viafb_platform_epia_dvi == 1) { | ||
643 | viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f); | ||
644 | viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0); | ||
645 | if (viafb_bus_width == 24) { | ||
646 | if (viafb_device_lcd_dualedge == 1) | ||
647 | data = 0x3F; | ||
648 | else | ||
649 | data = 0x37; | ||
650 | viafb_i2c_writebyte(viaparinfo->chip_info-> | ||
651 | tmds_chip_info. | ||
652 | tmds_chip_slave_addr, | ||
653 | 0x08, data); | ||
654 | } | ||
655 | } | ||
656 | } | ||
657 | |||
658 | if (viaparinfo->chip_info-> | ||
659 | tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) { | ||
660 | viafb_write_reg(SR2A, VIASR, | ||
661 | viafb_read_reg(VIASR, SR2A) | 0x0C); | ||
662 | viafb_write_reg(CR91, VIACR, | ||
663 | viafb_read_reg(VIACR, CR91) & 0xDF); | ||
664 | } | ||
665 | |||
666 | if (viaparinfo->chip_info-> | ||
667 | tmds_chip_info.output_interface == INTERFACE_DFP_LOW) { | ||
668 | viafb_write_reg(SR2A, VIASR, | ||
669 | viafb_read_reg(VIASR, SR2A) | 0x03); | ||
670 | viafb_write_reg(CR91, VIACR, | ||
671 | viafb_read_reg(VIACR, CR91) & 0xDF); | ||
672 | } | ||
673 | if (viaparinfo->chip_info-> | ||
674 | tmds_chip_info.output_interface == INTERFACE_TMDS) { | ||
675 | /* Turn on Display period in the panel path. */ | ||
676 | viafb_write_reg_mask(CR91, VIACR, 0, BIT7); | ||
677 | |||
678 | /* Turn on TMDS power. */ | ||
679 | viafb_write_reg_mask(CRD2, VIACR, 0, BIT3); | ||
680 | } | ||
681 | } | ||
682 | |||
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h new file mode 100644 index 000000000000..e1ec37fb0dc3 --- /dev/null +++ b/drivers/video/via/dvi.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __DVI_H__ | ||
23 | #define __DVI_H__ | ||
24 | |||
25 | /*Definition TMDS Device ID register*/ | ||
26 | #define VT1632_DEVICE_ID_REG 0x02 | ||
27 | #define VT1632_DEVICE_ID 0x92 | ||
28 | |||
29 | #define GET_DVI_SIZE_BY_SYSTEM_BIOS 0x01 | ||
30 | #define GET_DVI_SIZE_BY_VGA_BIOS 0x02 | ||
31 | #define GET_DVI_SZIE_BY_HW_STRAPPING 0x03 | ||
32 | |||
33 | /* Definition DVI Panel ID*/ | ||
34 | /* Resolution: 640x480, Channel: single, Dithering: Enable */ | ||
35 | #define DVI_PANEL_ID0_640X480 0x00 | ||
36 | /* Resolution: 800x600, Channel: single, Dithering: Enable */ | ||
37 | #define DVI_PANEL_ID1_800x600 0x01 | ||
38 | /* Resolution: 1024x768, Channel: single, Dithering: Enable */ | ||
39 | #define DVI_PANEL_ID1_1024x768 0x02 | ||
40 | /* Resolution: 1280x768, Channel: single, Dithering: Enable */ | ||
41 | #define DVI_PANEL_ID1_1280x768 0x03 | ||
42 | /* Resolution: 1280x1024, Channel: dual, Dithering: Enable */ | ||
43 | #define DVI_PANEL_ID1_1280x1024 0x04 | ||
44 | /* Resolution: 1400x1050, Channel: dual, Dithering: Enable */ | ||
45 | #define DVI_PANEL_ID1_1400x1050 0x05 | ||
46 | /* Resolution: 1600x1200, Channel: dual, Dithering: Enable */ | ||
47 | #define DVI_PANEL_ID1_1600x1200 0x06 | ||
48 | |||
49 | /* Define the version of EDID*/ | ||
50 | #define EDID_VERSION_1 1 | ||
51 | #define EDID_VERSION_2 2 | ||
52 | |||
53 | #define DEV_CONNECT_DVI 0x01 | ||
54 | #define DEV_CONNECT_HDMI 0x02 | ||
55 | |||
56 | struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index); | ||
57 | int viafb_dvi_sense(void); | ||
58 | void viafb_dvi_disable(void); | ||
59 | void viafb_dvi_enable(void); | ||
60 | int viafb_tmds_trasmitter_identify(void); | ||
61 | void viafb_init_dvi_size(void); | ||
62 | void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga); | ||
63 | |||
64 | #endif /* __DVI_H__ */ | ||
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c new file mode 100644 index 000000000000..468be2425af3 --- /dev/null +++ b/drivers/video/via/global.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #include "global.h" | ||
22 | int viafb_platform_epia_dvi = STATE_OFF; | ||
23 | int viafb_device_lcd_dualedge = STATE_OFF; | ||
24 | int viafb_bus_width = 12; | ||
25 | int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI; | ||
26 | int viafb_memsize; | ||
27 | int viafb_DeviceStatus = CRT_Device; | ||
28 | int viafb_hotplug; | ||
29 | int viafb_refresh = 60; | ||
30 | int viafb_refresh1 = 60; | ||
31 | int viafb_lcd_dsp_method = LCD_EXPANDSION; | ||
32 | int viafb_lcd_mode = LCD_OPENLDI; | ||
33 | int viafb_bpp = 32; | ||
34 | int viafb_bpp1 = 32; | ||
35 | int viafb_accel = 1; | ||
36 | int viafb_CRT_ON = 1; | ||
37 | int viafb_DVI_ON; | ||
38 | int viafb_LCD_ON ; | ||
39 | int viafb_LCD2_ON; | ||
40 | int viafb_SAMM_ON; | ||
41 | int viafb_dual_fb; | ||
42 | int viafb_hotplug_Xres = 640; | ||
43 | int viafb_hotplug_Yres = 480; | ||
44 | int viafb_hotplug_bpp = 32; | ||
45 | int viafb_hotplug_refresh = 60; | ||
46 | unsigned int viafb_second_offset; | ||
47 | int viafb_second_size; | ||
48 | int viafb_primary_dev = None_Device; | ||
49 | void __iomem *viafb_FB_MM; | ||
50 | unsigned int viafb_second_xres = 640; | ||
51 | unsigned int viafb_second_yres = 480; | ||
52 | unsigned int viafb_second_virtual_xres; | ||
53 | unsigned int viafb_second_virtual_yres; | ||
54 | int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; | ||
55 | struct fb_cursor viacursor; | ||
56 | struct fb_info *viafbinfo; | ||
57 | struct fb_info *viafbinfo1; | ||
58 | struct viafb_par *viaparinfo; | ||
59 | struct viafb_par *viaparinfo1; | ||
60 | |||
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h new file mode 100644 index 000000000000..8e5263c5b812 --- /dev/null +++ b/drivers/video/via/global.h | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __GLOBAL_H__ | ||
23 | #define __GLOBAL_H__ | ||
24 | |||
25 | #include <linux/fb.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/uaccess.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/proc_fs.h> | ||
33 | #include <linux/console.h> | ||
34 | #include <linux/timer.h> | ||
35 | |||
36 | #include "debug.h" | ||
37 | |||
38 | #include "iface.h" | ||
39 | #include "viafbdev.h" | ||
40 | #include "chip.h" | ||
41 | #include "debug.h" | ||
42 | #include "accel.h" | ||
43 | #include "share.h" | ||
44 | #include "dvi.h" | ||
45 | #include "viamode.h" | ||
46 | #include "via_i2c.h" | ||
47 | #include "hw.h" | ||
48 | |||
49 | #include "lcd.h" | ||
50 | #include "ioctl.h" | ||
51 | #include "viamode.h" | ||
52 | #include "via_utility.h" | ||
53 | #include "vt1636.h" | ||
54 | #include "tblDPASetting.h" | ||
55 | #include "tbl1636.h" | ||
56 | #include "viafbdev.h" | ||
57 | |||
58 | /* External struct*/ | ||
59 | |||
60 | extern int viafb_platform_epia_dvi; | ||
61 | extern int viafb_device_lcd_dualedge; | ||
62 | extern int viafb_bus_width; | ||
63 | extern int viafb_display_hardware_layout; | ||
64 | extern struct offset offset_reg; | ||
65 | extern struct viafb_par *viaparinfo; | ||
66 | extern struct viafb_par *viaparinfo1; | ||
67 | extern struct fb_info *viafbinfo; | ||
68 | extern struct fb_info *viafbinfo1; | ||
69 | extern int viafb_DeviceStatus; | ||
70 | extern int viafb_refresh; | ||
71 | extern int viafb_refresh1; | ||
72 | extern int viafb_lcd_dsp_method; | ||
73 | extern int viafb_lcd_mode; | ||
74 | extern int viafb_bpp; | ||
75 | extern int viafb_bpp1; | ||
76 | |||
77 | extern int viafb_CRT_ON; | ||
78 | extern int viafb_hotplug_Xres; | ||
79 | extern int viafb_hotplug_Yres; | ||
80 | extern int viafb_hotplug_bpp; | ||
81 | extern int viafb_hotplug_refresh; | ||
82 | extern int viafb_primary_dev; | ||
83 | extern void __iomem *viafb_FB_MM; | ||
84 | extern struct fb_cursor viacursor; | ||
85 | |||
86 | extern unsigned int viafb_second_xres; | ||
87 | extern unsigned int viafb_second_yres; | ||
88 | extern int viafb_lcd_panel_id; | ||
89 | |||
90 | #endif /* __GLOBAL_H__ */ | ||
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c new file mode 100644 index 000000000000..fcd53ceb88fa --- /dev/null +++ b/drivers/video/via/hw.c | |||
@@ -0,0 +1,2865 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | |||
24 | static const struct pci_device_id_info pciidlist[] = { | ||
25 | {PCI_VIA_VENDOR_ID, UNICHROME_CLE266_DID, UNICHROME_CLE266}, | ||
26 | {PCI_VIA_VENDOR_ID, UNICHROME_PM800_DID, UNICHROME_PM800}, | ||
27 | {PCI_VIA_VENDOR_ID, UNICHROME_K400_DID, UNICHROME_K400}, | ||
28 | {PCI_VIA_VENDOR_ID, UNICHROME_K800_DID, UNICHROME_K800}, | ||
29 | {PCI_VIA_VENDOR_ID, UNICHROME_CN700_DID, UNICHROME_CN700}, | ||
30 | {PCI_VIA_VENDOR_ID, UNICHROME_P4M890_DID, UNICHROME_P4M890}, | ||
31 | {PCI_VIA_VENDOR_ID, UNICHROME_K8M890_DID, UNICHROME_K8M890}, | ||
32 | {PCI_VIA_VENDOR_ID, UNICHROME_CX700_DID, UNICHROME_CX700}, | ||
33 | {PCI_VIA_VENDOR_ID, UNICHROME_P4M900_DID, UNICHROME_P4M900}, | ||
34 | {PCI_VIA_VENDOR_ID, UNICHROME_CN750_DID, UNICHROME_CN750}, | ||
35 | {PCI_VIA_VENDOR_ID, UNICHROME_VX800_DID, UNICHROME_VX800}, | ||
36 | {0, 0, 0} | ||
37 | }; | ||
38 | |||
39 | struct offset offset_reg = { | ||
40 | /* IGA1 Offset Register */ | ||
41 | {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } }, | ||
42 | /* IGA2 Offset Register */ | ||
43 | {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } } | ||
44 | }; | ||
45 | |||
46 | static struct pll_map pll_value[] = { | ||
47 | {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M}, | ||
48 | {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M}, | ||
49 | {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M}, | ||
50 | {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M}, | ||
51 | {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M}, | ||
52 | {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M}, | ||
53 | {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M}, | ||
54 | {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M}, | ||
55 | {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M}, | ||
56 | {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M}, | ||
57 | {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M}, | ||
58 | {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, CX700_45_250M}, | ||
59 | {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, CX700_46_000M}, | ||
60 | {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, CX700_46_996M}, | ||
61 | {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, CX700_48_000M}, | ||
62 | {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M}, | ||
63 | {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M}, | ||
64 | {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M}, | ||
65 | {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, CX700_52_977M}, | ||
66 | {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M}, | ||
67 | {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, CX700_60_466M}, | ||
68 | {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, CX700_61_500M}, | ||
69 | {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M}, | ||
70 | {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, CX700_65_178M}, | ||
71 | {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, CX700_66_750M}, | ||
72 | {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M}, | ||
73 | {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, CX700_69_924M}, | ||
74 | {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, CX700_70_159M}, | ||
75 | {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, CX700_72_000M}, | ||
76 | {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M}, | ||
77 | {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M}, | ||
78 | {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M}, | ||
79 | {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M}, | ||
80 | {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, CX700_84_750M}, | ||
81 | {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M}, | ||
82 | {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, CX700_88_750M}, | ||
83 | {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M}, | ||
84 | {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, CX700_97_750M}, | ||
85 | {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M, | ||
86 | CX700_101_000M}, | ||
87 | {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M, | ||
88 | CX700_106_500M}, | ||
89 | {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M, | ||
90 | CX700_108_000M}, | ||
91 | {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M, | ||
92 | CX700_113_309M}, | ||
93 | {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M, | ||
94 | CX700_118_840M}, | ||
95 | {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M, | ||
96 | CX700_119_000M}, | ||
97 | {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M, | ||
98 | CX700_121_750M}, | ||
99 | {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M, | ||
100 | CX700_125_104M}, | ||
101 | {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M, | ||
102 | CX700_133_308M}, | ||
103 | {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M, | ||
104 | CX700_135_000M}, | ||
105 | {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M, | ||
106 | CX700_136_700M}, | ||
107 | {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M, | ||
108 | CX700_138_400M}, | ||
109 | {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M, | ||
110 | CX700_146_760M}, | ||
111 | {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M, | ||
112 | CX700_153_920M}, | ||
113 | {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M, | ||
114 | CX700_156_000M}, | ||
115 | {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M, | ||
116 | CX700_157_500M}, | ||
117 | {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M, | ||
118 | CX700_162_000M}, | ||
119 | {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M, | ||
120 | CX700_187_000M}, | ||
121 | {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M, | ||
122 | CX700_193_295M}, | ||
123 | {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M, | ||
124 | CX700_202_500M}, | ||
125 | {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M, | ||
126 | CX700_204_000M}, | ||
127 | {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M, | ||
128 | CX700_218_500M}, | ||
129 | {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M, | ||
130 | CX700_234_000M}, | ||
131 | {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M, | ||
132 | CX700_267_250M}, | ||
133 | {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M, | ||
134 | CX700_297_500M}, | ||
135 | {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M}, | ||
136 | {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M, | ||
137 | CX700_172_798M}, | ||
138 | {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M, | ||
139 | CX700_122_614M}, | ||
140 | {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, CX700_74_270M}, | ||
141 | {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M, | ||
142 | CX700_148_500M} | ||
143 | }; | ||
144 | |||
145 | static struct fifo_depth_select display_fifo_depth_reg = { | ||
146 | /* IGA1 FIFO Depth_Select */ | ||
147 | {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } }, | ||
148 | /* IGA2 FIFO Depth_Select */ | ||
149 | {IGA2_FIFO_DEPTH_SELECT_REG_NUM, | ||
150 | {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } } | ||
151 | }; | ||
152 | |||
153 | static struct fifo_threshold_select fifo_threshold_select_reg = { | ||
154 | /* IGA1 FIFO Threshold Select */ | ||
155 | {IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } }, | ||
156 | /* IGA2 FIFO Threshold Select */ | ||
157 | {IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } } | ||
158 | }; | ||
159 | |||
160 | static struct fifo_high_threshold_select fifo_high_threshold_select_reg = { | ||
161 | /* IGA1 FIFO High Threshold Select */ | ||
162 | {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } }, | ||
163 | /* IGA2 FIFO High Threshold Select */ | ||
164 | {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } } | ||
165 | }; | ||
166 | |||
167 | static struct display_queue_expire_num display_queue_expire_num_reg = { | ||
168 | /* IGA1 Display Queue Expire Num */ | ||
169 | {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } }, | ||
170 | /* IGA2 Display Queue Expire Num */ | ||
171 | {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } } | ||
172 | }; | ||
173 | |||
174 | /* Definition Fetch Count Registers*/ | ||
175 | static struct fetch_count fetch_count_reg = { | ||
176 | /* IGA1 Fetch Count Register */ | ||
177 | {IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } }, | ||
178 | /* IGA2 Fetch Count Register */ | ||
179 | {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } } | ||
180 | }; | ||
181 | |||
182 | static struct iga1_crtc_timing iga1_crtc_reg = { | ||
183 | /* IGA1 Horizontal Total */ | ||
184 | {IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } }, | ||
185 | /* IGA1 Horizontal Addressable Video */ | ||
186 | {IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } }, | ||
187 | /* IGA1 Horizontal Blank Start */ | ||
188 | {IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } }, | ||
189 | /* IGA1 Horizontal Blank End */ | ||
190 | {IGA1_HOR_BLANK_END_REG_NUM, | ||
191 | {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } }, | ||
192 | /* IGA1 Horizontal Sync Start */ | ||
193 | {IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } }, | ||
194 | /* IGA1 Horizontal Sync End */ | ||
195 | {IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } }, | ||
196 | /* IGA1 Vertical Total */ | ||
197 | {IGA1_VER_TOTAL_REG_NUM, | ||
198 | {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } }, | ||
199 | /* IGA1 Vertical Addressable Video */ | ||
200 | {IGA1_VER_ADDR_REG_NUM, | ||
201 | {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } }, | ||
202 | /* IGA1 Vertical Blank Start */ | ||
203 | {IGA1_VER_BLANK_START_REG_NUM, | ||
204 | {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } }, | ||
205 | /* IGA1 Vertical Blank End */ | ||
206 | {IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } }, | ||
207 | /* IGA1 Vertical Sync Start */ | ||
208 | {IGA1_VER_SYNC_START_REG_NUM, | ||
209 | {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } }, | ||
210 | /* IGA1 Vertical Sync End */ | ||
211 | {IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } } | ||
212 | }; | ||
213 | |||
214 | static struct iga2_crtc_timing iga2_crtc_reg = { | ||
215 | /* IGA2 Horizontal Total */ | ||
216 | {IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } }, | ||
217 | /* IGA2 Horizontal Addressable Video */ | ||
218 | {IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } }, | ||
219 | /* IGA2 Horizontal Blank Start */ | ||
220 | {IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } }, | ||
221 | /* IGA2 Horizontal Blank End */ | ||
222 | {IGA2_HOR_BLANK_END_REG_NUM, | ||
223 | {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } }, | ||
224 | /* IGA2 Horizontal Sync Start */ | ||
225 | {IGA2_HOR_SYNC_START_REG_NUM, | ||
226 | {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } }, | ||
227 | /* IGA2 Horizontal Sync End */ | ||
228 | {IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } }, | ||
229 | /* IGA2 Vertical Total */ | ||
230 | {IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } }, | ||
231 | /* IGA2 Vertical Addressable Video */ | ||
232 | {IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } }, | ||
233 | /* IGA2 Vertical Blank Start */ | ||
234 | {IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } }, | ||
235 | /* IGA2 Vertical Blank End */ | ||
236 | {IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } }, | ||
237 | /* IGA2 Vertical Sync Start */ | ||
238 | {IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } }, | ||
239 | /* IGA2 Vertical Sync End */ | ||
240 | {IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } } | ||
241 | }; | ||
242 | |||
243 | static struct rgbLUT palLUT_table[] = { | ||
244 | /* {R,G,B} */ | ||
245 | /* Index 0x00~0x03 */ | ||
246 | {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00, | ||
247 | 0x2A, | ||
248 | 0x2A}, | ||
249 | /* Index 0x04~0x07 */ | ||
250 | {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A, | ||
251 | 0x2A, | ||
252 | 0x2A}, | ||
253 | /* Index 0x08~0x0B */ | ||
254 | {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15, | ||
255 | 0x3F, | ||
256 | 0x3F}, | ||
257 | /* Index 0x0C~0x0F */ | ||
258 | {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F, | ||
259 | 0x3F, | ||
260 | 0x3F}, | ||
261 | /* Index 0x10~0x13 */ | ||
262 | {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B, | ||
263 | 0x0B, | ||
264 | 0x0B}, | ||
265 | /* Index 0x14~0x17 */ | ||
266 | {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18, | ||
267 | 0x18, | ||
268 | 0x18}, | ||
269 | /* Index 0x18~0x1B */ | ||
270 | {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28, | ||
271 | 0x28, | ||
272 | 0x28}, | ||
273 | /* Index 0x1C~0x1F */ | ||
274 | {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F, | ||
275 | 0x3F, | ||
276 | 0x3F}, | ||
277 | /* Index 0x20~0x23 */ | ||
278 | {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F, | ||
279 | 0x00, | ||
280 | 0x3F}, | ||
281 | /* Index 0x24~0x27 */ | ||
282 | {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F, | ||
283 | 0x00, | ||
284 | 0x10}, | ||
285 | /* Index 0x28~0x2B */ | ||
286 | {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F, | ||
287 | 0x2F, | ||
288 | 0x00}, | ||
289 | /* Index 0x2C~0x2F */ | ||
290 | {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10, | ||
291 | 0x3F, | ||
292 | 0x00}, | ||
293 | /* Index 0x30~0x33 */ | ||
294 | {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00, | ||
295 | 0x3F, | ||
296 | 0x2F}, | ||
297 | /* Index 0x34~0x37 */ | ||
298 | {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00, | ||
299 | 0x10, | ||
300 | 0x3F}, | ||
301 | /* Index 0x38~0x3B */ | ||
302 | {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37, | ||
303 | 0x1F, | ||
304 | 0x3F}, | ||
305 | /* Index 0x3C~0x3F */ | ||
306 | {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F, | ||
307 | 0x1F, | ||
308 | 0x27}, | ||
309 | /* Index 0x40~0x43 */ | ||
310 | {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F, | ||
311 | 0x3F, | ||
312 | 0x1F}, | ||
313 | /* Index 0x44~0x47 */ | ||
314 | {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27, | ||
315 | 0x3F, | ||
316 | 0x1F}, | ||
317 | /* Index 0x48~0x4B */ | ||
318 | {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F, | ||
319 | 0x3F, | ||
320 | 0x37}, | ||
321 | /* Index 0x4C~0x4F */ | ||
322 | {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F, | ||
323 | 0x27, | ||
324 | 0x3F}, | ||
325 | /* Index 0x50~0x53 */ | ||
326 | {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A, | ||
327 | 0x2D, | ||
328 | 0x3F}, | ||
329 | /* Index 0x54~0x57 */ | ||
330 | {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F, | ||
331 | 0x2D, | ||
332 | 0x31}, | ||
333 | /* Index 0x58~0x5B */ | ||
334 | {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F, | ||
335 | 0x3A, | ||
336 | 0x2D}, | ||
337 | /* Index 0x5C~0x5F */ | ||
338 | {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31, | ||
339 | 0x3F, | ||
340 | 0x2D}, | ||
341 | /* Index 0x60~0x63 */ | ||
342 | {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D, | ||
343 | 0x3F, | ||
344 | 0x3A}, | ||
345 | /* Index 0x64~0x67 */ | ||
346 | {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D, | ||
347 | 0x31, | ||
348 | 0x3F}, | ||
349 | /* Index 0x68~0x6B */ | ||
350 | {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15, | ||
351 | 0x00, | ||
352 | 0x1C}, | ||
353 | /* Index 0x6C~0x6F */ | ||
354 | {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C, | ||
355 | 0x00, | ||
356 | 0x07}, | ||
357 | /* Index 0x70~0x73 */ | ||
358 | {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C, | ||
359 | 0x15, | ||
360 | 0x00}, | ||
361 | /* Index 0x74~0x77 */ | ||
362 | {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07, | ||
363 | 0x1C, | ||
364 | 0x00}, | ||
365 | /* Index 0x78~0x7B */ | ||
366 | {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00, | ||
367 | 0x1C, | ||
368 | 0x15}, | ||
369 | /* Index 0x7C~0x7F */ | ||
370 | {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00, | ||
371 | 0x07, | ||
372 | 0x1C}, | ||
373 | /* Index 0x80~0x83 */ | ||
374 | {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18, | ||
375 | 0x0E, | ||
376 | 0x1C}, | ||
377 | /* Index 0x84~0x87 */ | ||
378 | {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C, | ||
379 | 0x0E, | ||
380 | 0x11}, | ||
381 | /* Index 0x88~0x8B */ | ||
382 | {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C, | ||
383 | 0x18, | ||
384 | 0x0E}, | ||
385 | /* Index 0x8C~0x8F */ | ||
386 | {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11, | ||
387 | 0x1C, | ||
388 | 0x0E}, | ||
389 | /* Index 0x90~0x93 */ | ||
390 | {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E, | ||
391 | 0x1C, | ||
392 | 0x18}, | ||
393 | /* Index 0x94~0x97 */ | ||
394 | {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E, | ||
395 | 0x11, | ||
396 | 0x1C}, | ||
397 | /* Index 0x98~0x9B */ | ||
398 | {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A, | ||
399 | 0x14, | ||
400 | 0x1C}, | ||
401 | /* Index 0x9C~0x9F */ | ||
402 | {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C, | ||
403 | 0x14, | ||
404 | 0x16}, | ||
405 | /* Index 0xA0~0xA3 */ | ||
406 | {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C, | ||
407 | 0x1A, | ||
408 | 0x14}, | ||
409 | /* Index 0xA4~0xA7 */ | ||
410 | {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16, | ||
411 | 0x1C, | ||
412 | 0x14}, | ||
413 | /* Index 0xA8~0xAB */ | ||
414 | {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14, | ||
415 | 0x1C, | ||
416 | 0x1A}, | ||
417 | /* Index 0xAC~0xAF */ | ||
418 | {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14, | ||
419 | 0x16, | ||
420 | 0x1C}, | ||
421 | /* Index 0xB0~0xB3 */ | ||
422 | {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C, | ||
423 | 0x00, | ||
424 | 0x10}, | ||
425 | /* Index 0xB4~0xB7 */ | ||
426 | {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10, | ||
427 | 0x00, | ||
428 | 0x04}, | ||
429 | /* Index 0xB8~0xBB */ | ||
430 | {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10, | ||
431 | 0x0C, | ||
432 | 0x00}, | ||
433 | /* Index 0xBC~0xBF */ | ||
434 | {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04, | ||
435 | 0x10, | ||
436 | 0x00}, | ||
437 | /* Index 0xC0~0xC3 */ | ||
438 | {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00, | ||
439 | 0x10, | ||
440 | 0x0C}, | ||
441 | /* Index 0xC4~0xC7 */ | ||
442 | {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00, | ||
443 | 0x04, | ||
444 | 0x10}, | ||
445 | /* Index 0xC8~0xCB */ | ||
446 | {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E, | ||
447 | 0x08, | ||
448 | 0x10}, | ||
449 | /* Index 0xCC~0xCF */ | ||
450 | {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10, | ||
451 | 0x08, | ||
452 | 0x0A}, | ||
453 | /* Index 0xD0~0xD3 */ | ||
454 | {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10, | ||
455 | 0x0E, | ||
456 | 0x08}, | ||
457 | /* Index 0xD4~0xD7 */ | ||
458 | {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A, | ||
459 | 0x10, | ||
460 | 0x08}, | ||
461 | /* Index 0xD8~0xDB */ | ||
462 | {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08, | ||
463 | 0x10, | ||
464 | 0x0E}, | ||
465 | /* Index 0xDC~0xDF */ | ||
466 | {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08, | ||
467 | 0x0A, | ||
468 | 0x10}, | ||
469 | /* Index 0xE0~0xE3 */ | ||
470 | {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F, | ||
471 | 0x0B, | ||
472 | 0x10}, | ||
473 | /* Index 0xE4~0xE7 */ | ||
474 | {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10, | ||
475 | 0x0B, | ||
476 | 0x0C}, | ||
477 | /* Index 0xE8~0xEB */ | ||
478 | {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10, | ||
479 | 0x0F, | ||
480 | 0x0B}, | ||
481 | /* Index 0xEC~0xEF */ | ||
482 | {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C, | ||
483 | 0x10, | ||
484 | 0x0B}, | ||
485 | /* Index 0xF0~0xF3 */ | ||
486 | {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B, | ||
487 | 0x10, | ||
488 | 0x0F}, | ||
489 | /* Index 0xF4~0xF7 */ | ||
490 | {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B, | ||
491 | 0x0C, | ||
492 | 0x10}, | ||
493 | /* Index 0xF8~0xFB */ | ||
494 | {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, | ||
495 | 0x00, | ||
496 | 0x00}, | ||
497 | /* Index 0xFC~0xFF */ | ||
498 | {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, | ||
499 | 0x00, | ||
500 | 0x00} | ||
501 | }; | ||
502 | |||
503 | static void set_crt_output_path(int set_iga); | ||
504 | static void dvi_patch_skew_dvp0(void); | ||
505 | static void dvi_patch_skew_dvp1(void); | ||
506 | static void dvi_patch_skew_dvp_low(void); | ||
507 | static void set_dvi_output_path(int set_iga, int output_interface); | ||
508 | static void set_lcd_output_path(int set_iga, int output_interface); | ||
509 | static int search_mode_setting(int ModeInfoIndex); | ||
510 | static void load_fix_bit_crtc_reg(void); | ||
511 | static void init_gfx_chip_info(void); | ||
512 | static void init_tmds_chip_info(void); | ||
513 | static void init_lvds_chip_info(void); | ||
514 | static void device_screen_off(void); | ||
515 | static void device_screen_on(void); | ||
516 | static void set_display_channel(void); | ||
517 | static void device_off(void); | ||
518 | static void device_on(void); | ||
519 | static void enable_second_display_channel(void); | ||
520 | static void disable_second_display_channel(void); | ||
521 | static int get_fb_size_from_pci(void); | ||
522 | |||
523 | void viafb_write_reg(u8 index, u16 io_port, u8 data) | ||
524 | { | ||
525 | outb(index, io_port); | ||
526 | outb(data, io_port + 1); | ||
527 | /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, data); */ | ||
528 | } | ||
529 | u8 viafb_read_reg(int io_port, u8 index) | ||
530 | { | ||
531 | outb(index, io_port); | ||
532 | return inb(io_port + 1); | ||
533 | } | ||
534 | |||
535 | void viafb_lock_crt(void) | ||
536 | { | ||
537 | viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7); | ||
538 | } | ||
539 | |||
540 | void viafb_unlock_crt(void) | ||
541 | { | ||
542 | viafb_write_reg_mask(CR11, VIACR, 0, BIT7); | ||
543 | viafb_write_reg_mask(CR47, VIACR, 0, BIT0); | ||
544 | } | ||
545 | |||
546 | void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask) | ||
547 | { | ||
548 | u8 tmp; | ||
549 | |||
550 | outb(index, io_port); | ||
551 | tmp = inb(io_port + 1); | ||
552 | outb((data & mask) | (tmp & (~mask)), io_port + 1); | ||
553 | /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, tmp); */ | ||
554 | } | ||
555 | |||
556 | void write_dac_reg(u8 index, u8 r, u8 g, u8 b) | ||
557 | { | ||
558 | outb(index, LUT_INDEX_WRITE); | ||
559 | outb(r, LUT_DATA); | ||
560 | outb(g, LUT_DATA); | ||
561 | outb(b, LUT_DATA); | ||
562 | } | ||
563 | |||
564 | /*Set IGA path for each device*/ | ||
565 | void viafb_set_iga_path(void) | ||
566 | { | ||
567 | |||
568 | if (viafb_SAMM_ON == 1) { | ||
569 | if (viafb_CRT_ON) { | ||
570 | if (viafb_primary_dev == CRT_Device) | ||
571 | viaparinfo->crt_setting_info->iga_path = IGA1; | ||
572 | else | ||
573 | viaparinfo->crt_setting_info->iga_path = IGA2; | ||
574 | } | ||
575 | |||
576 | if (viafb_DVI_ON) { | ||
577 | if (viafb_primary_dev == DVI_Device) | ||
578 | viaparinfo->tmds_setting_info->iga_path = IGA1; | ||
579 | else | ||
580 | viaparinfo->tmds_setting_info->iga_path = IGA2; | ||
581 | } | ||
582 | |||
583 | if (viafb_LCD_ON) { | ||
584 | if (viafb_primary_dev == LCD_Device) { | ||
585 | if (viafb_dual_fb && | ||
586 | (viaparinfo->chip_info->gfx_chip_name == | ||
587 | UNICHROME_CLE266)) { | ||
588 | viaparinfo-> | ||
589 | lvds_setting_info->iga_path = IGA2; | ||
590 | viaparinfo-> | ||
591 | crt_setting_info->iga_path = IGA1; | ||
592 | viaparinfo-> | ||
593 | tmds_setting_info->iga_path = IGA1; | ||
594 | } else | ||
595 | viaparinfo-> | ||
596 | lvds_setting_info->iga_path = IGA1; | ||
597 | } else { | ||
598 | viaparinfo->lvds_setting_info->iga_path = IGA2; | ||
599 | } | ||
600 | } | ||
601 | if (viafb_LCD2_ON) { | ||
602 | if (LCD2_Device == viafb_primary_dev) | ||
603 | viaparinfo->lvds_setting_info2->iga_path = IGA1; | ||
604 | else | ||
605 | viaparinfo->lvds_setting_info2->iga_path = IGA2; | ||
606 | } | ||
607 | } else { | ||
608 | viafb_SAMM_ON = 0; | ||
609 | |||
610 | if (viafb_CRT_ON && viafb_LCD_ON) { | ||
611 | viaparinfo->crt_setting_info->iga_path = IGA1; | ||
612 | viaparinfo->lvds_setting_info->iga_path = IGA2; | ||
613 | } else if (viafb_CRT_ON && viafb_DVI_ON) { | ||
614 | viaparinfo->crt_setting_info->iga_path = IGA1; | ||
615 | viaparinfo->tmds_setting_info->iga_path = IGA2; | ||
616 | } else if (viafb_LCD_ON && viafb_DVI_ON) { | ||
617 | viaparinfo->tmds_setting_info->iga_path = IGA1; | ||
618 | viaparinfo->lvds_setting_info->iga_path = IGA2; | ||
619 | } else if (viafb_LCD_ON && viafb_LCD2_ON) { | ||
620 | viaparinfo->lvds_setting_info->iga_path = IGA2; | ||
621 | viaparinfo->lvds_setting_info2->iga_path = IGA2; | ||
622 | } else if (viafb_CRT_ON) { | ||
623 | viaparinfo->crt_setting_info->iga_path = IGA1; | ||
624 | } else if (viafb_LCD_ON) { | ||
625 | viaparinfo->lvds_setting_info->iga_path = IGA2; | ||
626 | } else if (viafb_DVI_ON) { | ||
627 | viaparinfo->tmds_setting_info->iga_path = IGA1; | ||
628 | } | ||
629 | } | ||
630 | } | ||
631 | |||
632 | void viafb_set_start_addr(void) | ||
633 | { | ||
634 | unsigned long offset = 0, tmp = 0, size = 0; | ||
635 | unsigned long length; | ||
636 | |||
637 | DEBUG_MSG(KERN_INFO "viafb_set_start_addr!\n"); | ||
638 | viafb_unlock_crt(); | ||
639 | /* update starting address of IGA1 */ | ||
640 | viafb_write_reg(CR0C, VIACR, 0x00); /*initial starting address */ | ||
641 | viafb_write_reg(CR0D, VIACR, 0x00); | ||
642 | viafb_write_reg(CR34, VIACR, 0x00); | ||
643 | viafb_write_reg_mask(CR48, VIACR, 0x00, 0x1F); | ||
644 | |||
645 | if (viafb_dual_fb) { | ||
646 | viaparinfo->iga_path = IGA1; | ||
647 | viaparinfo1->iga_path = IGA2; | ||
648 | } | ||
649 | |||
650 | if (viafb_SAMM_ON == 1) { | ||
651 | if (!viafb_dual_fb) { | ||
652 | if (viafb_second_size) | ||
653 | size = viafb_second_size * 1024 * 1024; | ||
654 | else | ||
655 | size = 8 * 1024 * 1024; | ||
656 | } else { | ||
657 | |||
658 | size = viaparinfo1->memsize; | ||
659 | } | ||
660 | offset = viafb_second_offset; | ||
661 | DEBUG_MSG(KERN_INFO | ||
662 | "viafb_second_size=%lx, second start_adddress=%lx\n", | ||
663 | size, offset); | ||
664 | } | ||
665 | if (viafb_SAMM_ON == 1) { | ||
666 | offset = offset >> 3; | ||
667 | |||
668 | tmp = viafb_read_reg(VIACR, 0x62) & 0x01; | ||
669 | tmp |= (offset & 0x7F) << 1; | ||
670 | viafb_write_reg(CR62, VIACR, tmp); | ||
671 | viafb_write_reg(CR63, VIACR, ((offset & 0x7F80) >> 7)); | ||
672 | viafb_write_reg(CR64, VIACR, ((offset & 0x7F8000) >> 15)); | ||
673 | viafb_write_reg(CRA3, VIACR, ((offset & 0x3800000) >> 23)); | ||
674 | } else { | ||
675 | /* update starting address */ | ||
676 | viafb_write_reg(CR62, VIACR, 0x00); | ||
677 | viafb_write_reg(CR63, VIACR, 0x00); | ||
678 | viafb_write_reg(CR64, VIACR, 0x00); | ||
679 | viafb_write_reg(CRA3, VIACR, 0x00); | ||
680 | } | ||
681 | |||
682 | if (viafb_SAMM_ON == 1) { | ||
683 | if (viafb_accel) { | ||
684 | if (!viafb_dual_fb) | ||
685 | length = size - viaparinfo->fbmem_used; | ||
686 | else | ||
687 | length = size - viaparinfo1->fbmem_used; | ||
688 | } else | ||
689 | length = size; | ||
690 | offset = (unsigned long)(void *)viafb_FB_MM + | ||
691 | viafb_second_offset; | ||
692 | memset((void *)offset, 0, length); | ||
693 | } | ||
694 | |||
695 | viafb_lock_crt(); | ||
696 | } | ||
697 | |||
698 | void viafb_set_output_path(int device, int set_iga, int output_interface) | ||
699 | { | ||
700 | switch (device) { | ||
701 | case DEVICE_CRT: | ||
702 | set_crt_output_path(set_iga); | ||
703 | break; | ||
704 | case DEVICE_DVI: | ||
705 | set_dvi_output_path(set_iga, output_interface); | ||
706 | break; | ||
707 | case DEVICE_LCD: | ||
708 | set_lcd_output_path(set_iga, output_interface); | ||
709 | break; | ||
710 | } | ||
711 | } | ||
712 | |||
713 | static void set_crt_output_path(int set_iga) | ||
714 | { | ||
715 | viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); | ||
716 | |||
717 | switch (set_iga) { | ||
718 | case IGA1: | ||
719 | viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6); | ||
720 | break; | ||
721 | case IGA2: | ||
722 | case IGA1_IGA2: | ||
723 | viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); | ||
724 | viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6); | ||
725 | if (set_iga == IGA1_IGA2) | ||
726 | viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3); | ||
727 | break; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | static void dvi_patch_skew_dvp0(void) | ||
732 | { | ||
733 | /* Reset data driving first: */ | ||
734 | viafb_write_reg_mask(SR1B, VIASR, 0, BIT1); | ||
735 | viafb_write_reg_mask(SR2A, VIASR, 0, BIT4); | ||
736 | |||
737 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
738 | case UNICHROME_P4M890: | ||
739 | { | ||
740 | if ((viaparinfo->tmds_setting_info->h_active == 1600) && | ||
741 | (viaparinfo->tmds_setting_info->v_active == | ||
742 | 1200)) | ||
743 | viafb_write_reg_mask(CR96, VIACR, 0x03, | ||
744 | BIT0 + BIT1 + BIT2); | ||
745 | else | ||
746 | viafb_write_reg_mask(CR96, VIACR, 0x07, | ||
747 | BIT0 + BIT1 + BIT2); | ||
748 | break; | ||
749 | } | ||
750 | |||
751 | case UNICHROME_P4M900: | ||
752 | { | ||
753 | viafb_write_reg_mask(CR96, VIACR, 0x07, | ||
754 | BIT0 + BIT1 + BIT2 + BIT3); | ||
755 | viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1); | ||
756 | viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4); | ||
757 | break; | ||
758 | } | ||
759 | |||
760 | default: | ||
761 | { | ||
762 | break; | ||
763 | } | ||
764 | } | ||
765 | } | ||
766 | |||
767 | static void dvi_patch_skew_dvp1(void) | ||
768 | { | ||
769 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
770 | case UNICHROME_CX700: | ||
771 | { | ||
772 | break; | ||
773 | } | ||
774 | |||
775 | default: | ||
776 | { | ||
777 | break; | ||
778 | } | ||
779 | } | ||
780 | } | ||
781 | |||
782 | static void dvi_patch_skew_dvp_low(void) | ||
783 | { | ||
784 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
785 | case UNICHROME_K8M890: | ||
786 | { | ||
787 | viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1); | ||
788 | break; | ||
789 | } | ||
790 | |||
791 | case UNICHROME_P4M900: | ||
792 | { | ||
793 | viafb_write_reg_mask(CR99, VIACR, 0x08, | ||
794 | BIT0 + BIT1 + BIT2 + BIT3); | ||
795 | break; | ||
796 | } | ||
797 | |||
798 | case UNICHROME_P4M890: | ||
799 | { | ||
800 | viafb_write_reg_mask(CR99, VIACR, 0x0F, | ||
801 | BIT0 + BIT1 + BIT2 + BIT3); | ||
802 | break; | ||
803 | } | ||
804 | |||
805 | default: | ||
806 | { | ||
807 | break; | ||
808 | } | ||
809 | } | ||
810 | } | ||
811 | |||
812 | static void set_dvi_output_path(int set_iga, int output_interface) | ||
813 | { | ||
814 | switch (output_interface) { | ||
815 | case INTERFACE_DVP0: | ||
816 | viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); | ||
817 | |||
818 | if (set_iga == IGA1) { | ||
819 | viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); | ||
820 | viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + | ||
821 | BIT5 + BIT7); | ||
822 | } else { | ||
823 | viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); | ||
824 | viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 + | ||
825 | BIT5 + BIT7); | ||
826 | } | ||
827 | |||
828 | viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6); | ||
829 | |||
830 | dvi_patch_skew_dvp0(); | ||
831 | break; | ||
832 | |||
833 | case INTERFACE_DVP1: | ||
834 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | ||
835 | if (set_iga == IGA1) | ||
836 | viafb_write_reg_mask(CR93, VIACR, 0x21, | ||
837 | BIT0 + BIT5 + BIT7); | ||
838 | else | ||
839 | viafb_write_reg_mask(CR93, VIACR, 0xA1, | ||
840 | BIT0 + BIT5 + BIT7); | ||
841 | } else { | ||
842 | if (set_iga == IGA1) | ||
843 | viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); | ||
844 | else | ||
845 | viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); | ||
846 | } | ||
847 | |||
848 | viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); | ||
849 | dvi_patch_skew_dvp1(); | ||
850 | break; | ||
851 | case INTERFACE_DFP_HIGH: | ||
852 | if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) { | ||
853 | if (set_iga == IGA1) { | ||
854 | viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); | ||
855 | viafb_write_reg_mask(CR97, VIACR, 0x03, | ||
856 | BIT0 + BIT1 + BIT4); | ||
857 | } else { | ||
858 | viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); | ||
859 | viafb_write_reg_mask(CR97, VIACR, 0x13, | ||
860 | BIT0 + BIT1 + BIT4); | ||
861 | } | ||
862 | } | ||
863 | viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3); | ||
864 | break; | ||
865 | |||
866 | case INTERFACE_DFP_LOW: | ||
867 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
868 | break; | ||
869 | |||
870 | if (set_iga == IGA1) { | ||
871 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | ||
872 | viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); | ||
873 | } else { | ||
874 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | ||
875 | viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); | ||
876 | } | ||
877 | |||
878 | viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); | ||
879 | dvi_patch_skew_dvp_low(); | ||
880 | break; | ||
881 | |||
882 | case INTERFACE_TMDS: | ||
883 | if (set_iga == IGA1) | ||
884 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | ||
885 | else | ||
886 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | ||
887 | break; | ||
888 | } | ||
889 | |||
890 | if (set_iga == IGA2) { | ||
891 | enable_second_display_channel(); | ||
892 | /* Disable LCD Scaling */ | ||
893 | viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); | ||
894 | } | ||
895 | } | ||
896 | |||
897 | static void set_lcd_output_path(int set_iga, int output_interface) | ||
898 | { | ||
899 | DEBUG_MSG(KERN_INFO | ||
900 | "set_lcd_output_path, iga:%d,out_interface:%d\n", | ||
901 | set_iga, output_interface); | ||
902 | switch (set_iga) { | ||
903 | case IGA1: | ||
904 | viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); | ||
905 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); | ||
906 | |||
907 | disable_second_display_channel(); | ||
908 | break; | ||
909 | |||
910 | case IGA2: | ||
911 | viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); | ||
912 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); | ||
913 | |||
914 | enable_second_display_channel(); | ||
915 | break; | ||
916 | |||
917 | case IGA1_IGA2: | ||
918 | viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3); | ||
919 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); | ||
920 | |||
921 | disable_second_display_channel(); | ||
922 | break; | ||
923 | } | ||
924 | |||
925 | switch (output_interface) { | ||
926 | case INTERFACE_DVP0: | ||
927 | if (set_iga == IGA1) { | ||
928 | viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); | ||
929 | } else { | ||
930 | viafb_write_reg(CR91, VIACR, 0x00); | ||
931 | viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); | ||
932 | } | ||
933 | break; | ||
934 | |||
935 | case INTERFACE_DVP1: | ||
936 | if (set_iga == IGA1) | ||
937 | viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); | ||
938 | else { | ||
939 | viafb_write_reg(CR91, VIACR, 0x00); | ||
940 | viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); | ||
941 | } | ||
942 | break; | ||
943 | |||
944 | case INTERFACE_DFP_HIGH: | ||
945 | if (set_iga == IGA1) | ||
946 | viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); | ||
947 | else { | ||
948 | viafb_write_reg(CR91, VIACR, 0x00); | ||
949 | viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); | ||
950 | viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); | ||
951 | } | ||
952 | break; | ||
953 | |||
954 | case INTERFACE_DFP_LOW: | ||
955 | if (set_iga == IGA1) | ||
956 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | ||
957 | else { | ||
958 | viafb_write_reg(CR91, VIACR, 0x00); | ||
959 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | ||
960 | viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); | ||
961 | } | ||
962 | |||
963 | break; | ||
964 | |||
965 | case INTERFACE_DFP: | ||
966 | if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name) | ||
967 | || (UNICHROME_P4M890 == | ||
968 | viaparinfo->chip_info->gfx_chip_name)) | ||
969 | viafb_write_reg_mask(CR97, VIACR, 0x84, | ||
970 | BIT7 + BIT2 + BIT1 + BIT0); | ||
971 | if (set_iga == IGA1) { | ||
972 | viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); | ||
973 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | ||
974 | } else { | ||
975 | viafb_write_reg(CR91, VIACR, 0x00); | ||
976 | viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); | ||
977 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | ||
978 | } | ||
979 | break; | ||
980 | |||
981 | case INTERFACE_LVDS0: | ||
982 | case INTERFACE_LVDS0LVDS1: | ||
983 | if (set_iga == IGA1) | ||
984 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | ||
985 | else | ||
986 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | ||
987 | |||
988 | break; | ||
989 | |||
990 | case INTERFACE_LVDS1: | ||
991 | if (set_iga == IGA1) | ||
992 | viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); | ||
993 | else | ||
994 | viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); | ||
995 | break; | ||
996 | } | ||
997 | } | ||
998 | |||
999 | /* Search Mode Index */ | ||
1000 | static int search_mode_setting(int ModeInfoIndex) | ||
1001 | { | ||
1002 | int i = 0; | ||
1003 | |||
1004 | while ((i < NUM_TOTAL_MODETABLE) && | ||
1005 | (ModeInfoIndex != CLE266Modes[i].ModeIndex)) | ||
1006 | i++; | ||
1007 | if (i >= NUM_TOTAL_MODETABLE) | ||
1008 | i = 0; | ||
1009 | return i; | ||
1010 | |||
1011 | } | ||
1012 | |||
1013 | struct VideoModeTable *viafb_get_modetbl_pointer(int Index) | ||
1014 | { | ||
1015 | struct VideoModeTable *TmpTbl = NULL; | ||
1016 | TmpTbl = &CLE266Modes[search_mode_setting(Index)]; | ||
1017 | return TmpTbl; | ||
1018 | } | ||
1019 | |||
1020 | struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index) | ||
1021 | { | ||
1022 | struct VideoModeTable *TmpTbl = NULL; | ||
1023 | int i = 0; | ||
1024 | while ((i < NUM_TOTAL_CEA_MODES) && | ||
1025 | (Index != CEA_HDMI_Modes[i].ModeIndex)) | ||
1026 | i++; | ||
1027 | if ((i < NUM_TOTAL_CEA_MODES)) | ||
1028 | TmpTbl = &CEA_HDMI_Modes[i]; | ||
1029 | else { | ||
1030 | /*Still use general timing if don't find CEA timing */ | ||
1031 | i = 0; | ||
1032 | while ((i < NUM_TOTAL_MODETABLE) && | ||
1033 | (Index != CLE266Modes[i].ModeIndex)) | ||
1034 | i++; | ||
1035 | if (i >= NUM_TOTAL_MODETABLE) | ||
1036 | i = 0; | ||
1037 | TmpTbl = &CLE266Modes[i]; | ||
1038 | } | ||
1039 | return TmpTbl; | ||
1040 | } | ||
1041 | |||
1042 | static void load_fix_bit_crtc_reg(void) | ||
1043 | { | ||
1044 | /* always set to 1 */ | ||
1045 | viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7); | ||
1046 | /* line compare should set all bits = 1 (extend modes) */ | ||
1047 | viafb_write_reg(CR18, VIACR, 0xff); | ||
1048 | /* line compare should set all bits = 1 (extend modes) */ | ||
1049 | viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4); | ||
1050 | /* line compare should set all bits = 1 (extend modes) */ | ||
1051 | viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6); | ||
1052 | /* line compare should set all bits = 1 (extend modes) */ | ||
1053 | viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4); | ||
1054 | /* line compare should set all bits = 1 (extend modes) */ | ||
1055 | viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2); | ||
1056 | /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */ | ||
1057 | /* extend mode always set to e3h */ | ||
1058 | viafb_write_reg(CR17, VIACR, 0xe3); | ||
1059 | /* extend mode always set to 0h */ | ||
1060 | viafb_write_reg(CR08, VIACR, 0x00); | ||
1061 | /* extend mode always set to 0h */ | ||
1062 | viafb_write_reg(CR14, VIACR, 0x00); | ||
1063 | |||
1064 | /* If K8M800, enable Prefetch Mode. */ | ||
1065 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) | ||
1066 | || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890)) | ||
1067 | viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3); | ||
1068 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
1069 | && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX)) | ||
1070 | viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1); | ||
1071 | |||
1072 | } | ||
1073 | |||
1074 | void viafb_load_reg(int timing_value, int viafb_load_reg_num, | ||
1075 | struct io_register *reg, | ||
1076 | int io_type) | ||
1077 | { | ||
1078 | int reg_mask; | ||
1079 | int bit_num = 0; | ||
1080 | int data; | ||
1081 | int i, j; | ||
1082 | int shift_next_reg; | ||
1083 | int start_index, end_index, cr_index; | ||
1084 | u16 get_bit; | ||
1085 | |||
1086 | for (i = 0; i < viafb_load_reg_num; i++) { | ||
1087 | reg_mask = 0; | ||
1088 | data = 0; | ||
1089 | start_index = reg[i].start_bit; | ||
1090 | end_index = reg[i].end_bit; | ||
1091 | cr_index = reg[i].io_addr; | ||
1092 | |||
1093 | shift_next_reg = bit_num; | ||
1094 | for (j = start_index; j <= end_index; j++) { | ||
1095 | /*if (bit_num==8) timing_value = timing_value >>8; */ | ||
1096 | reg_mask = reg_mask | (BIT0 << j); | ||
1097 | get_bit = (timing_value & (BIT0 << bit_num)); | ||
1098 | data = | ||
1099 | data | ((get_bit >> shift_next_reg) << start_index); | ||
1100 | bit_num++; | ||
1101 | } | ||
1102 | if (io_type == VIACR) | ||
1103 | viafb_write_reg_mask(cr_index, VIACR, data, reg_mask); | ||
1104 | else | ||
1105 | viafb_write_reg_mask(cr_index, VIASR, data, reg_mask); | ||
1106 | } | ||
1107 | |||
1108 | } | ||
1109 | |||
1110 | /* Write Registers */ | ||
1111 | void viafb_write_regx(struct io_reg RegTable[], int ItemNum) | ||
1112 | { | ||
1113 | int i; | ||
1114 | unsigned char RegTemp; | ||
1115 | |||
1116 | /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */ | ||
1117 | |||
1118 | for (i = 0; i < ItemNum; i++) { | ||
1119 | outb(RegTable[i].index, RegTable[i].port); | ||
1120 | RegTemp = inb(RegTable[i].port + 1); | ||
1121 | RegTemp = (RegTemp & (~RegTable[i].mask)) | RegTable[i].value; | ||
1122 | outb(RegTemp, RegTable[i].port + 1); | ||
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga) | ||
1127 | { | ||
1128 | int reg_value; | ||
1129 | int viafb_load_reg_num; | ||
1130 | struct io_register *reg; | ||
1131 | |||
1132 | switch (set_iga) { | ||
1133 | case IGA1_IGA2: | ||
1134 | case IGA1: | ||
1135 | reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte); | ||
1136 | viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num; | ||
1137 | reg = offset_reg.iga1_offset_reg.reg; | ||
1138 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1139 | if (set_iga == IGA1) | ||
1140 | break; | ||
1141 | case IGA2: | ||
1142 | reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte); | ||
1143 | viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num; | ||
1144 | reg = offset_reg.iga2_offset_reg.reg; | ||
1145 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1146 | break; | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) | ||
1151 | { | ||
1152 | int reg_value; | ||
1153 | int viafb_load_reg_num; | ||
1154 | struct io_register *reg = NULL; | ||
1155 | |||
1156 | switch (set_iga) { | ||
1157 | case IGA1_IGA2: | ||
1158 | case IGA1: | ||
1159 | reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte); | ||
1160 | viafb_load_reg_num = fetch_count_reg. | ||
1161 | iga1_fetch_count_reg.reg_num; | ||
1162 | reg = fetch_count_reg.iga1_fetch_count_reg.reg; | ||
1163 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR); | ||
1164 | if (set_iga == IGA1) | ||
1165 | break; | ||
1166 | case IGA2: | ||
1167 | reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte); | ||
1168 | viafb_load_reg_num = fetch_count_reg. | ||
1169 | iga2_fetch_count_reg.reg_num; | ||
1170 | reg = fetch_count_reg.iga2_fetch_count_reg.reg; | ||
1171 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1172 | break; | ||
1173 | } | ||
1174 | |||
1175 | } | ||
1176 | |||
1177 | void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) | ||
1178 | { | ||
1179 | int reg_value; | ||
1180 | int viafb_load_reg_num; | ||
1181 | struct io_register *reg = NULL; | ||
1182 | int iga1_fifo_max_depth = 0, iga1_fifo_threshold = | ||
1183 | 0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0; | ||
1184 | int iga2_fifo_max_depth = 0, iga2_fifo_threshold = | ||
1185 | 0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0; | ||
1186 | |||
1187 | if (set_iga == IGA1) { | ||
1188 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { | ||
1189 | iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH; | ||
1190 | iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD; | ||
1191 | iga1_fifo_high_threshold = | ||
1192 | K800_IGA1_FIFO_HIGH_THRESHOLD; | ||
1193 | /* If resolution > 1280x1024, expire length = 64, else | ||
1194 | expire length = 128 */ | ||
1195 | if ((hor_active > 1280) && (ver_active > 1024)) | ||
1196 | iga1_display_queue_expire_num = 16; | ||
1197 | else | ||
1198 | iga1_display_queue_expire_num = | ||
1199 | K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1200 | |||
1201 | } | ||
1202 | |||
1203 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) { | ||
1204 | iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH; | ||
1205 | iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD; | ||
1206 | iga1_fifo_high_threshold = | ||
1207 | P880_IGA1_FIFO_HIGH_THRESHOLD; | ||
1208 | iga1_display_queue_expire_num = | ||
1209 | P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1210 | |||
1211 | /* If resolution > 1280x1024, expire length = 64, else | ||
1212 | expire length = 128 */ | ||
1213 | if ((hor_active > 1280) && (ver_active > 1024)) | ||
1214 | iga1_display_queue_expire_num = 16; | ||
1215 | else | ||
1216 | iga1_display_queue_expire_num = | ||
1217 | P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1218 | } | ||
1219 | |||
1220 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) { | ||
1221 | iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH; | ||
1222 | iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD; | ||
1223 | iga1_fifo_high_threshold = | ||
1224 | CN700_IGA1_FIFO_HIGH_THRESHOLD; | ||
1225 | |||
1226 | /* If resolution > 1280x1024, expire length = 64, | ||
1227 | else expire length = 128 */ | ||
1228 | if ((hor_active > 1280) && (ver_active > 1024)) | ||
1229 | iga1_display_queue_expire_num = 16; | ||
1230 | else | ||
1231 | iga1_display_queue_expire_num = | ||
1232 | CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1233 | } | ||
1234 | |||
1235 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { | ||
1236 | iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH; | ||
1237 | iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD; | ||
1238 | iga1_fifo_high_threshold = | ||
1239 | CX700_IGA1_FIFO_HIGH_THRESHOLD; | ||
1240 | iga1_display_queue_expire_num = | ||
1241 | CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1242 | } | ||
1243 | |||
1244 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) { | ||
1245 | iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH; | ||
1246 | iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD; | ||
1247 | iga1_fifo_high_threshold = | ||
1248 | K8M890_IGA1_FIFO_HIGH_THRESHOLD; | ||
1249 | iga1_display_queue_expire_num = | ||
1250 | K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1251 | } | ||
1252 | |||
1253 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) { | ||
1254 | iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH; | ||
1255 | iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD; | ||
1256 | iga1_fifo_high_threshold = | ||
1257 | P4M890_IGA1_FIFO_HIGH_THRESHOLD; | ||
1258 | iga1_display_queue_expire_num = | ||
1259 | P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1260 | } | ||
1261 | |||
1262 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) { | ||
1263 | iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH; | ||
1264 | iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD; | ||
1265 | iga1_fifo_high_threshold = | ||
1266 | P4M900_IGA1_FIFO_HIGH_THRESHOLD; | ||
1267 | iga1_display_queue_expire_num = | ||
1268 | P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1269 | } | ||
1270 | |||
1271 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) { | ||
1272 | iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH; | ||
1273 | iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD; | ||
1274 | iga1_fifo_high_threshold = | ||
1275 | VX800_IGA1_FIFO_HIGH_THRESHOLD; | ||
1276 | iga1_display_queue_expire_num = | ||
1277 | VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1278 | } | ||
1279 | |||
1280 | /* Set Display FIFO Depath Select */ | ||
1281 | reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); | ||
1282 | viafb_load_reg_num = | ||
1283 | display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num; | ||
1284 | reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg; | ||
1285 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR); | ||
1286 | |||
1287 | /* Set Display FIFO Threshold Select */ | ||
1288 | reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold); | ||
1289 | viafb_load_reg_num = | ||
1290 | fifo_threshold_select_reg. | ||
1291 | iga1_fifo_threshold_select_reg.reg_num; | ||
1292 | reg = | ||
1293 | fifo_threshold_select_reg. | ||
1294 | iga1_fifo_threshold_select_reg.reg; | ||
1295 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR); | ||
1296 | |||
1297 | /* Set FIFO High Threshold Select */ | ||
1298 | reg_value = | ||
1299 | IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold); | ||
1300 | viafb_load_reg_num = | ||
1301 | fifo_high_threshold_select_reg. | ||
1302 | iga1_fifo_high_threshold_select_reg.reg_num; | ||
1303 | reg = | ||
1304 | fifo_high_threshold_select_reg. | ||
1305 | iga1_fifo_high_threshold_select_reg.reg; | ||
1306 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR); | ||
1307 | |||
1308 | /* Set Display Queue Expire Num */ | ||
1309 | reg_value = | ||
1310 | IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA | ||
1311 | (iga1_display_queue_expire_num); | ||
1312 | viafb_load_reg_num = | ||
1313 | display_queue_expire_num_reg. | ||
1314 | iga1_display_queue_expire_num_reg.reg_num; | ||
1315 | reg = | ||
1316 | display_queue_expire_num_reg. | ||
1317 | iga1_display_queue_expire_num_reg.reg; | ||
1318 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR); | ||
1319 | |||
1320 | } else { | ||
1321 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { | ||
1322 | iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH; | ||
1323 | iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD; | ||
1324 | iga2_fifo_high_threshold = | ||
1325 | K800_IGA2_FIFO_HIGH_THRESHOLD; | ||
1326 | |||
1327 | /* If resolution > 1280x1024, expire length = 64, | ||
1328 | else expire length = 128 */ | ||
1329 | if ((hor_active > 1280) && (ver_active > 1024)) | ||
1330 | iga2_display_queue_expire_num = 16; | ||
1331 | else | ||
1332 | iga2_display_queue_expire_num = | ||
1333 | K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1334 | } | ||
1335 | |||
1336 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) { | ||
1337 | iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH; | ||
1338 | iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD; | ||
1339 | iga2_fifo_high_threshold = | ||
1340 | P880_IGA2_FIFO_HIGH_THRESHOLD; | ||
1341 | |||
1342 | /* If resolution > 1280x1024, expire length = 64, | ||
1343 | else expire length = 128 */ | ||
1344 | if ((hor_active > 1280) && (ver_active > 1024)) | ||
1345 | iga2_display_queue_expire_num = 16; | ||
1346 | else | ||
1347 | iga2_display_queue_expire_num = | ||
1348 | P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1349 | } | ||
1350 | |||
1351 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) { | ||
1352 | iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH; | ||
1353 | iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD; | ||
1354 | iga2_fifo_high_threshold = | ||
1355 | CN700_IGA2_FIFO_HIGH_THRESHOLD; | ||
1356 | |||
1357 | /* If resolution > 1280x1024, expire length = 64, | ||
1358 | else expire length = 128 */ | ||
1359 | if ((hor_active > 1280) && (ver_active > 1024)) | ||
1360 | iga2_display_queue_expire_num = 16; | ||
1361 | else | ||
1362 | iga2_display_queue_expire_num = | ||
1363 | CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1364 | } | ||
1365 | |||
1366 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { | ||
1367 | iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH; | ||
1368 | iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD; | ||
1369 | iga2_fifo_high_threshold = | ||
1370 | CX700_IGA2_FIFO_HIGH_THRESHOLD; | ||
1371 | iga2_display_queue_expire_num = | ||
1372 | CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1373 | } | ||
1374 | |||
1375 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) { | ||
1376 | iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH; | ||
1377 | iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD; | ||
1378 | iga2_fifo_high_threshold = | ||
1379 | K8M890_IGA2_FIFO_HIGH_THRESHOLD; | ||
1380 | iga2_display_queue_expire_num = | ||
1381 | K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1382 | } | ||
1383 | |||
1384 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) { | ||
1385 | iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH; | ||
1386 | iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD; | ||
1387 | iga2_fifo_high_threshold = | ||
1388 | P4M890_IGA2_FIFO_HIGH_THRESHOLD; | ||
1389 | iga2_display_queue_expire_num = | ||
1390 | P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1391 | } | ||
1392 | |||
1393 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) { | ||
1394 | iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH; | ||
1395 | iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD; | ||
1396 | iga2_fifo_high_threshold = | ||
1397 | P4M900_IGA2_FIFO_HIGH_THRESHOLD; | ||
1398 | iga2_display_queue_expire_num = | ||
1399 | P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1400 | } | ||
1401 | |||
1402 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) { | ||
1403 | iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH; | ||
1404 | iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD; | ||
1405 | iga2_fifo_high_threshold = | ||
1406 | VX800_IGA2_FIFO_HIGH_THRESHOLD; | ||
1407 | iga2_display_queue_expire_num = | ||
1408 | VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1409 | } | ||
1410 | |||
1411 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { | ||
1412 | /* Set Display FIFO Depath Select */ | ||
1413 | reg_value = | ||
1414 | IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth) | ||
1415 | - 1; | ||
1416 | /* Patch LCD in IGA2 case */ | ||
1417 | viafb_load_reg_num = | ||
1418 | display_fifo_depth_reg. | ||
1419 | iga2_fifo_depth_select_reg.reg_num; | ||
1420 | reg = | ||
1421 | display_fifo_depth_reg. | ||
1422 | iga2_fifo_depth_select_reg.reg; | ||
1423 | viafb_load_reg(reg_value, | ||
1424 | viafb_load_reg_num, reg, VIACR); | ||
1425 | } else { | ||
1426 | |||
1427 | /* Set Display FIFO Depath Select */ | ||
1428 | reg_value = | ||
1429 | IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth); | ||
1430 | viafb_load_reg_num = | ||
1431 | display_fifo_depth_reg. | ||
1432 | iga2_fifo_depth_select_reg.reg_num; | ||
1433 | reg = | ||
1434 | display_fifo_depth_reg. | ||
1435 | iga2_fifo_depth_select_reg.reg; | ||
1436 | viafb_load_reg(reg_value, | ||
1437 | viafb_load_reg_num, reg, VIACR); | ||
1438 | } | ||
1439 | |||
1440 | /* Set Display FIFO Threshold Select */ | ||
1441 | reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold); | ||
1442 | viafb_load_reg_num = | ||
1443 | fifo_threshold_select_reg. | ||
1444 | iga2_fifo_threshold_select_reg.reg_num; | ||
1445 | reg = | ||
1446 | fifo_threshold_select_reg. | ||
1447 | iga2_fifo_threshold_select_reg.reg; | ||
1448 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1449 | |||
1450 | /* Set FIFO High Threshold Select */ | ||
1451 | reg_value = | ||
1452 | IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold); | ||
1453 | viafb_load_reg_num = | ||
1454 | fifo_high_threshold_select_reg. | ||
1455 | iga2_fifo_high_threshold_select_reg.reg_num; | ||
1456 | reg = | ||
1457 | fifo_high_threshold_select_reg. | ||
1458 | iga2_fifo_high_threshold_select_reg.reg; | ||
1459 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1460 | |||
1461 | /* Set Display Queue Expire Num */ | ||
1462 | reg_value = | ||
1463 | IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA | ||
1464 | (iga2_display_queue_expire_num); | ||
1465 | viafb_load_reg_num = | ||
1466 | display_queue_expire_num_reg. | ||
1467 | iga2_display_queue_expire_num_reg.reg_num; | ||
1468 | reg = | ||
1469 | display_queue_expire_num_reg. | ||
1470 | iga2_display_queue_expire_num_reg.reg; | ||
1471 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1472 | |||
1473 | } | ||
1474 | |||
1475 | } | ||
1476 | |||
1477 | u32 viafb_get_clk_value(int clk) | ||
1478 | { | ||
1479 | int i; | ||
1480 | |||
1481 | for (i = 0; i < NUM_TOTAL_PLL_TABLE; i++) { | ||
1482 | if (clk == pll_value[i].clk) { | ||
1483 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
1484 | case UNICHROME_CLE266: | ||
1485 | case UNICHROME_K400: | ||
1486 | return pll_value[i].cle266_pll; | ||
1487 | |||
1488 | case UNICHROME_K800: | ||
1489 | case UNICHROME_PM800: | ||
1490 | case UNICHROME_CN700: | ||
1491 | return pll_value[i].k800_pll; | ||
1492 | |||
1493 | case UNICHROME_CX700: | ||
1494 | case UNICHROME_K8M890: | ||
1495 | case UNICHROME_P4M890: | ||
1496 | case UNICHROME_P4M900: | ||
1497 | case UNICHROME_VX800: | ||
1498 | return pll_value[i].cx700_pll; | ||
1499 | } | ||
1500 | } | ||
1501 | } | ||
1502 | |||
1503 | DEBUG_MSG(KERN_INFO "Can't find match PLL value\n\n"); | ||
1504 | return 0; | ||
1505 | } | ||
1506 | |||
1507 | /* Set VCLK*/ | ||
1508 | void viafb_set_vclock(u32 CLK, int set_iga) | ||
1509 | { | ||
1510 | unsigned char RegTemp; | ||
1511 | |||
1512 | /* H.W. Reset : ON */ | ||
1513 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | ||
1514 | |||
1515 | if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) { | ||
1516 | /* Change D,N FOR VCLK */ | ||
1517 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
1518 | case UNICHROME_CLE266: | ||
1519 | case UNICHROME_K400: | ||
1520 | viafb_write_reg(SR46, VIASR, CLK / 0x100); | ||
1521 | viafb_write_reg(SR47, VIASR, CLK % 0x100); | ||
1522 | break; | ||
1523 | |||
1524 | case UNICHROME_K800: | ||
1525 | case UNICHROME_PM800: | ||
1526 | case UNICHROME_CN700: | ||
1527 | case UNICHROME_CX700: | ||
1528 | case UNICHROME_K8M890: | ||
1529 | case UNICHROME_P4M890: | ||
1530 | case UNICHROME_P4M900: | ||
1531 | case UNICHROME_VX800: | ||
1532 | viafb_write_reg(SR44, VIASR, CLK / 0x10000); | ||
1533 | DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000); | ||
1534 | viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100); | ||
1535 | DEBUG_MSG(KERN_INFO "\nSR45=%x", | ||
1536 | (CLK & 0xFFFF) / 0x100); | ||
1537 | viafb_write_reg(SR46, VIASR, CLK % 0x100); | ||
1538 | DEBUG_MSG(KERN_INFO "\nSR46=%x", CLK % 0x100); | ||
1539 | break; | ||
1540 | } | ||
1541 | } | ||
1542 | |||
1543 | if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) { | ||
1544 | /* Change D,N FOR LCK */ | ||
1545 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
1546 | case UNICHROME_CLE266: | ||
1547 | case UNICHROME_K400: | ||
1548 | viafb_write_reg(SR44, VIASR, CLK / 0x100); | ||
1549 | viafb_write_reg(SR45, VIASR, CLK % 0x100); | ||
1550 | break; | ||
1551 | |||
1552 | case UNICHROME_K800: | ||
1553 | case UNICHROME_PM800: | ||
1554 | case UNICHROME_CN700: | ||
1555 | case UNICHROME_CX700: | ||
1556 | case UNICHROME_K8M890: | ||
1557 | case UNICHROME_P4M890: | ||
1558 | case UNICHROME_P4M900: | ||
1559 | case UNICHROME_VX800: | ||
1560 | viafb_write_reg(SR4A, VIASR, CLK / 0x10000); | ||
1561 | viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100); | ||
1562 | viafb_write_reg(SR4C, VIASR, CLK % 0x100); | ||
1563 | break; | ||
1564 | } | ||
1565 | } | ||
1566 | |||
1567 | /* H.W. Reset : OFF */ | ||
1568 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | ||
1569 | |||
1570 | /* Reset PLL */ | ||
1571 | if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) { | ||
1572 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); | ||
1573 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); | ||
1574 | } | ||
1575 | |||
1576 | if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) { | ||
1577 | viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0); | ||
1578 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0); | ||
1579 | } | ||
1580 | |||
1581 | /* Fire! */ | ||
1582 | RegTemp = inb(VIARMisc); | ||
1583 | outb(RegTemp | (BIT2 + BIT3), VIAWMisc); | ||
1584 | } | ||
1585 | |||
1586 | void viafb_load_crtc_timing(struct display_timing device_timing, | ||
1587 | int set_iga) | ||
1588 | { | ||
1589 | int i; | ||
1590 | int viafb_load_reg_num = 0; | ||
1591 | int reg_value = 0; | ||
1592 | struct io_register *reg = NULL; | ||
1593 | |||
1594 | viafb_unlock_crt(); | ||
1595 | |||
1596 | for (i = 0; i < 12; i++) { | ||
1597 | if (set_iga == IGA1) { | ||
1598 | switch (i) { | ||
1599 | case H_TOTAL_INDEX: | ||
1600 | reg_value = | ||
1601 | IGA1_HOR_TOTAL_FORMULA(device_timing. | ||
1602 | hor_total); | ||
1603 | viafb_load_reg_num = | ||
1604 | iga1_crtc_reg.hor_total.reg_num; | ||
1605 | reg = iga1_crtc_reg.hor_total.reg; | ||
1606 | break; | ||
1607 | case H_ADDR_INDEX: | ||
1608 | reg_value = | ||
1609 | IGA1_HOR_ADDR_FORMULA(device_timing. | ||
1610 | hor_addr); | ||
1611 | viafb_load_reg_num = | ||
1612 | iga1_crtc_reg.hor_addr.reg_num; | ||
1613 | reg = iga1_crtc_reg.hor_addr.reg; | ||
1614 | break; | ||
1615 | case H_BLANK_START_INDEX: | ||
1616 | reg_value = | ||
1617 | IGA1_HOR_BLANK_START_FORMULA | ||
1618 | (device_timing.hor_blank_start); | ||
1619 | viafb_load_reg_num = | ||
1620 | iga1_crtc_reg.hor_blank_start.reg_num; | ||
1621 | reg = iga1_crtc_reg.hor_blank_start.reg; | ||
1622 | break; | ||
1623 | case H_BLANK_END_INDEX: | ||
1624 | reg_value = | ||
1625 | IGA1_HOR_BLANK_END_FORMULA | ||
1626 | (device_timing.hor_blank_start, | ||
1627 | device_timing.hor_blank_end); | ||
1628 | viafb_load_reg_num = | ||
1629 | iga1_crtc_reg.hor_blank_end.reg_num; | ||
1630 | reg = iga1_crtc_reg.hor_blank_end.reg; | ||
1631 | break; | ||
1632 | case H_SYNC_START_INDEX: | ||
1633 | reg_value = | ||
1634 | IGA1_HOR_SYNC_START_FORMULA | ||
1635 | (device_timing.hor_sync_start); | ||
1636 | viafb_load_reg_num = | ||
1637 | iga1_crtc_reg.hor_sync_start.reg_num; | ||
1638 | reg = iga1_crtc_reg.hor_sync_start.reg; | ||
1639 | break; | ||
1640 | case H_SYNC_END_INDEX: | ||
1641 | reg_value = | ||
1642 | IGA1_HOR_SYNC_END_FORMULA | ||
1643 | (device_timing.hor_sync_start, | ||
1644 | device_timing.hor_sync_end); | ||
1645 | viafb_load_reg_num = | ||
1646 | iga1_crtc_reg.hor_sync_end.reg_num; | ||
1647 | reg = iga1_crtc_reg.hor_sync_end.reg; | ||
1648 | break; | ||
1649 | case V_TOTAL_INDEX: | ||
1650 | reg_value = | ||
1651 | IGA1_VER_TOTAL_FORMULA(device_timing. | ||
1652 | ver_total); | ||
1653 | viafb_load_reg_num = | ||
1654 | iga1_crtc_reg.ver_total.reg_num; | ||
1655 | reg = iga1_crtc_reg.ver_total.reg; | ||
1656 | break; | ||
1657 | case V_ADDR_INDEX: | ||
1658 | reg_value = | ||
1659 | IGA1_VER_ADDR_FORMULA(device_timing. | ||
1660 | ver_addr); | ||
1661 | viafb_load_reg_num = | ||
1662 | iga1_crtc_reg.ver_addr.reg_num; | ||
1663 | reg = iga1_crtc_reg.ver_addr.reg; | ||
1664 | break; | ||
1665 | case V_BLANK_START_INDEX: | ||
1666 | reg_value = | ||
1667 | IGA1_VER_BLANK_START_FORMULA | ||
1668 | (device_timing.ver_blank_start); | ||
1669 | viafb_load_reg_num = | ||
1670 | iga1_crtc_reg.ver_blank_start.reg_num; | ||
1671 | reg = iga1_crtc_reg.ver_blank_start.reg; | ||
1672 | break; | ||
1673 | case V_BLANK_END_INDEX: | ||
1674 | reg_value = | ||
1675 | IGA1_VER_BLANK_END_FORMULA | ||
1676 | (device_timing.ver_blank_start, | ||
1677 | device_timing.ver_blank_end); | ||
1678 | viafb_load_reg_num = | ||
1679 | iga1_crtc_reg.ver_blank_end.reg_num; | ||
1680 | reg = iga1_crtc_reg.ver_blank_end.reg; | ||
1681 | break; | ||
1682 | case V_SYNC_START_INDEX: | ||
1683 | reg_value = | ||
1684 | IGA1_VER_SYNC_START_FORMULA | ||
1685 | (device_timing.ver_sync_start); | ||
1686 | viafb_load_reg_num = | ||
1687 | iga1_crtc_reg.ver_sync_start.reg_num; | ||
1688 | reg = iga1_crtc_reg.ver_sync_start.reg; | ||
1689 | break; | ||
1690 | case V_SYNC_END_INDEX: | ||
1691 | reg_value = | ||
1692 | IGA1_VER_SYNC_END_FORMULA | ||
1693 | (device_timing.ver_sync_start, | ||
1694 | device_timing.ver_sync_end); | ||
1695 | viafb_load_reg_num = | ||
1696 | iga1_crtc_reg.ver_sync_end.reg_num; | ||
1697 | reg = iga1_crtc_reg.ver_sync_end.reg; | ||
1698 | break; | ||
1699 | |||
1700 | } | ||
1701 | } | ||
1702 | |||
1703 | if (set_iga == IGA2) { | ||
1704 | switch (i) { | ||
1705 | case H_TOTAL_INDEX: | ||
1706 | reg_value = | ||
1707 | IGA2_HOR_TOTAL_FORMULA(device_timing. | ||
1708 | hor_total); | ||
1709 | viafb_load_reg_num = | ||
1710 | iga2_crtc_reg.hor_total.reg_num; | ||
1711 | reg = iga2_crtc_reg.hor_total.reg; | ||
1712 | break; | ||
1713 | case H_ADDR_INDEX: | ||
1714 | reg_value = | ||
1715 | IGA2_HOR_ADDR_FORMULA(device_timing. | ||
1716 | hor_addr); | ||
1717 | viafb_load_reg_num = | ||
1718 | iga2_crtc_reg.hor_addr.reg_num; | ||
1719 | reg = iga2_crtc_reg.hor_addr.reg; | ||
1720 | break; | ||
1721 | case H_BLANK_START_INDEX: | ||
1722 | reg_value = | ||
1723 | IGA2_HOR_BLANK_START_FORMULA | ||
1724 | (device_timing.hor_blank_start); | ||
1725 | viafb_load_reg_num = | ||
1726 | iga2_crtc_reg.hor_blank_start.reg_num; | ||
1727 | reg = iga2_crtc_reg.hor_blank_start.reg; | ||
1728 | break; | ||
1729 | case H_BLANK_END_INDEX: | ||
1730 | reg_value = | ||
1731 | IGA2_HOR_BLANK_END_FORMULA | ||
1732 | (device_timing.hor_blank_start, | ||
1733 | device_timing.hor_blank_end); | ||
1734 | viafb_load_reg_num = | ||
1735 | iga2_crtc_reg.hor_blank_end.reg_num; | ||
1736 | reg = iga2_crtc_reg.hor_blank_end.reg; | ||
1737 | break; | ||
1738 | case H_SYNC_START_INDEX: | ||
1739 | reg_value = | ||
1740 | IGA2_HOR_SYNC_START_FORMULA | ||
1741 | (device_timing.hor_sync_start); | ||
1742 | if (UNICHROME_CN700 <= | ||
1743 | viaparinfo->chip_info->gfx_chip_name) | ||
1744 | viafb_load_reg_num = | ||
1745 | iga2_crtc_reg.hor_sync_start. | ||
1746 | reg_num; | ||
1747 | else | ||
1748 | viafb_load_reg_num = 3; | ||
1749 | reg = iga2_crtc_reg.hor_sync_start.reg; | ||
1750 | break; | ||
1751 | case H_SYNC_END_INDEX: | ||
1752 | reg_value = | ||
1753 | IGA2_HOR_SYNC_END_FORMULA | ||
1754 | (device_timing.hor_sync_start, | ||
1755 | device_timing.hor_sync_end); | ||
1756 | viafb_load_reg_num = | ||
1757 | iga2_crtc_reg.hor_sync_end.reg_num; | ||
1758 | reg = iga2_crtc_reg.hor_sync_end.reg; | ||
1759 | break; | ||
1760 | case V_TOTAL_INDEX: | ||
1761 | reg_value = | ||
1762 | IGA2_VER_TOTAL_FORMULA(device_timing. | ||
1763 | ver_total); | ||
1764 | viafb_load_reg_num = | ||
1765 | iga2_crtc_reg.ver_total.reg_num; | ||
1766 | reg = iga2_crtc_reg.ver_total.reg; | ||
1767 | break; | ||
1768 | case V_ADDR_INDEX: | ||
1769 | reg_value = | ||
1770 | IGA2_VER_ADDR_FORMULA(device_timing. | ||
1771 | ver_addr); | ||
1772 | viafb_load_reg_num = | ||
1773 | iga2_crtc_reg.ver_addr.reg_num; | ||
1774 | reg = iga2_crtc_reg.ver_addr.reg; | ||
1775 | break; | ||
1776 | case V_BLANK_START_INDEX: | ||
1777 | reg_value = | ||
1778 | IGA2_VER_BLANK_START_FORMULA | ||
1779 | (device_timing.ver_blank_start); | ||
1780 | viafb_load_reg_num = | ||
1781 | iga2_crtc_reg.ver_blank_start.reg_num; | ||
1782 | reg = iga2_crtc_reg.ver_blank_start.reg; | ||
1783 | break; | ||
1784 | case V_BLANK_END_INDEX: | ||
1785 | reg_value = | ||
1786 | IGA2_VER_BLANK_END_FORMULA | ||
1787 | (device_timing.ver_blank_start, | ||
1788 | device_timing.ver_blank_end); | ||
1789 | viafb_load_reg_num = | ||
1790 | iga2_crtc_reg.ver_blank_end.reg_num; | ||
1791 | reg = iga2_crtc_reg.ver_blank_end.reg; | ||
1792 | break; | ||
1793 | case V_SYNC_START_INDEX: | ||
1794 | reg_value = | ||
1795 | IGA2_VER_SYNC_START_FORMULA | ||
1796 | (device_timing.ver_sync_start); | ||
1797 | viafb_load_reg_num = | ||
1798 | iga2_crtc_reg.ver_sync_start.reg_num; | ||
1799 | reg = iga2_crtc_reg.ver_sync_start.reg; | ||
1800 | break; | ||
1801 | case V_SYNC_END_INDEX: | ||
1802 | reg_value = | ||
1803 | IGA2_VER_SYNC_END_FORMULA | ||
1804 | (device_timing.ver_sync_start, | ||
1805 | device_timing.ver_sync_end); | ||
1806 | viafb_load_reg_num = | ||
1807 | iga2_crtc_reg.ver_sync_end.reg_num; | ||
1808 | reg = iga2_crtc_reg.ver_sync_end.reg; | ||
1809 | break; | ||
1810 | |||
1811 | } | ||
1812 | } | ||
1813 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1814 | } | ||
1815 | |||
1816 | viafb_lock_crt(); | ||
1817 | } | ||
1818 | |||
1819 | void viafb_set_color_depth(int bpp_byte, int set_iga) | ||
1820 | { | ||
1821 | if (set_iga == IGA1) { | ||
1822 | switch (bpp_byte) { | ||
1823 | case MODE_8BPP: | ||
1824 | viafb_write_reg_mask(SR15, VIASR, 0x22, 0x7E); | ||
1825 | break; | ||
1826 | case MODE_16BPP: | ||
1827 | viafb_write_reg_mask(SR15, VIASR, 0xB6, 0xFE); | ||
1828 | break; | ||
1829 | case MODE_32BPP: | ||
1830 | viafb_write_reg_mask(SR15, VIASR, 0xAE, 0xFE); | ||
1831 | break; | ||
1832 | } | ||
1833 | } else { | ||
1834 | switch (bpp_byte) { | ||
1835 | case MODE_8BPP: | ||
1836 | viafb_write_reg_mask(CR67, VIACR, 0x00, BIT6 + BIT7); | ||
1837 | break; | ||
1838 | case MODE_16BPP: | ||
1839 | viafb_write_reg_mask(CR67, VIACR, 0x40, BIT6 + BIT7); | ||
1840 | break; | ||
1841 | case MODE_32BPP: | ||
1842 | viafb_write_reg_mask(CR67, VIACR, 0xC0, BIT6 + BIT7); | ||
1843 | break; | ||
1844 | } | ||
1845 | } | ||
1846 | } | ||
1847 | |||
1848 | void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | ||
1849 | int mode_index, int bpp_byte, int set_iga) | ||
1850 | { | ||
1851 | struct VideoModeTable *video_mode; | ||
1852 | struct display_timing crt_reg; | ||
1853 | int i; | ||
1854 | int index = 0; | ||
1855 | int h_addr, v_addr; | ||
1856 | u32 pll_D_N; | ||
1857 | |||
1858 | video_mode = &CLE266Modes[search_mode_setting(mode_index)]; | ||
1859 | |||
1860 | for (i = 0; i < video_mode->mode_array; i++) { | ||
1861 | index = i; | ||
1862 | |||
1863 | if (crt_table[i].refresh_rate == viaparinfo-> | ||
1864 | crt_setting_info->refresh_rate) | ||
1865 | break; | ||
1866 | } | ||
1867 | |||
1868 | crt_reg = crt_table[index].crtc; | ||
1869 | |||
1870 | /* Mode 640x480 has border, but LCD/DFP didn't have border. */ | ||
1871 | /* So we would delete border. */ | ||
1872 | if ((viafb_LCD_ON | viafb_DVI_ON) && (mode_index == VIA_RES_640X480) | ||
1873 | && (viaparinfo->crt_setting_info->refresh_rate == 60)) { | ||
1874 | /* The border is 8 pixels. */ | ||
1875 | crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8; | ||
1876 | |||
1877 | /* Blanking time should add left and right borders. */ | ||
1878 | crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16; | ||
1879 | } | ||
1880 | |||
1881 | h_addr = crt_reg.hor_addr; | ||
1882 | v_addr = crt_reg.ver_addr; | ||
1883 | |||
1884 | /* update polarity for CRT timing */ | ||
1885 | if (crt_table[index].h_sync_polarity == NEGATIVE) { | ||
1886 | if (crt_table[index].v_sync_polarity == NEGATIVE) | ||
1887 | outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | | ||
1888 | (BIT6 + BIT7), VIAWMisc); | ||
1889 | else | ||
1890 | outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT6), | ||
1891 | VIAWMisc); | ||
1892 | } else { | ||
1893 | if (crt_table[index].v_sync_polarity == NEGATIVE) | ||
1894 | outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT7), | ||
1895 | VIAWMisc); | ||
1896 | else | ||
1897 | outb((inb(VIARMisc) & (~(BIT6 + BIT7))), VIAWMisc); | ||
1898 | } | ||
1899 | |||
1900 | if (set_iga == IGA1) { | ||
1901 | viafb_unlock_crt(); | ||
1902 | viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */ | ||
1903 | viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6); | ||
1904 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | ||
1905 | } | ||
1906 | |||
1907 | switch (set_iga) { | ||
1908 | case IGA1: | ||
1909 | viafb_load_crtc_timing(crt_reg, IGA1); | ||
1910 | break; | ||
1911 | case IGA2: | ||
1912 | viafb_load_crtc_timing(crt_reg, IGA2); | ||
1913 | break; | ||
1914 | } | ||
1915 | |||
1916 | load_fix_bit_crtc_reg(); | ||
1917 | viafb_lock_crt(); | ||
1918 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | ||
1919 | viafb_load_offset_reg(h_addr, bpp_byte, set_iga); | ||
1920 | viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); | ||
1921 | |||
1922 | /* load FIFO */ | ||
1923 | if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) | ||
1924 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) | ||
1925 | viafb_load_FIFO_reg(set_iga, h_addr, v_addr); | ||
1926 | |||
1927 | /* load SR Register About Memory and Color part */ | ||
1928 | viafb_set_color_depth(bpp_byte, set_iga); | ||
1929 | |||
1930 | pll_D_N = viafb_get_clk_value(crt_table[index].clk); | ||
1931 | DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); | ||
1932 | viafb_set_vclock(pll_D_N, set_iga); | ||
1933 | |||
1934 | } | ||
1935 | |||
1936 | void viafb_init_chip_info(void) | ||
1937 | { | ||
1938 | init_gfx_chip_info(); | ||
1939 | init_tmds_chip_info(); | ||
1940 | init_lvds_chip_info(); | ||
1941 | |||
1942 | viaparinfo->crt_setting_info->iga_path = IGA1; | ||
1943 | viaparinfo->crt_setting_info->refresh_rate = viafb_refresh; | ||
1944 | |||
1945 | /*Set IGA path for each device */ | ||
1946 | viafb_set_iga_path(); | ||
1947 | |||
1948 | viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method; | ||
1949 | viaparinfo->lvds_setting_info->get_lcd_size_method = | ||
1950 | GET_LCD_SIZE_BY_USER_SETTING; | ||
1951 | viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode; | ||
1952 | viaparinfo->lvds_setting_info2->display_method = | ||
1953 | viaparinfo->lvds_setting_info->display_method; | ||
1954 | viaparinfo->lvds_setting_info2->lcd_mode = | ||
1955 | viaparinfo->lvds_setting_info->lcd_mode; | ||
1956 | } | ||
1957 | |||
1958 | void viafb_update_device_setting(int hres, int vres, | ||
1959 | int bpp, int vmode_refresh, int flag) | ||
1960 | { | ||
1961 | if (flag == 0) { | ||
1962 | viaparinfo->crt_setting_info->h_active = hres; | ||
1963 | viaparinfo->crt_setting_info->v_active = vres; | ||
1964 | viaparinfo->crt_setting_info->bpp = bpp; | ||
1965 | viaparinfo->crt_setting_info->refresh_rate = | ||
1966 | vmode_refresh; | ||
1967 | |||
1968 | viaparinfo->tmds_setting_info->h_active = hres; | ||
1969 | viaparinfo->tmds_setting_info->v_active = vres; | ||
1970 | viaparinfo->tmds_setting_info->bpp = bpp; | ||
1971 | viaparinfo->tmds_setting_info->refresh_rate = | ||
1972 | vmode_refresh; | ||
1973 | |||
1974 | viaparinfo->lvds_setting_info->h_active = hres; | ||
1975 | viaparinfo->lvds_setting_info->v_active = vres; | ||
1976 | viaparinfo->lvds_setting_info->bpp = bpp; | ||
1977 | viaparinfo->lvds_setting_info->refresh_rate = | ||
1978 | vmode_refresh; | ||
1979 | viaparinfo->lvds_setting_info2->h_active = hres; | ||
1980 | viaparinfo->lvds_setting_info2->v_active = vres; | ||
1981 | viaparinfo->lvds_setting_info2->bpp = bpp; | ||
1982 | viaparinfo->lvds_setting_info2->refresh_rate = | ||
1983 | vmode_refresh; | ||
1984 | } else { | ||
1985 | |||
1986 | if (viaparinfo->tmds_setting_info->iga_path == IGA2) { | ||
1987 | viaparinfo->tmds_setting_info->h_active = hres; | ||
1988 | viaparinfo->tmds_setting_info->v_active = vres; | ||
1989 | viaparinfo->tmds_setting_info->bpp = bpp; | ||
1990 | viaparinfo->tmds_setting_info->refresh_rate = | ||
1991 | vmode_refresh; | ||
1992 | } | ||
1993 | |||
1994 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) { | ||
1995 | viaparinfo->lvds_setting_info->h_active = hres; | ||
1996 | viaparinfo->lvds_setting_info->v_active = vres; | ||
1997 | viaparinfo->lvds_setting_info->bpp = bpp; | ||
1998 | viaparinfo->lvds_setting_info->refresh_rate = | ||
1999 | vmode_refresh; | ||
2000 | } | ||
2001 | if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) { | ||
2002 | viaparinfo->lvds_setting_info2->h_active = hres; | ||
2003 | viaparinfo->lvds_setting_info2->v_active = vres; | ||
2004 | viaparinfo->lvds_setting_info2->bpp = bpp; | ||
2005 | viaparinfo->lvds_setting_info2->refresh_rate = | ||
2006 | vmode_refresh; | ||
2007 | } | ||
2008 | } | ||
2009 | } | ||
2010 | |||
2011 | static void init_gfx_chip_info(void) | ||
2012 | { | ||
2013 | struct pci_dev *pdev = NULL; | ||
2014 | u32 i; | ||
2015 | u8 tmp; | ||
2016 | |||
2017 | /* Indentify GFX Chip Name */ | ||
2018 | for (i = 0; pciidlist[i].vendor != 0; i++) { | ||
2019 | pdev = pci_get_device(pciidlist[i].vendor, | ||
2020 | pciidlist[i].device, 0); | ||
2021 | if (pdev) | ||
2022 | break; | ||
2023 | } | ||
2024 | |||
2025 | if (!pciidlist[i].vendor) | ||
2026 | return ; | ||
2027 | |||
2028 | viaparinfo->chip_info->gfx_chip_name = pciidlist[i].chip_index; | ||
2029 | |||
2030 | /* Check revision of CLE266 Chip */ | ||
2031 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | ||
2032 | /* CR4F only define in CLE266.CX chip */ | ||
2033 | tmp = viafb_read_reg(VIACR, CR4F); | ||
2034 | viafb_write_reg(CR4F, VIACR, 0x55); | ||
2035 | if (viafb_read_reg(VIACR, CR4F) != 0x55) | ||
2036 | viaparinfo->chip_info->gfx_chip_revision = | ||
2037 | CLE266_REVISION_AX; | ||
2038 | else | ||
2039 | viaparinfo->chip_info->gfx_chip_revision = | ||
2040 | CLE266_REVISION_CX; | ||
2041 | /* restore orignal CR4F value */ | ||
2042 | viafb_write_reg(CR4F, VIACR, tmp); | ||
2043 | } | ||
2044 | |||
2045 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { | ||
2046 | tmp = viafb_read_reg(VIASR, SR43); | ||
2047 | DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp); | ||
2048 | if (tmp & 0x02) { | ||
2049 | viaparinfo->chip_info->gfx_chip_revision = | ||
2050 | CX700_REVISION_700M2; | ||
2051 | } else if (tmp & 0x40) { | ||
2052 | viaparinfo->chip_info->gfx_chip_revision = | ||
2053 | CX700_REVISION_700M; | ||
2054 | } else { | ||
2055 | viaparinfo->chip_info->gfx_chip_revision = | ||
2056 | CX700_REVISION_700; | ||
2057 | } | ||
2058 | } | ||
2059 | |||
2060 | pci_dev_put(pdev); | ||
2061 | } | ||
2062 | |||
2063 | static void init_tmds_chip_info(void) | ||
2064 | { | ||
2065 | viafb_tmds_trasmitter_identify(); | ||
2066 | |||
2067 | if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info. | ||
2068 | output_interface) { | ||
2069 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
2070 | case UNICHROME_CX700: | ||
2071 | { | ||
2072 | /* we should check support by hardware layout.*/ | ||
2073 | if ((viafb_display_hardware_layout == | ||
2074 | HW_LAYOUT_DVI_ONLY) | ||
2075 | || (viafb_display_hardware_layout == | ||
2076 | HW_LAYOUT_LCD_DVI)) { | ||
2077 | viaparinfo->chip_info->tmds_chip_info. | ||
2078 | output_interface = INTERFACE_TMDS; | ||
2079 | } else { | ||
2080 | viaparinfo->chip_info->tmds_chip_info. | ||
2081 | output_interface = | ||
2082 | INTERFACE_NONE; | ||
2083 | } | ||
2084 | break; | ||
2085 | } | ||
2086 | case UNICHROME_K8M890: | ||
2087 | case UNICHROME_P4M900: | ||
2088 | case UNICHROME_P4M890: | ||
2089 | /* TMDS on PCIE, we set DFPLOW as default. */ | ||
2090 | viaparinfo->chip_info->tmds_chip_info.output_interface = | ||
2091 | INTERFACE_DFP_LOW; | ||
2092 | break; | ||
2093 | default: | ||
2094 | { | ||
2095 | /* set DVP1 default for DVI */ | ||
2096 | viaparinfo->chip_info->tmds_chip_info | ||
2097 | .output_interface = INTERFACE_DVP1; | ||
2098 | } | ||
2099 | } | ||
2100 | } | ||
2101 | |||
2102 | DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n", | ||
2103 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); | ||
2104 | viaparinfo->tmds_setting_info->get_dvi_size_method = | ||
2105 | GET_DVI_SIZE_BY_VGA_BIOS; | ||
2106 | viafb_init_dvi_size(); | ||
2107 | } | ||
2108 | |||
2109 | static void init_lvds_chip_info(void) | ||
2110 | { | ||
2111 | if (viafb_lcd_panel_id > LCD_PANEL_ID_MAXIMUM) | ||
2112 | viaparinfo->lvds_setting_info->get_lcd_size_method = | ||
2113 | GET_LCD_SIZE_BY_VGA_BIOS; | ||
2114 | else | ||
2115 | viaparinfo->lvds_setting_info->get_lcd_size_method = | ||
2116 | GET_LCD_SIZE_BY_USER_SETTING; | ||
2117 | |||
2118 | viafb_lvds_trasmitter_identify(); | ||
2119 | viafb_init_lcd_size(); | ||
2120 | viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info, | ||
2121 | viaparinfo->lvds_setting_info); | ||
2122 | if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { | ||
2123 | viafb_init_lvds_output_interface(&viaparinfo->chip_info-> | ||
2124 | lvds_chip_info2, viaparinfo->lvds_setting_info2); | ||
2125 | } | ||
2126 | /*If CX700,two singel LCD, we need to reassign | ||
2127 | LCD interface to different LVDS port */ | ||
2128 | if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name) | ||
2129 | && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) { | ||
2130 | if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info. | ||
2131 | lvds_chip_name) && (INTEGRATED_LVDS == | ||
2132 | viaparinfo->chip_info-> | ||
2133 | lvds_chip_info2.lvds_chip_name)) { | ||
2134 | viaparinfo->chip_info->lvds_chip_info.output_interface = | ||
2135 | INTERFACE_LVDS0; | ||
2136 | viaparinfo->chip_info->lvds_chip_info2. | ||
2137 | output_interface = | ||
2138 | INTERFACE_LVDS1; | ||
2139 | } | ||
2140 | } | ||
2141 | |||
2142 | DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n", | ||
2143 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); | ||
2144 | DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n", | ||
2145 | viaparinfo->chip_info->lvds_chip_info.output_interface); | ||
2146 | DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n", | ||
2147 | viaparinfo->chip_info->lvds_chip_info.output_interface); | ||
2148 | } | ||
2149 | |||
2150 | void viafb_init_dac(int set_iga) | ||
2151 | { | ||
2152 | int i; | ||
2153 | u8 tmp; | ||
2154 | |||
2155 | if (set_iga == IGA1) { | ||
2156 | /* access Primary Display's LUT */ | ||
2157 | viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0); | ||
2158 | /* turn off LCK */ | ||
2159 | viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6); | ||
2160 | for (i = 0; i < 256; i++) { | ||
2161 | write_dac_reg(i, palLUT_table[i].red, | ||
2162 | palLUT_table[i].green, | ||
2163 | palLUT_table[i].blue); | ||
2164 | } | ||
2165 | /* turn on LCK */ | ||
2166 | viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6); | ||
2167 | } else { | ||
2168 | tmp = viafb_read_reg(VIACR, CR6A); | ||
2169 | /* access Secondary Display's LUT */ | ||
2170 | viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6); | ||
2171 | viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0); | ||
2172 | for (i = 0; i < 256; i++) { | ||
2173 | write_dac_reg(i, palLUT_table[i].red, | ||
2174 | palLUT_table[i].green, | ||
2175 | palLUT_table[i].blue); | ||
2176 | } | ||
2177 | /* set IGA1 DAC for default */ | ||
2178 | viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0); | ||
2179 | viafb_write_reg(CR6A, VIACR, tmp); | ||
2180 | } | ||
2181 | } | ||
2182 | |||
2183 | static void device_screen_off(void) | ||
2184 | { | ||
2185 | /* turn off CRT screen (IGA1) */ | ||
2186 | viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5); | ||
2187 | } | ||
2188 | |||
2189 | static void device_screen_on(void) | ||
2190 | { | ||
2191 | /* turn on CRT screen (IGA1) */ | ||
2192 | viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5); | ||
2193 | } | ||
2194 | |||
2195 | static void set_display_channel(void) | ||
2196 | { | ||
2197 | /*If viafb_LCD2_ON, on cx700, internal lvds's information | ||
2198 | is keeped on lvds_setting_info2 */ | ||
2199 | if (viafb_LCD2_ON && | ||
2200 | viaparinfo->lvds_setting_info2->device_lcd_dualedge) { | ||
2201 | /* For dual channel LCD: */ | ||
2202 | /* Set to Dual LVDS channel. */ | ||
2203 | viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5); | ||
2204 | } else if (viafb_LCD_ON && viafb_DVI_ON) { | ||
2205 | /* For LCD+DFP: */ | ||
2206 | /* Set to LVDS1 + TMDS channel. */ | ||
2207 | viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5); | ||
2208 | } else if (viafb_DVI_ON) { | ||
2209 | /* Set to single TMDS channel. */ | ||
2210 | viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5); | ||
2211 | } else if (viafb_LCD_ON) { | ||
2212 | if (viaparinfo->lvds_setting_info->device_lcd_dualedge) { | ||
2213 | /* For dual channel LCD: */ | ||
2214 | /* Set to Dual LVDS channel. */ | ||
2215 | viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5); | ||
2216 | } else { | ||
2217 | /* Set to LVDS0 + LVDS1 channel. */ | ||
2218 | viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5); | ||
2219 | } | ||
2220 | } | ||
2221 | } | ||
2222 | |||
2223 | int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | ||
2224 | int vmode_index1, int hor_res1, int ver_res1, int video_bpp1) | ||
2225 | { | ||
2226 | int i, j; | ||
2227 | int port; | ||
2228 | u8 value, index, mask; | ||
2229 | struct VideoModeTable *vmode_tbl; | ||
2230 | struct crt_mode_table *crt_timing; | ||
2231 | struct VideoModeTable *vmode_tbl1 = NULL; | ||
2232 | struct crt_mode_table *crt_timing1 = NULL; | ||
2233 | |||
2234 | DEBUG_MSG(KERN_INFO "Set Mode!!\n"); | ||
2235 | DEBUG_MSG(KERN_INFO | ||
2236 | "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n", | ||
2237 | vmode_index, hor_res, ver_res, video_bpp); | ||
2238 | |||
2239 | device_screen_off(); | ||
2240 | vmode_tbl = &CLE266Modes[search_mode_setting(vmode_index)]; | ||
2241 | crt_timing = vmode_tbl->crtc; | ||
2242 | |||
2243 | if (viafb_SAMM_ON == 1) { | ||
2244 | vmode_tbl1 = &CLE266Modes[search_mode_setting(vmode_index1)]; | ||
2245 | crt_timing1 = vmode_tbl1->crtc; | ||
2246 | } | ||
2247 | |||
2248 | inb(VIAStatus); | ||
2249 | outb(0x00, VIAAR); | ||
2250 | |||
2251 | /* Write Common Setting for Video Mode */ | ||
2252 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
2253 | case UNICHROME_CLE266: | ||
2254 | viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs); | ||
2255 | break; | ||
2256 | |||
2257 | case UNICHROME_K400: | ||
2258 | viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs); | ||
2259 | break; | ||
2260 | |||
2261 | case UNICHROME_K800: | ||
2262 | case UNICHROME_PM800: | ||
2263 | viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs); | ||
2264 | break; | ||
2265 | |||
2266 | case UNICHROME_CN700: | ||
2267 | case UNICHROME_K8M890: | ||
2268 | case UNICHROME_P4M890: | ||
2269 | case UNICHROME_P4M900: | ||
2270 | viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs); | ||
2271 | break; | ||
2272 | |||
2273 | case UNICHROME_CX700: | ||
2274 | viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs); | ||
2275 | |||
2276 | case UNICHROME_VX800: | ||
2277 | viafb_write_regx(VX800_ModeXregs, NUM_TOTAL_VX800_ModeXregs); | ||
2278 | |||
2279 | break; | ||
2280 | } | ||
2281 | |||
2282 | device_off(); | ||
2283 | |||
2284 | /* Fill VPIT Parameters */ | ||
2285 | /* Write Misc Register */ | ||
2286 | outb(VPIT.Misc, VIAWMisc); | ||
2287 | |||
2288 | /* Write Sequencer */ | ||
2289 | for (i = 1; i <= StdSR; i++) { | ||
2290 | outb(i, VIASR); | ||
2291 | outb(VPIT.SR[i - 1], VIASR + 1); | ||
2292 | } | ||
2293 | |||
2294 | viafb_set_start_addr(); | ||
2295 | viafb_set_iga_path(); | ||
2296 | |||
2297 | /* Write CRTC */ | ||
2298 | viafb_fill_crtc_timing(crt_timing, vmode_index, video_bpp / 8, IGA1); | ||
2299 | |||
2300 | /* Write Graphic Controller */ | ||
2301 | for (i = 0; i < StdGR; i++) { | ||
2302 | outb(i, VIAGR); | ||
2303 | outb(VPIT.GR[i], VIAGR + 1); | ||
2304 | } | ||
2305 | |||
2306 | /* Write Attribute Controller */ | ||
2307 | for (i = 0; i < StdAR; i++) { | ||
2308 | inb(VIAStatus); | ||
2309 | outb(i, VIAAR); | ||
2310 | outb(VPIT.AR[i], VIAAR); | ||
2311 | } | ||
2312 | |||
2313 | inb(VIAStatus); | ||
2314 | outb(0x20, VIAAR); | ||
2315 | |||
2316 | /* Update Patch Register */ | ||
2317 | |||
2318 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
2319 | || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)) { | ||
2320 | for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) { | ||
2321 | if (res_patch_table[i].mode_index == vmode_index) { | ||
2322 | for (j = 0; | ||
2323 | j < res_patch_table[i].table_length; j++) { | ||
2324 | index = | ||
2325 | res_patch_table[i]. | ||
2326 | io_reg_table[j].index; | ||
2327 | port = | ||
2328 | res_patch_table[i]. | ||
2329 | io_reg_table[j].port; | ||
2330 | value = | ||
2331 | res_patch_table[i]. | ||
2332 | io_reg_table[j].value; | ||
2333 | mask = | ||
2334 | res_patch_table[i]. | ||
2335 | io_reg_table[j].mask; | ||
2336 | viafb_write_reg_mask(index, port, value, | ||
2337 | mask); | ||
2338 | } | ||
2339 | } | ||
2340 | } | ||
2341 | } | ||
2342 | |||
2343 | if (viafb_SAMM_ON == 1) { | ||
2344 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
2345 | || (viaparinfo->chip_info->gfx_chip_name == | ||
2346 | UNICHROME_K400)) { | ||
2347 | for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) { | ||
2348 | if (res_patch_table[i].mode_index == | ||
2349 | vmode_index1) { | ||
2350 | for (j = 0; | ||
2351 | j < | ||
2352 | res_patch_table[i]. | ||
2353 | table_length; j++) { | ||
2354 | index = | ||
2355 | res_patch_table[i]. | ||
2356 | io_reg_table[j].index; | ||
2357 | port = | ||
2358 | res_patch_table[i]. | ||
2359 | io_reg_table[j].port; | ||
2360 | value = | ||
2361 | res_patch_table[i]. | ||
2362 | io_reg_table[j].value; | ||
2363 | mask = | ||
2364 | res_patch_table[i]. | ||
2365 | io_reg_table[j].mask; | ||
2366 | viafb_write_reg_mask(index, | ||
2367 | port, value, mask); | ||
2368 | } | ||
2369 | } | ||
2370 | } | ||
2371 | } | ||
2372 | } | ||
2373 | |||
2374 | /* Update Refresh Rate Setting */ | ||
2375 | |||
2376 | /* Clear On Screen */ | ||
2377 | |||
2378 | /* CRT set mode */ | ||
2379 | if (viafb_CRT_ON) { | ||
2380 | if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == | ||
2381 | IGA2)) { | ||
2382 | viafb_fill_crtc_timing(crt_timing1, vmode_index1, | ||
2383 | video_bpp1 / 8, | ||
2384 | viaparinfo->crt_setting_info->iga_path); | ||
2385 | } else { | ||
2386 | viafb_fill_crtc_timing(crt_timing, vmode_index, | ||
2387 | video_bpp / 8, | ||
2388 | viaparinfo->crt_setting_info->iga_path); | ||
2389 | } | ||
2390 | |||
2391 | set_crt_output_path(viaparinfo->crt_setting_info->iga_path); | ||
2392 | |||
2393 | /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode | ||
2394 | to 8 alignment (1368),there is several pixels (2 pixels) | ||
2395 | on right side of screen. */ | ||
2396 | if (hor_res % 8) { | ||
2397 | viafb_unlock_crt(); | ||
2398 | viafb_write_reg(CR02, VIACR, | ||
2399 | viafb_read_reg(VIACR, CR02) - 1); | ||
2400 | viafb_lock_crt(); | ||
2401 | } | ||
2402 | } | ||
2403 | |||
2404 | if (viafb_DVI_ON) { | ||
2405 | if (viafb_SAMM_ON && | ||
2406 | (viaparinfo->tmds_setting_info->iga_path == IGA2)) { | ||
2407 | viafb_dvi_set_mode(viafb_get_mode_index | ||
2408 | (viaparinfo->tmds_setting_info->h_active, | ||
2409 | viaparinfo->tmds_setting_info-> | ||
2410 | v_active, 1), | ||
2411 | video_bpp1, viaparinfo-> | ||
2412 | tmds_setting_info->iga_path); | ||
2413 | } else { | ||
2414 | viafb_dvi_set_mode(viafb_get_mode_index | ||
2415 | (viaparinfo->tmds_setting_info->h_active, | ||
2416 | viaparinfo-> | ||
2417 | tmds_setting_info->v_active, 0), | ||
2418 | video_bpp, viaparinfo-> | ||
2419 | tmds_setting_info->iga_path); | ||
2420 | } | ||
2421 | } | ||
2422 | |||
2423 | if (viafb_LCD_ON) { | ||
2424 | if (viafb_SAMM_ON && | ||
2425 | (viaparinfo->lvds_setting_info->iga_path == IGA2)) { | ||
2426 | viaparinfo->lvds_setting_info->bpp = video_bpp1; | ||
2427 | viafb_lcd_set_mode(crt_timing1, viaparinfo-> | ||
2428 | lvds_setting_info, | ||
2429 | &viaparinfo->chip_info->lvds_chip_info); | ||
2430 | } else { | ||
2431 | /* IGA1 doesn't have LCD scaling, so set it center. */ | ||
2432 | if (viaparinfo->lvds_setting_info->iga_path == IGA1) { | ||
2433 | viaparinfo->lvds_setting_info->display_method = | ||
2434 | LCD_CENTERING; | ||
2435 | } | ||
2436 | viaparinfo->lvds_setting_info->bpp = video_bpp; | ||
2437 | viafb_lcd_set_mode(crt_timing, viaparinfo-> | ||
2438 | lvds_setting_info, | ||
2439 | &viaparinfo->chip_info->lvds_chip_info); | ||
2440 | } | ||
2441 | } | ||
2442 | if (viafb_LCD2_ON) { | ||
2443 | if (viafb_SAMM_ON && | ||
2444 | (viaparinfo->lvds_setting_info2->iga_path == IGA2)) { | ||
2445 | viaparinfo->lvds_setting_info2->bpp = video_bpp1; | ||
2446 | viafb_lcd_set_mode(crt_timing1, viaparinfo-> | ||
2447 | lvds_setting_info2, | ||
2448 | &viaparinfo->chip_info->lvds_chip_info2); | ||
2449 | } else { | ||
2450 | /* IGA1 doesn't have LCD scaling, so set it center. */ | ||
2451 | if (viaparinfo->lvds_setting_info2->iga_path == IGA1) { | ||
2452 | viaparinfo->lvds_setting_info2->display_method = | ||
2453 | LCD_CENTERING; | ||
2454 | } | ||
2455 | viaparinfo->lvds_setting_info2->bpp = video_bpp; | ||
2456 | viafb_lcd_set_mode(crt_timing, viaparinfo-> | ||
2457 | lvds_setting_info2, | ||
2458 | &viaparinfo->chip_info->lvds_chip_info2); | ||
2459 | } | ||
2460 | } | ||
2461 | |||
2462 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) | ||
2463 | && (viafb_LCD_ON || viafb_DVI_ON)) | ||
2464 | set_display_channel(); | ||
2465 | |||
2466 | /* If set mode normally, save resolution information for hot-plug . */ | ||
2467 | if (!viafb_hotplug) { | ||
2468 | viafb_hotplug_Xres = hor_res; | ||
2469 | viafb_hotplug_Yres = ver_res; | ||
2470 | viafb_hotplug_bpp = video_bpp; | ||
2471 | viafb_hotplug_refresh = viafb_refresh; | ||
2472 | |||
2473 | if (viafb_DVI_ON) | ||
2474 | viafb_DeviceStatus = DVI_Device; | ||
2475 | else | ||
2476 | viafb_DeviceStatus = CRT_Device; | ||
2477 | } | ||
2478 | device_on(); | ||
2479 | |||
2480 | if (viafb_SAMM_ON == 1) | ||
2481 | viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); | ||
2482 | |||
2483 | device_screen_on(); | ||
2484 | return 1; | ||
2485 | } | ||
2486 | |||
2487 | int viafb_get_pixclock(int hres, int vres, int vmode_refresh) | ||
2488 | { | ||
2489 | int i; | ||
2490 | |||
2491 | for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) { | ||
2492 | if ((hres == res_map_refresh_tbl[i].hres) | ||
2493 | && (vres == res_map_refresh_tbl[i].vres) | ||
2494 | && (vmode_refresh == res_map_refresh_tbl[i].vmode_refresh)) | ||
2495 | return res_map_refresh_tbl[i].pixclock; | ||
2496 | } | ||
2497 | return RES_640X480_60HZ_PIXCLOCK; | ||
2498 | |||
2499 | } | ||
2500 | |||
2501 | int viafb_get_refresh(int hres, int vres, u32 long_refresh) | ||
2502 | { | ||
2503 | #define REFRESH_TOLERANCE 3 | ||
2504 | int i, nearest = -1, diff = REFRESH_TOLERANCE; | ||
2505 | for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) { | ||
2506 | if ((hres == res_map_refresh_tbl[i].hres) | ||
2507 | && (vres == res_map_refresh_tbl[i].vres) | ||
2508 | && (diff > (abs(long_refresh - | ||
2509 | res_map_refresh_tbl[i].vmode_refresh)))) { | ||
2510 | diff = abs(long_refresh - res_map_refresh_tbl[i]. | ||
2511 | vmode_refresh); | ||
2512 | nearest = i; | ||
2513 | } | ||
2514 | } | ||
2515 | #undef REFRESH_TOLERANCE | ||
2516 | if (nearest > 0) | ||
2517 | return res_map_refresh_tbl[nearest].vmode_refresh; | ||
2518 | return 60; | ||
2519 | } | ||
2520 | |||
2521 | static void device_off(void) | ||
2522 | { | ||
2523 | viafb_crt_disable(); | ||
2524 | viafb_dvi_disable(); | ||
2525 | viafb_lcd_disable(); | ||
2526 | } | ||
2527 | |||
2528 | static void device_on(void) | ||
2529 | { | ||
2530 | if (viafb_CRT_ON == 1) | ||
2531 | viafb_crt_enable(); | ||
2532 | if (viafb_DVI_ON == 1) | ||
2533 | viafb_dvi_enable(); | ||
2534 | if (viafb_LCD_ON == 1) | ||
2535 | viafb_lcd_enable(); | ||
2536 | } | ||
2537 | |||
2538 | void viafb_crt_disable(void) | ||
2539 | { | ||
2540 | viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4); | ||
2541 | } | ||
2542 | |||
2543 | void viafb_crt_enable(void) | ||
2544 | { | ||
2545 | viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4); | ||
2546 | } | ||
2547 | |||
2548 | void viafb_get_mmio_info(unsigned long *mmio_base, | ||
2549 | unsigned long *mmio_len) | ||
2550 | { | ||
2551 | struct pci_dev *pdev = NULL; | ||
2552 | u32 vendor, device; | ||
2553 | u32 i; | ||
2554 | |||
2555 | for (i = 0; pciidlist[i].vendor != 0; i++) | ||
2556 | if (viaparinfo->chip_info->gfx_chip_name == | ||
2557 | pciidlist[i].chip_index) | ||
2558 | break; | ||
2559 | |||
2560 | if (!pciidlist[i].vendor) | ||
2561 | return ; | ||
2562 | |||
2563 | vendor = pciidlist[i].vendor; | ||
2564 | device = pciidlist[i].device; | ||
2565 | |||
2566 | pdev = pci_get_device(vendor, device, NULL); | ||
2567 | |||
2568 | if (!pdev) { | ||
2569 | *mmio_base = 0; | ||
2570 | *mmio_len = 0; | ||
2571 | return ; | ||
2572 | } | ||
2573 | |||
2574 | *mmio_base = pci_resource_start(pdev, 1); | ||
2575 | *mmio_len = pci_resource_len(pdev, 1); | ||
2576 | |||
2577 | pci_dev_put(pdev); | ||
2578 | } | ||
2579 | |||
2580 | static void enable_second_display_channel(void) | ||
2581 | { | ||
2582 | /* to enable second display channel. */ | ||
2583 | viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6); | ||
2584 | viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7); | ||
2585 | viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); | ||
2586 | } | ||
2587 | |||
2588 | static void disable_second_display_channel(void) | ||
2589 | { | ||
2590 | /* to disable second display channel. */ | ||
2591 | viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6); | ||
2592 | viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7); | ||
2593 | viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); | ||
2594 | } | ||
2595 | |||
2596 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len) | ||
2597 | { | ||
2598 | struct pci_dev *pdev = NULL; | ||
2599 | u32 vendor, device; | ||
2600 | u32 i; | ||
2601 | |||
2602 | for (i = 0; pciidlist[i].vendor != 0; i++) | ||
2603 | if (viaparinfo->chip_info->gfx_chip_name == | ||
2604 | pciidlist[i].chip_index) | ||
2605 | break; | ||
2606 | |||
2607 | if (!pciidlist[i].vendor) | ||
2608 | return ; | ||
2609 | |||
2610 | vendor = pciidlist[i].vendor; | ||
2611 | device = pciidlist[i].device; | ||
2612 | |||
2613 | pdev = pci_get_device(vendor, device, NULL); | ||
2614 | |||
2615 | if (!pdev) { | ||
2616 | *fb_base = viafb_read_reg(VIASR, SR30) << 24; | ||
2617 | *fb_len = viafb_get_memsize(); | ||
2618 | DEBUG_MSG(KERN_INFO "Get FB info from SR30!\n"); | ||
2619 | DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base); | ||
2620 | DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len); | ||
2621 | return ; | ||
2622 | } | ||
2623 | |||
2624 | *fb_base = (unsigned int)pci_resource_start(pdev, 0); | ||
2625 | *fb_len = get_fb_size_from_pci(); | ||
2626 | DEBUG_MSG(KERN_INFO "Get FB info from PCI system!\n"); | ||
2627 | DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base); | ||
2628 | DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len); | ||
2629 | |||
2630 | pci_dev_put(pdev); | ||
2631 | } | ||
2632 | |||
2633 | static int get_fb_size_from_pci(void) | ||
2634 | { | ||
2635 | unsigned long configid, deviceid, FBSize = 0; | ||
2636 | int VideoMemSize; | ||
2637 | int DeviceFound = false; | ||
2638 | |||
2639 | for (configid = 0x80000000; configid < 0x80010800; configid += 0x100) { | ||
2640 | outl(configid, (unsigned long)0xCF8); | ||
2641 | deviceid = (inl((unsigned long)0xCFC) >> 16) & 0xffff; | ||
2642 | |||
2643 | switch (deviceid) { | ||
2644 | case CLE266: | ||
2645 | case KM400: | ||
2646 | outl(configid + 0xE0, (unsigned long)0xCF8); | ||
2647 | FBSize = inl((unsigned long)0xCFC); | ||
2648 | DeviceFound = true; /* Found device id */ | ||
2649 | break; | ||
2650 | |||
2651 | case CN400_FUNCTION3: | ||
2652 | case CN700_FUNCTION3: | ||
2653 | case CX700_FUNCTION3: | ||
2654 | case KM800_FUNCTION3: | ||
2655 | case KM890_FUNCTION3: | ||
2656 | case P4M890_FUNCTION3: | ||
2657 | case P4M900_FUNCTION3: | ||
2658 | case VX800_FUNCTION3: | ||
2659 | /*case CN750_FUNCTION3: */ | ||
2660 | outl(configid + 0xA0, (unsigned long)0xCF8); | ||
2661 | FBSize = inl((unsigned long)0xCFC); | ||
2662 | DeviceFound = true; /* Found device id */ | ||
2663 | break; | ||
2664 | |||
2665 | default: | ||
2666 | break; | ||
2667 | } | ||
2668 | |||
2669 | if (DeviceFound) | ||
2670 | break; | ||
2671 | } | ||
2672 | |||
2673 | DEBUG_MSG(KERN_INFO "Device ID = %lx\n", deviceid); | ||
2674 | |||
2675 | FBSize = FBSize & 0x00007000; | ||
2676 | DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize); | ||
2677 | |||
2678 | if (viaparinfo->chip_info->gfx_chip_name < UNICHROME_CX700) { | ||
2679 | switch (FBSize) { | ||
2680 | case 0x00004000: | ||
2681 | VideoMemSize = (16 << 20); /*16M */ | ||
2682 | break; | ||
2683 | |||
2684 | case 0x00005000: | ||
2685 | VideoMemSize = (32 << 20); /*32M */ | ||
2686 | break; | ||
2687 | |||
2688 | case 0x00006000: | ||
2689 | VideoMemSize = (64 << 20); /*64M */ | ||
2690 | break; | ||
2691 | |||
2692 | default: | ||
2693 | VideoMemSize = (32 << 20); /*32M */ | ||
2694 | break; | ||
2695 | } | ||
2696 | } else { | ||
2697 | switch (FBSize) { | ||
2698 | case 0x00001000: | ||
2699 | VideoMemSize = (8 << 20); /*8M */ | ||
2700 | break; | ||
2701 | |||
2702 | case 0x00002000: | ||
2703 | VideoMemSize = (16 << 20); /*16M */ | ||
2704 | break; | ||
2705 | |||
2706 | case 0x00003000: | ||
2707 | VideoMemSize = (32 << 20); /*32M */ | ||
2708 | break; | ||
2709 | |||
2710 | case 0x00004000: | ||
2711 | VideoMemSize = (64 << 20); /*64M */ | ||
2712 | break; | ||
2713 | |||
2714 | case 0x00005000: | ||
2715 | VideoMemSize = (128 << 20); /*128M */ | ||
2716 | break; | ||
2717 | |||
2718 | case 0x00006000: | ||
2719 | VideoMemSize = (256 << 20); /*256M */ | ||
2720 | break; | ||
2721 | |||
2722 | default: | ||
2723 | VideoMemSize = (32 << 20); /*32M */ | ||
2724 | break; | ||
2725 | } | ||
2726 | } | ||
2727 | |||
2728 | return VideoMemSize; | ||
2729 | } | ||
2730 | |||
2731 | void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ | ||
2732 | *p_gfx_dpa_setting) | ||
2733 | { | ||
2734 | switch (output_interface) { | ||
2735 | case INTERFACE_DVP0: | ||
2736 | { | ||
2737 | /* DVP0 Clock Polarity and Adjust: */ | ||
2738 | viafb_write_reg_mask(CR96, VIACR, | ||
2739 | p_gfx_dpa_setting->DVP0, 0x0F); | ||
2740 | |||
2741 | /* DVP0 Clock and Data Pads Driving: */ | ||
2742 | viafb_write_reg_mask(SR1E, VIASR, | ||
2743 | p_gfx_dpa_setting->DVP0ClockDri_S, BIT2); | ||
2744 | viafb_write_reg_mask(SR2A, VIASR, | ||
2745 | p_gfx_dpa_setting->DVP0ClockDri_S1, | ||
2746 | BIT4); | ||
2747 | viafb_write_reg_mask(SR1B, VIASR, | ||
2748 | p_gfx_dpa_setting->DVP0DataDri_S, BIT1); | ||
2749 | viafb_write_reg_mask(SR2A, VIASR, | ||
2750 | p_gfx_dpa_setting->DVP0DataDri_S1, BIT5); | ||
2751 | break; | ||
2752 | } | ||
2753 | |||
2754 | case INTERFACE_DVP1: | ||
2755 | { | ||
2756 | /* DVP1 Clock Polarity and Adjust: */ | ||
2757 | viafb_write_reg_mask(CR9B, VIACR, | ||
2758 | p_gfx_dpa_setting->DVP1, 0x0F); | ||
2759 | |||
2760 | /* DVP1 Clock and Data Pads Driving: */ | ||
2761 | viafb_write_reg_mask(SR65, VIASR, | ||
2762 | p_gfx_dpa_setting->DVP1Driving, 0x0F); | ||
2763 | break; | ||
2764 | } | ||
2765 | |||
2766 | case INTERFACE_DFP_HIGH: | ||
2767 | { | ||
2768 | viafb_write_reg_mask(CR97, VIACR, | ||
2769 | p_gfx_dpa_setting->DFPHigh, 0x0F); | ||
2770 | break; | ||
2771 | } | ||
2772 | |||
2773 | case INTERFACE_DFP_LOW: | ||
2774 | { | ||
2775 | viafb_write_reg_mask(CR99, VIACR, | ||
2776 | p_gfx_dpa_setting->DFPLow, 0x0F); | ||
2777 | break; | ||
2778 | } | ||
2779 | |||
2780 | case INTERFACE_DFP: | ||
2781 | { | ||
2782 | viafb_write_reg_mask(CR97, VIACR, | ||
2783 | p_gfx_dpa_setting->DFPHigh, 0x0F); | ||
2784 | viafb_write_reg_mask(CR99, VIACR, | ||
2785 | p_gfx_dpa_setting->DFPLow, 0x0F); | ||
2786 | break; | ||
2787 | } | ||
2788 | } | ||
2789 | } | ||
2790 | |||
2791 | void viafb_memory_pitch_patch(struct fb_info *info) | ||
2792 | { | ||
2793 | if (info->var.xres != info->var.xres_virtual) { | ||
2794 | viafb_load_offset_reg(info->var.xres_virtual, | ||
2795 | info->var.bits_per_pixel >> 3, IGA1); | ||
2796 | |||
2797 | if (viafb_SAMM_ON) { | ||
2798 | viafb_load_offset_reg(viafb_second_virtual_xres, | ||
2799 | viafb_bpp1 >> 3, | ||
2800 | IGA2); | ||
2801 | } else { | ||
2802 | viafb_load_offset_reg(info->var.xres_virtual, | ||
2803 | info->var.bits_per_pixel >> 3, IGA2); | ||
2804 | } | ||
2805 | |||
2806 | } | ||
2807 | } | ||
2808 | |||
2809 | /*According var's xres, yres fill var's other timing information*/ | ||
2810 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | ||
2811 | int mode_index) | ||
2812 | { | ||
2813 | struct VideoModeTable *vmode_tbl = NULL; | ||
2814 | struct crt_mode_table *crt_timing = NULL; | ||
2815 | struct display_timing crt_reg; | ||
2816 | int i = 0, index = 0; | ||
2817 | vmode_tbl = &CLE266Modes[search_mode_setting(mode_index)]; | ||
2818 | crt_timing = vmode_tbl->crtc; | ||
2819 | for (i = 0; i < vmode_tbl->mode_array; i++) { | ||
2820 | index = i; | ||
2821 | if (crt_timing[i].refresh_rate == refresh) | ||
2822 | break; | ||
2823 | } | ||
2824 | |||
2825 | crt_reg = crt_timing[index].crtc; | ||
2826 | switch (var->bits_per_pixel) { | ||
2827 | case 8: | ||
2828 | var->red.offset = 0; | ||
2829 | var->green.offset = 0; | ||
2830 | var->blue.offset = 0; | ||
2831 | var->red.length = 6; | ||
2832 | var->green.length = 6; | ||
2833 | var->blue.length = 6; | ||
2834 | break; | ||
2835 | case 16: | ||
2836 | var->red.offset = 11; | ||
2837 | var->green.offset = 5; | ||
2838 | var->blue.offset = 0; | ||
2839 | var->red.length = 5; | ||
2840 | var->green.length = 6; | ||
2841 | var->blue.length = 5; | ||
2842 | break; | ||
2843 | case 32: | ||
2844 | var->red.offset = 16; | ||
2845 | var->green.offset = 8; | ||
2846 | var->blue.offset = 0; | ||
2847 | var->red.length = 8; | ||
2848 | var->green.length = 8; | ||
2849 | var->blue.length = 8; | ||
2850 | break; | ||
2851 | default: | ||
2852 | /* never happed, put here to keep consistent */ | ||
2853 | break; | ||
2854 | } | ||
2855 | |||
2856 | var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh); | ||
2857 | var->left_margin = | ||
2858 | crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end); | ||
2859 | var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr; | ||
2860 | var->hsync_len = crt_reg.hor_sync_end; | ||
2861 | var->upper_margin = | ||
2862 | crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end); | ||
2863 | var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr; | ||
2864 | var->vsync_len = crt_reg.ver_sync_end; | ||
2865 | } | ||
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h new file mode 100644 index 000000000000..6ff38fa8569a --- /dev/null +++ b/drivers/video/via/hw.h | |||
@@ -0,0 +1,933 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __HW_H__ | ||
23 | #define __HW_H__ | ||
24 | |||
25 | #include "global.h" | ||
26 | |||
27 | /*************************************************** | ||
28 | * Definition IGA1 Design Method of CRTC Registers * | ||
29 | ****************************************************/ | ||
30 | #define IGA1_HOR_TOTAL_FORMULA(x) (((x)/8)-5) | ||
31 | #define IGA1_HOR_ADDR_FORMULA(x) (((x)/8)-1) | ||
32 | #define IGA1_HOR_BLANK_START_FORMULA(x) (((x)/8)-1) | ||
33 | #define IGA1_HOR_BLANK_END_FORMULA(x, y) (((x+y)/8)-1) | ||
34 | #define IGA1_HOR_SYNC_START_FORMULA(x) ((x)/8) | ||
35 | #define IGA1_HOR_SYNC_END_FORMULA(x, y) ((x+y)/8) | ||
36 | |||
37 | #define IGA1_VER_TOTAL_FORMULA(x) ((x)-2) | ||
38 | #define IGA1_VER_ADDR_FORMULA(x) ((x)-1) | ||
39 | #define IGA1_VER_BLANK_START_FORMULA(x) ((x)-1) | ||
40 | #define IGA1_VER_BLANK_END_FORMULA(x, y) ((x+y)-1) | ||
41 | #define IGA1_VER_SYNC_START_FORMULA(x) ((x)-1) | ||
42 | #define IGA1_VER_SYNC_END_FORMULA(x, y) ((x+y)-1) | ||
43 | |||
44 | /*************************************************** | ||
45 | ** Definition IGA2 Design Method of CRTC Registers * | ||
46 | ****************************************************/ | ||
47 | #define IGA2_HOR_TOTAL_FORMULA(x) ((x)-1) | ||
48 | #define IGA2_HOR_ADDR_FORMULA(x) ((x)-1) | ||
49 | #define IGA2_HOR_BLANK_START_FORMULA(x) ((x)-1) | ||
50 | #define IGA2_HOR_BLANK_END_FORMULA(x, y) ((x+y)-1) | ||
51 | #define IGA2_HOR_SYNC_START_FORMULA(x) ((x)-1) | ||
52 | #define IGA2_HOR_SYNC_END_FORMULA(x, y) ((x+y)-1) | ||
53 | |||
54 | #define IGA2_VER_TOTAL_FORMULA(x) ((x)-1) | ||
55 | #define IGA2_VER_ADDR_FORMULA(x) ((x)-1) | ||
56 | #define IGA2_VER_BLANK_START_FORMULA(x) ((x)-1) | ||
57 | #define IGA2_VER_BLANK_END_FORMULA(x, y) ((x+y)-1) | ||
58 | #define IGA2_VER_SYNC_START_FORMULA(x) ((x)-1) | ||
59 | #define IGA2_VER_SYNC_END_FORMULA(x, y) ((x+y)-1) | ||
60 | |||
61 | /**********************************************************/ | ||
62 | /* Definition IGA2 Design Method of CRTC Shadow Registers */ | ||
63 | /**********************************************************/ | ||
64 | #define IGA2_HOR_TOTAL_SHADOW_FORMULA(x) ((x/8)-5) | ||
65 | #define IGA2_HOR_BLANK_END_SHADOW_FORMULA(x, y) (((x+y)/8)-1) | ||
66 | #define IGA2_VER_TOTAL_SHADOW_FORMULA(x) ((x)-2) | ||
67 | #define IGA2_VER_ADDR_SHADOW_FORMULA(x) ((x)-1) | ||
68 | #define IGA2_VER_BLANK_START_SHADOW_FORMULA(x) ((x)-1) | ||
69 | #define IGA2_VER_BLANK_END_SHADOW_FORMULA(x, y) ((x+y)-1) | ||
70 | #define IGA2_VER_SYNC_START_SHADOW_FORMULA(x) (x) | ||
71 | #define IGA2_VER_SYNC_END_SHADOW_FORMULA(x, y) (x+y) | ||
72 | |||
73 | /* Define Register Number for IGA1 CRTC Timing */ | ||
74 | |||
75 | /* location: {CR00,0,7},{CR36,3,3} */ | ||
76 | #define IGA1_HOR_TOTAL_REG_NUM 2 | ||
77 | /* location: {CR01,0,7} */ | ||
78 | #define IGA1_HOR_ADDR_REG_NUM 1 | ||
79 | /* location: {CR02,0,7} */ | ||
80 | #define IGA1_HOR_BLANK_START_REG_NUM 1 | ||
81 | /* location: {CR03,0,4},{CR05,7,7},{CR33,5,5} */ | ||
82 | #define IGA1_HOR_BLANK_END_REG_NUM 3 | ||
83 | /* location: {CR04,0,7},{CR33,4,4} */ | ||
84 | #define IGA1_HOR_SYNC_START_REG_NUM 2 | ||
85 | /* location: {CR05,0,4} */ | ||
86 | #define IGA1_HOR_SYNC_END_REG_NUM 1 | ||
87 | /* location: {CR06,0,7},{CR07,0,0},{CR07,5,5},{CR35,0,0} */ | ||
88 | #define IGA1_VER_TOTAL_REG_NUM 4 | ||
89 | /* location: {CR12,0,7},{CR07,1,1},{CR07,6,6},{CR35,2,2} */ | ||
90 | #define IGA1_VER_ADDR_REG_NUM 4 | ||
91 | /* location: {CR15,0,7},{CR07,3,3},{CR09,5,5},{CR35,3,3} */ | ||
92 | #define IGA1_VER_BLANK_START_REG_NUM 4 | ||
93 | /* location: {CR16,0,7} */ | ||
94 | #define IGA1_VER_BLANK_END_REG_NUM 1 | ||
95 | /* location: {CR10,0,7},{CR07,2,2},{CR07,7,7},{CR35,1,1} */ | ||
96 | #define IGA1_VER_SYNC_START_REG_NUM 4 | ||
97 | /* location: {CR11,0,3} */ | ||
98 | #define IGA1_VER_SYNC_END_REG_NUM 1 | ||
99 | |||
100 | /* Define Register Number for IGA2 Shadow CRTC Timing */ | ||
101 | |||
102 | /* location: {CR6D,0,7},{CR71,3,3} */ | ||
103 | #define IGA2_SHADOW_HOR_TOTAL_REG_NUM 2 | ||
104 | /* location: {CR6E,0,7} */ | ||
105 | #define IGA2_SHADOW_HOR_BLANK_END_REG_NUM 1 | ||
106 | /* location: {CR6F,0,7},{CR71,0,2} */ | ||
107 | #define IGA2_SHADOW_VER_TOTAL_REG_NUM 2 | ||
108 | /* location: {CR70,0,7},{CR71,4,6} */ | ||
109 | #define IGA2_SHADOW_VER_ADDR_REG_NUM 2 | ||
110 | /* location: {CR72,0,7},{CR74,4,6} */ | ||
111 | #define IGA2_SHADOW_VER_BLANK_START_REG_NUM 2 | ||
112 | /* location: {CR73,0,7},{CR74,0,2} */ | ||
113 | #define IGA2_SHADOW_VER_BLANK_END_REG_NUM 2 | ||
114 | /* location: {CR75,0,7},{CR76,4,6} */ | ||
115 | #define IGA2_SHADOW_VER_SYNC_START_REG_NUM 2 | ||
116 | /* location: {CR76,0,3} */ | ||
117 | #define IGA2_SHADOW_VER_SYNC_END_REG_NUM 1 | ||
118 | |||
119 | /* Define Register Number for IGA2 CRTC Timing */ | ||
120 | |||
121 | /* location: {CR50,0,7},{CR55,0,3} */ | ||
122 | #define IGA2_HOR_TOTAL_REG_NUM 2 | ||
123 | /* location: {CR51,0,7},{CR55,4,6} */ | ||
124 | #define IGA2_HOR_ADDR_REG_NUM 2 | ||
125 | /* location: {CR52,0,7},{CR54,0,2} */ | ||
126 | #define IGA2_HOR_BLANK_START_REG_NUM 2 | ||
127 | /* location: CLE266: {CR53,0,7},{CR54,3,5} => CLE266's CR5D[6] | ||
128 | is reserved, so it may have problem to set 1600x1200 on IGA2. */ | ||
129 | /* Others: {CR53,0,7},{CR54,3,5},{CR5D,6,6} */ | ||
130 | #define IGA2_HOR_BLANK_END_REG_NUM 3 | ||
131 | /* location: {CR56,0,7},{CR54,6,7},{CR5C,7,7} */ | ||
132 | /* VT3314 and Later: {CR56,0,7},{CR54,6,7},{CR5C,7,7}, {CR5D,7,7} */ | ||
133 | #define IGA2_HOR_SYNC_START_REG_NUM 4 | ||
134 | |||
135 | /* location: {CR57,0,7},{CR5C,6,6} */ | ||
136 | #define IGA2_HOR_SYNC_END_REG_NUM 2 | ||
137 | /* location: {CR58,0,7},{CR5D,0,2} */ | ||
138 | #define IGA2_VER_TOTAL_REG_NUM 2 | ||
139 | /* location: {CR59,0,7},{CR5D,3,5} */ | ||
140 | #define IGA2_VER_ADDR_REG_NUM 2 | ||
141 | /* location: {CR5A,0,7},{CR5C,0,2} */ | ||
142 | #define IGA2_VER_BLANK_START_REG_NUM 2 | ||
143 | /* location: {CR5E,0,7},{CR5C,3,5} */ | ||
144 | #define IGA2_VER_BLANK_END_REG_NUM 2 | ||
145 | /* location: {CR5E,0,7},{CR5F,5,7} */ | ||
146 | #define IGA2_VER_SYNC_START_REG_NUM 2 | ||
147 | /* location: {CR5F,0,4} */ | ||
148 | #define IGA2_VER_SYNC_END_REG_NUM 1 | ||
149 | |||
150 | /* Define Offset and Fetch Count Register*/ | ||
151 | |||
152 | /* location: {CR13,0,7},{CR35,5,7} */ | ||
153 | #define IGA1_OFFSET_REG_NUM 2 | ||
154 | /* 8 bytes alignment. */ | ||
155 | #define IGA1_OFFSER_ALIGN_BYTE 8 | ||
156 | /* x: H resolution, y: color depth */ | ||
157 | #define IGA1_OFFSET_FORMULA(x, y) ((x*y)/IGA1_OFFSER_ALIGN_BYTE) | ||
158 | /* location: {SR1C,0,7},{SR1D,0,1} */ | ||
159 | #define IGA1_FETCH_COUNT_REG_NUM 2 | ||
160 | /* 16 bytes alignment. */ | ||
161 | #define IGA1_FETCH_COUNT_ALIGN_BYTE 16 | ||
162 | /* x: H resolution, y: color depth */ | ||
163 | #define IGA1_FETCH_COUNT_PATCH_VALUE 4 | ||
164 | #define IGA1_FETCH_COUNT_FORMULA(x, y) \ | ||
165 | (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE) | ||
166 | |||
167 | /* location: {CR66,0,7},{CR67,0,1} */ | ||
168 | #define IGA2_OFFSET_REG_NUM 2 | ||
169 | #define IGA2_OFFSET_ALIGN_BYTE 8 | ||
170 | /* x: H resolution, y: color depth */ | ||
171 | #define IGA2_OFFSET_FORMULA(x, y) ((x*y)/IGA2_OFFSET_ALIGN_BYTE) | ||
172 | /* location: {CR65,0,7},{CR67,2,3} */ | ||
173 | #define IGA2_FETCH_COUNT_REG_NUM 2 | ||
174 | #define IGA2_FETCH_COUNT_ALIGN_BYTE 16 | ||
175 | #define IGA2_FETCH_COUNT_PATCH_VALUE 0 | ||
176 | #define IGA2_FETCH_COUNT_FORMULA(x, y) \ | ||
177 | (((x*y)/IGA2_FETCH_COUNT_ALIGN_BYTE) + IGA2_FETCH_COUNT_PATCH_VALUE) | ||
178 | |||
179 | /* Staring Address*/ | ||
180 | |||
181 | /* location: {CR0C,0,7},{CR0D,0,7},{CR34,0,7},{CR48,0,1} */ | ||
182 | #define IGA1_STARTING_ADDR_REG_NUM 4 | ||
183 | /* location: {CR62,1,7},{CR63,0,7},{CR64,0,7} */ | ||
184 | #define IGA2_STARTING_ADDR_REG_NUM 3 | ||
185 | |||
186 | /* Define Display OFFSET*/ | ||
187 | /* These value are by HW suggested value*/ | ||
188 | /* location: {SR17,0,7} */ | ||
189 | #define K800_IGA1_FIFO_MAX_DEPTH 384 | ||
190 | /* location: {SR16,0,5},{SR16,7,7} */ | ||
191 | #define K800_IGA1_FIFO_THRESHOLD 328 | ||
192 | /* location: {SR18,0,5},{SR18,7,7} */ | ||
193 | #define K800_IGA1_FIFO_HIGH_THRESHOLD 296 | ||
194 | /* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */ | ||
195 | /* because HW only 5 bits */ | ||
196 | #define K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0 | ||
197 | |||
198 | /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ | ||
199 | #define K800_IGA2_FIFO_MAX_DEPTH 384 | ||
200 | /* location: {CR68,0,3},{CR95,4,6} */ | ||
201 | #define K800_IGA2_FIFO_THRESHOLD 328 | ||
202 | /* location: {CR92,0,3},{CR95,0,2} */ | ||
203 | #define K800_IGA2_FIFO_HIGH_THRESHOLD 296 | ||
204 | /* location: {CR94,0,6} */ | ||
205 | #define K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 | ||
206 | |||
207 | /* location: {SR17,0,7} */ | ||
208 | #define P880_IGA1_FIFO_MAX_DEPTH 192 | ||
209 | /* location: {SR16,0,5},{SR16,7,7} */ | ||
210 | #define P880_IGA1_FIFO_THRESHOLD 128 | ||
211 | /* location: {SR18,0,5},{SR18,7,7} */ | ||
212 | #define P880_IGA1_FIFO_HIGH_THRESHOLD 64 | ||
213 | /* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */ | ||
214 | /* because HW only 5 bits */ | ||
215 | #define P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0 | ||
216 | |||
217 | /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ | ||
218 | #define P880_IGA2_FIFO_MAX_DEPTH 96 | ||
219 | /* location: {CR68,0,3},{CR95,4,6} */ | ||
220 | #define P880_IGA2_FIFO_THRESHOLD 64 | ||
221 | /* location: {CR92,0,3},{CR95,0,2} */ | ||
222 | #define P880_IGA2_FIFO_HIGH_THRESHOLD 32 | ||
223 | /* location: {CR94,0,6} */ | ||
224 | #define P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 | ||
225 | |||
226 | /* VT3314 chipset*/ | ||
227 | |||
228 | /* location: {SR17,0,7} */ | ||
229 | #define CN700_IGA1_FIFO_MAX_DEPTH 96 | ||
230 | /* location: {SR16,0,5},{SR16,7,7} */ | ||
231 | #define CN700_IGA1_FIFO_THRESHOLD 80 | ||
232 | /* location: {SR18,0,5},{SR18,7,7} */ | ||
233 | #define CN700_IGA1_FIFO_HIGH_THRESHOLD 64 | ||
234 | /* location: {SR22,0,4}. (128/4) =64, P800 must be set zero, | ||
235 | because HW only 5 bits */ | ||
236 | #define CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0 | ||
237 | /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ | ||
238 | #define CN700_IGA2_FIFO_MAX_DEPTH 96 | ||
239 | /* location: {CR68,0,3},{CR95,4,6} */ | ||
240 | #define CN700_IGA2_FIFO_THRESHOLD 80 | ||
241 | /* location: {CR92,0,3},{CR95,0,2} */ | ||
242 | #define CN700_IGA2_FIFO_HIGH_THRESHOLD 32 | ||
243 | /* location: {CR94,0,6} */ | ||
244 | #define CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 | ||
245 | |||
246 | /* For VT3324, these values are suggested by HW */ | ||
247 | /* location: {SR17,0,7} */ | ||
248 | #define CX700_IGA1_FIFO_MAX_DEPTH 192 | ||
249 | /* location: {SR16,0,5},{SR16,7,7} */ | ||
250 | #define CX700_IGA1_FIFO_THRESHOLD 128 | ||
251 | /* location: {SR18,0,5},{SR18,7,7} */ | ||
252 | #define CX700_IGA1_FIFO_HIGH_THRESHOLD 128 | ||
253 | /* location: {SR22,0,4} */ | ||
254 | #define CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124 | ||
255 | |||
256 | /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ | ||
257 | #define CX700_IGA2_FIFO_MAX_DEPTH 96 | ||
258 | /* location: {CR68,0,3},{CR95,4,6} */ | ||
259 | #define CX700_IGA2_FIFO_THRESHOLD 64 | ||
260 | /* location: {CR92,0,3},{CR95,0,2} */ | ||
261 | #define CX700_IGA2_FIFO_HIGH_THRESHOLD 32 | ||
262 | /* location: {CR94,0,6} */ | ||
263 | #define CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 | ||
264 | |||
265 | /* VT3336 chipset*/ | ||
266 | /* location: {SR17,0,7} */ | ||
267 | #define K8M890_IGA1_FIFO_MAX_DEPTH 360 | ||
268 | /* location: {SR16,0,5},{SR16,7,7} */ | ||
269 | #define K8M890_IGA1_FIFO_THRESHOLD 328 | ||
270 | /* location: {SR18,0,5},{SR18,7,7} */ | ||
271 | #define K8M890_IGA1_FIFO_HIGH_THRESHOLD 296 | ||
272 | /* location: {SR22,0,4}. */ | ||
273 | #define K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124 | ||
274 | |||
275 | /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ | ||
276 | #define K8M890_IGA2_FIFO_MAX_DEPTH 360 | ||
277 | /* location: {CR68,0,3},{CR95,4,6} */ | ||
278 | #define K8M890_IGA2_FIFO_THRESHOLD 328 | ||
279 | /* location: {CR92,0,3},{CR95,0,2} */ | ||
280 | #define K8M890_IGA2_FIFO_HIGH_THRESHOLD 296 | ||
281 | /* location: {CR94,0,6} */ | ||
282 | #define K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 124 | ||
283 | |||
284 | /* VT3327 chipset*/ | ||
285 | /* location: {SR17,0,7} */ | ||
286 | #define P4M890_IGA1_FIFO_MAX_DEPTH 96 | ||
287 | /* location: {SR16,0,5},{SR16,7,7} */ | ||
288 | #define P4M890_IGA1_FIFO_THRESHOLD 76 | ||
289 | /* location: {SR18,0,5},{SR18,7,7} */ | ||
290 | #define P4M890_IGA1_FIFO_HIGH_THRESHOLD 64 | ||
291 | /* location: {SR22,0,4}. (32/4) =8 */ | ||
292 | #define P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32 | ||
293 | /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ | ||
294 | #define P4M890_IGA2_FIFO_MAX_DEPTH 96 | ||
295 | /* location: {CR68,0,3},{CR95,4,6} */ | ||
296 | #define P4M890_IGA2_FIFO_THRESHOLD 76 | ||
297 | /* location: {CR92,0,3},{CR95,0,2} */ | ||
298 | #define P4M890_IGA2_FIFO_HIGH_THRESHOLD 64 | ||
299 | /* location: {CR94,0,6} */ | ||
300 | #define P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32 | ||
301 | |||
302 | /* VT3364 chipset*/ | ||
303 | /* location: {SR17,0,7} */ | ||
304 | #define P4M900_IGA1_FIFO_MAX_DEPTH 96 | ||
305 | /* location: {SR16,0,5},{SR16,7,7} */ | ||
306 | #define P4M900_IGA1_FIFO_THRESHOLD 76 | ||
307 | /* location: {SR18,0,5},{SR18,7,7} */ | ||
308 | #define P4M900_IGA1_FIFO_HIGH_THRESHOLD 76 | ||
309 | /* location: {SR22,0,4}. */ | ||
310 | #define P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32 | ||
311 | /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ | ||
312 | #define P4M900_IGA2_FIFO_MAX_DEPTH 96 | ||
313 | /* location: {CR68,0,3},{CR95,4,6} */ | ||
314 | #define P4M900_IGA2_FIFO_THRESHOLD 76 | ||
315 | /* location: {CR92,0,3},{CR95,0,2} */ | ||
316 | #define P4M900_IGA2_FIFO_HIGH_THRESHOLD 76 | ||
317 | /* location: {CR94,0,6} */ | ||
318 | #define P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32 | ||
319 | |||
320 | /* For VT3353, these values are suggested by HW */ | ||
321 | /* location: {SR17,0,7} */ | ||
322 | #define VX800_IGA1_FIFO_MAX_DEPTH 192 | ||
323 | /* location: {SR16,0,5},{SR16,7,7} */ | ||
324 | #define VX800_IGA1_FIFO_THRESHOLD 152 | ||
325 | /* location: {SR18,0,5},{SR18,7,7} */ | ||
326 | #define VX800_IGA1_FIFO_HIGH_THRESHOLD 152 | ||
327 | /* location: {SR22,0,4} */ | ||
328 | #define VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 64 | ||
329 | /* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ | ||
330 | #define VX800_IGA2_FIFO_MAX_DEPTH 96 | ||
331 | /* location: {CR68,0,3},{CR95,4,6} */ | ||
332 | #define VX800_IGA2_FIFO_THRESHOLD 64 | ||
333 | /* location: {CR92,0,3},{CR95,0,2} */ | ||
334 | #define VX800_IGA2_FIFO_HIGH_THRESHOLD 32 | ||
335 | /* location: {CR94,0,6} */ | ||
336 | #define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128 | ||
337 | |||
338 | #define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1 | ||
339 | #define IGA1_FIFO_THRESHOLD_REG_NUM 2 | ||
340 | #define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2 | ||
341 | #define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1 | ||
342 | |||
343 | #define IGA2_FIFO_DEPTH_SELECT_REG_NUM 3 | ||
344 | #define IGA2_FIFO_THRESHOLD_REG_NUM 2 | ||
345 | #define IGA2_FIFO_HIGH_THRESHOLD_REG_NUM 2 | ||
346 | #define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1 | ||
347 | |||
348 | #define IGA1_FIFO_DEPTH_SELECT_FORMULA(x) ((x/2)-1) | ||
349 | #define IGA1_FIFO_THRESHOLD_FORMULA(x) (x/4) | ||
350 | #define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4) | ||
351 | #define IGA1_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4) | ||
352 | #define IGA2_FIFO_DEPTH_SELECT_FORMULA(x) (((x/2)/4)-1) | ||
353 | #define IGA2_FIFO_THRESHOLD_FORMULA(x) (x/4) | ||
354 | #define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4) | ||
355 | #define IGA2_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4) | ||
356 | |||
357 | /************************************************************************/ | ||
358 | /* LCD Timing */ | ||
359 | /************************************************************************/ | ||
360 | |||
361 | /* 500 ms = 500000 us */ | ||
362 | #define LCD_POWER_SEQ_TD0 500000 | ||
363 | /* 50 ms = 50000 us */ | ||
364 | #define LCD_POWER_SEQ_TD1 50000 | ||
365 | /* 0 us */ | ||
366 | #define LCD_POWER_SEQ_TD2 0 | ||
367 | /* 210 ms = 210000 us */ | ||
368 | #define LCD_POWER_SEQ_TD3 210000 | ||
369 | /* 2^10 * (1/14.31818M) = 71.475 us (K400.revA) */ | ||
370 | #define CLE266_POWER_SEQ_UNIT 71 | ||
371 | /* 2^11 * (1/14.31818M) = 142.95 us (K400.revB) */ | ||
372 | #define K800_POWER_SEQ_UNIT 142 | ||
373 | /* 2^13 * (1/14.31818M) = 572.1 us */ | ||
374 | #define P880_POWER_SEQ_UNIT 572 | ||
375 | |||
376 | #define CLE266_POWER_SEQ_FORMULA(x) ((x)/CLE266_POWER_SEQ_UNIT) | ||
377 | #define K800_POWER_SEQ_FORMULA(x) ((x)/K800_POWER_SEQ_UNIT) | ||
378 | #define P880_POWER_SEQ_FORMULA(x) ((x)/P880_POWER_SEQ_UNIT) | ||
379 | |||
380 | /* location: {CR8B,0,7},{CR8F,0,3} */ | ||
381 | #define LCD_POWER_SEQ_TD0_REG_NUM 2 | ||
382 | /* location: {CR8C,0,7},{CR8F,4,7} */ | ||
383 | #define LCD_POWER_SEQ_TD1_REG_NUM 2 | ||
384 | /* location: {CR8D,0,7},{CR90,0,3} */ | ||
385 | #define LCD_POWER_SEQ_TD2_REG_NUM 2 | ||
386 | /* location: {CR8E,0,7},{CR90,4,7} */ | ||
387 | #define LCD_POWER_SEQ_TD3_REG_NUM 2 | ||
388 | |||
389 | /* LCD Scaling factor*/ | ||
390 | /* x: indicate setting horizontal size*/ | ||
391 | /* y: indicate panel horizontal size*/ | ||
392 | |||
393 | /* Horizontal scaling factor 10 bits (2^10) */ | ||
394 | #define CLE266_LCD_HOR_SCF_FORMULA(x, y) (((x-1)*1024)/(y-1)) | ||
395 | /* Vertical scaling factor 10 bits (2^10) */ | ||
396 | #define CLE266_LCD_VER_SCF_FORMULA(x, y) (((x-1)*1024)/(y-1)) | ||
397 | /* Horizontal scaling factor 10 bits (2^12) */ | ||
398 | #define K800_LCD_HOR_SCF_FORMULA(x, y) (((x-1)*4096)/(y-1)) | ||
399 | /* Vertical scaling factor 10 bits (2^11) */ | ||
400 | #define K800_LCD_VER_SCF_FORMULA(x, y) (((x-1)*2048)/(y-1)) | ||
401 | |||
402 | /* location: {CR9F,0,1},{CR77,0,7},{CR79,4,5} */ | ||
403 | #define LCD_HOR_SCALING_FACTOR_REG_NUM 3 | ||
404 | /* location: {CR79,3,3},{CR78,0,7},{CR79,6,7} */ | ||
405 | #define LCD_VER_SCALING_FACTOR_REG_NUM 3 | ||
406 | /* location: {CR77,0,7},{CR79,4,5} */ | ||
407 | #define LCD_HOR_SCALING_FACTOR_REG_NUM_CLE 2 | ||
408 | /* location: {CR78,0,7},{CR79,6,7} */ | ||
409 | #define LCD_VER_SCALING_FACTOR_REG_NUM_CLE 2 | ||
410 | |||
411 | /************************************************ | ||
412 | ***** Define IGA1 Display Timing ***** | ||
413 | ************************************************/ | ||
414 | struct io_register { | ||
415 | u8 io_addr; | ||
416 | u8 start_bit; | ||
417 | u8 end_bit; | ||
418 | }; | ||
419 | |||
420 | /* IGA1 Horizontal Total */ | ||
421 | struct iga1_hor_total { | ||
422 | int reg_num; | ||
423 | struct io_register reg[IGA1_HOR_TOTAL_REG_NUM]; | ||
424 | }; | ||
425 | |||
426 | /* IGA1 Horizontal Addressable Video */ | ||
427 | struct iga1_hor_addr { | ||
428 | int reg_num; | ||
429 | struct io_register reg[IGA1_HOR_ADDR_REG_NUM]; | ||
430 | }; | ||
431 | |||
432 | /* IGA1 Horizontal Blank Start */ | ||
433 | struct iga1_hor_blank_start { | ||
434 | int reg_num; | ||
435 | struct io_register reg[IGA1_HOR_BLANK_START_REG_NUM]; | ||
436 | }; | ||
437 | |||
438 | /* IGA1 Horizontal Blank End */ | ||
439 | struct iga1_hor_blank_end { | ||
440 | int reg_num; | ||
441 | struct io_register reg[IGA1_HOR_BLANK_END_REG_NUM]; | ||
442 | }; | ||
443 | |||
444 | /* IGA1 Horizontal Sync Start */ | ||
445 | struct iga1_hor_sync_start { | ||
446 | int reg_num; | ||
447 | struct io_register reg[IGA1_HOR_SYNC_START_REG_NUM]; | ||
448 | }; | ||
449 | |||
450 | /* IGA1 Horizontal Sync End */ | ||
451 | struct iga1_hor_sync_end { | ||
452 | int reg_num; | ||
453 | struct io_register reg[IGA1_HOR_SYNC_END_REG_NUM]; | ||
454 | }; | ||
455 | |||
456 | /* IGA1 Vertical Total */ | ||
457 | struct iga1_ver_total { | ||
458 | int reg_num; | ||
459 | struct io_register reg[IGA1_VER_TOTAL_REG_NUM]; | ||
460 | }; | ||
461 | |||
462 | /* IGA1 Vertical Addressable Video */ | ||
463 | struct iga1_ver_addr { | ||
464 | int reg_num; | ||
465 | struct io_register reg[IGA1_VER_ADDR_REG_NUM]; | ||
466 | }; | ||
467 | |||
468 | /* IGA1 Vertical Blank Start */ | ||
469 | struct iga1_ver_blank_start { | ||
470 | int reg_num; | ||
471 | struct io_register reg[IGA1_VER_BLANK_START_REG_NUM]; | ||
472 | }; | ||
473 | |||
474 | /* IGA1 Vertical Blank End */ | ||
475 | struct iga1_ver_blank_end { | ||
476 | int reg_num; | ||
477 | struct io_register reg[IGA1_VER_BLANK_END_REG_NUM]; | ||
478 | }; | ||
479 | |||
480 | /* IGA1 Vertical Sync Start */ | ||
481 | struct iga1_ver_sync_start { | ||
482 | int reg_num; | ||
483 | struct io_register reg[IGA1_VER_SYNC_START_REG_NUM]; | ||
484 | }; | ||
485 | |||
486 | /* IGA1 Vertical Sync End */ | ||
487 | struct iga1_ver_sync_end { | ||
488 | int reg_num; | ||
489 | struct io_register reg[IGA1_VER_SYNC_END_REG_NUM]; | ||
490 | }; | ||
491 | |||
492 | /***************************************************** | ||
493 | ** Define IGA2 Shadow Display Timing **** | ||
494 | *****************************************************/ | ||
495 | |||
496 | /* IGA2 Shadow Horizontal Total */ | ||
497 | struct iga2_shadow_hor_total { | ||
498 | int reg_num; | ||
499 | struct io_register reg[IGA2_SHADOW_HOR_TOTAL_REG_NUM]; | ||
500 | }; | ||
501 | |||
502 | /* IGA2 Shadow Horizontal Blank End */ | ||
503 | struct iga2_shadow_hor_blank_end { | ||
504 | int reg_num; | ||
505 | struct io_register reg[IGA2_SHADOW_HOR_BLANK_END_REG_NUM]; | ||
506 | }; | ||
507 | |||
508 | /* IGA2 Shadow Vertical Total */ | ||
509 | struct iga2_shadow_ver_total { | ||
510 | int reg_num; | ||
511 | struct io_register reg[IGA2_SHADOW_VER_TOTAL_REG_NUM]; | ||
512 | }; | ||
513 | |||
514 | /* IGA2 Shadow Vertical Addressable Video */ | ||
515 | struct iga2_shadow_ver_addr { | ||
516 | int reg_num; | ||
517 | struct io_register reg[IGA2_SHADOW_VER_ADDR_REG_NUM]; | ||
518 | }; | ||
519 | |||
520 | /* IGA2 Shadow Vertical Blank Start */ | ||
521 | struct iga2_shadow_ver_blank_start { | ||
522 | int reg_num; | ||
523 | struct io_register reg[IGA2_SHADOW_VER_BLANK_START_REG_NUM]; | ||
524 | }; | ||
525 | |||
526 | /* IGA2 Shadow Vertical Blank End */ | ||
527 | struct iga2_shadow_ver_blank_end { | ||
528 | int reg_num; | ||
529 | struct io_register reg[IGA2_SHADOW_VER_BLANK_END_REG_NUM]; | ||
530 | }; | ||
531 | |||
532 | /* IGA2 Shadow Vertical Sync Start */ | ||
533 | struct iga2_shadow_ver_sync_start { | ||
534 | int reg_num; | ||
535 | struct io_register reg[IGA2_SHADOW_VER_SYNC_START_REG_NUM]; | ||
536 | }; | ||
537 | |||
538 | /* IGA2 Shadow Vertical Sync End */ | ||
539 | struct iga2_shadow_ver_sync_end { | ||
540 | int reg_num; | ||
541 | struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM]; | ||
542 | }; | ||
543 | |||
544 | /***************************************************** | ||
545 | ** Define IGA2 Display Timing **** | ||
546 | ******************************************************/ | ||
547 | |||
548 | /* IGA2 Horizontal Total */ | ||
549 | struct iga2_hor_total { | ||
550 | int reg_num; | ||
551 | struct io_register reg[IGA2_HOR_TOTAL_REG_NUM]; | ||
552 | }; | ||
553 | |||
554 | /* IGA2 Horizontal Addressable Video */ | ||
555 | struct iga2_hor_addr { | ||
556 | int reg_num; | ||
557 | struct io_register reg[IGA2_HOR_ADDR_REG_NUM]; | ||
558 | }; | ||
559 | |||
560 | /* IGA2 Horizontal Blank Start */ | ||
561 | struct iga2_hor_blank_start { | ||
562 | int reg_num; | ||
563 | struct io_register reg[IGA2_HOR_BLANK_START_REG_NUM]; | ||
564 | }; | ||
565 | |||
566 | /* IGA2 Horizontal Blank End */ | ||
567 | struct iga2_hor_blank_end { | ||
568 | int reg_num; | ||
569 | struct io_register reg[IGA2_HOR_BLANK_END_REG_NUM]; | ||
570 | }; | ||
571 | |||
572 | /* IGA2 Horizontal Sync Start */ | ||
573 | struct iga2_hor_sync_start { | ||
574 | int reg_num; | ||
575 | struct io_register reg[IGA2_HOR_SYNC_START_REG_NUM]; | ||
576 | }; | ||
577 | |||
578 | /* IGA2 Horizontal Sync End */ | ||
579 | struct iga2_hor_sync_end { | ||
580 | int reg_num; | ||
581 | struct io_register reg[IGA2_HOR_SYNC_END_REG_NUM]; | ||
582 | }; | ||
583 | |||
584 | /* IGA2 Vertical Total */ | ||
585 | struct iga2_ver_total { | ||
586 | int reg_num; | ||
587 | struct io_register reg[IGA2_VER_TOTAL_REG_NUM]; | ||
588 | }; | ||
589 | |||
590 | /* IGA2 Vertical Addressable Video */ | ||
591 | struct iga2_ver_addr { | ||
592 | int reg_num; | ||
593 | struct io_register reg[IGA2_VER_ADDR_REG_NUM]; | ||
594 | }; | ||
595 | |||
596 | /* IGA2 Vertical Blank Start */ | ||
597 | struct iga2_ver_blank_start { | ||
598 | int reg_num; | ||
599 | struct io_register reg[IGA2_VER_BLANK_START_REG_NUM]; | ||
600 | }; | ||
601 | |||
602 | /* IGA2 Vertical Blank End */ | ||
603 | struct iga2_ver_blank_end { | ||
604 | int reg_num; | ||
605 | struct io_register reg[IGA2_VER_BLANK_END_REG_NUM]; | ||
606 | }; | ||
607 | |||
608 | /* IGA2 Vertical Sync Start */ | ||
609 | struct iga2_ver_sync_start { | ||
610 | int reg_num; | ||
611 | struct io_register reg[IGA2_VER_SYNC_START_REG_NUM]; | ||
612 | }; | ||
613 | |||
614 | /* IGA2 Vertical Sync End */ | ||
615 | struct iga2_ver_sync_end { | ||
616 | int reg_num; | ||
617 | struct io_register reg[IGA2_VER_SYNC_END_REG_NUM]; | ||
618 | }; | ||
619 | |||
620 | /* IGA1 Offset Register */ | ||
621 | struct iga1_offset { | ||
622 | int reg_num; | ||
623 | struct io_register reg[IGA1_OFFSET_REG_NUM]; | ||
624 | }; | ||
625 | |||
626 | /* IGA2 Offset Register */ | ||
627 | struct iga2_offset { | ||
628 | int reg_num; | ||
629 | struct io_register reg[IGA2_OFFSET_REG_NUM]; | ||
630 | }; | ||
631 | |||
632 | struct offset { | ||
633 | struct iga1_offset iga1_offset_reg; | ||
634 | struct iga2_offset iga2_offset_reg; | ||
635 | }; | ||
636 | |||
637 | /* IGA1 Fetch Count Register */ | ||
638 | struct iga1_fetch_count { | ||
639 | int reg_num; | ||
640 | struct io_register reg[IGA1_FETCH_COUNT_REG_NUM]; | ||
641 | }; | ||
642 | |||
643 | /* IGA2 Fetch Count Register */ | ||
644 | struct iga2_fetch_count { | ||
645 | int reg_num; | ||
646 | struct io_register reg[IGA2_FETCH_COUNT_REG_NUM]; | ||
647 | }; | ||
648 | |||
649 | struct fetch_count { | ||
650 | struct iga1_fetch_count iga1_fetch_count_reg; | ||
651 | struct iga2_fetch_count iga2_fetch_count_reg; | ||
652 | }; | ||
653 | |||
654 | /* Starting Address Register */ | ||
655 | struct iga1_starting_addr { | ||
656 | int reg_num; | ||
657 | struct io_register reg[IGA1_STARTING_ADDR_REG_NUM]; | ||
658 | }; | ||
659 | |||
660 | struct iga2_starting_addr { | ||
661 | int reg_num; | ||
662 | struct io_register reg[IGA2_STARTING_ADDR_REG_NUM]; | ||
663 | }; | ||
664 | |||
665 | struct starting_addr { | ||
666 | struct iga1_starting_addr iga1_starting_addr_reg; | ||
667 | struct iga2_starting_addr iga2_starting_addr_reg; | ||
668 | }; | ||
669 | |||
670 | /* LCD Power Sequence Timer */ | ||
671 | struct lcd_pwd_seq_td0 { | ||
672 | int reg_num; | ||
673 | struct io_register reg[LCD_POWER_SEQ_TD0_REG_NUM]; | ||
674 | }; | ||
675 | |||
676 | struct lcd_pwd_seq_td1 { | ||
677 | int reg_num; | ||
678 | struct io_register reg[LCD_POWER_SEQ_TD1_REG_NUM]; | ||
679 | }; | ||
680 | |||
681 | struct lcd_pwd_seq_td2 { | ||
682 | int reg_num; | ||
683 | struct io_register reg[LCD_POWER_SEQ_TD2_REG_NUM]; | ||
684 | }; | ||
685 | |||
686 | struct lcd_pwd_seq_td3 { | ||
687 | int reg_num; | ||
688 | struct io_register reg[LCD_POWER_SEQ_TD3_REG_NUM]; | ||
689 | }; | ||
690 | |||
691 | struct _lcd_pwd_seq_timer { | ||
692 | struct lcd_pwd_seq_td0 td0; | ||
693 | struct lcd_pwd_seq_td1 td1; | ||
694 | struct lcd_pwd_seq_td2 td2; | ||
695 | struct lcd_pwd_seq_td3 td3; | ||
696 | }; | ||
697 | |||
698 | /* LCD Scaling Factor */ | ||
699 | struct _lcd_hor_scaling_factor { | ||
700 | int reg_num; | ||
701 | struct io_register reg[LCD_HOR_SCALING_FACTOR_REG_NUM]; | ||
702 | }; | ||
703 | |||
704 | struct _lcd_ver_scaling_factor { | ||
705 | int reg_num; | ||
706 | struct io_register reg[LCD_VER_SCALING_FACTOR_REG_NUM]; | ||
707 | }; | ||
708 | |||
709 | struct _lcd_scaling_factor { | ||
710 | struct _lcd_hor_scaling_factor lcd_hor_scaling_factor; | ||
711 | struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; | ||
712 | }; | ||
713 | |||
714 | struct pll_map { | ||
715 | u32 clk; | ||
716 | u32 cle266_pll; | ||
717 | u32 k800_pll; | ||
718 | u32 cx700_pll; | ||
719 | }; | ||
720 | |||
721 | struct rgbLUT { | ||
722 | u8 red; | ||
723 | u8 green; | ||
724 | u8 blue; | ||
725 | }; | ||
726 | |||
727 | struct lcd_pwd_seq_timer { | ||
728 | u16 td0; | ||
729 | u16 td1; | ||
730 | u16 td2; | ||
731 | u16 td3; | ||
732 | }; | ||
733 | |||
734 | /* Display FIFO Relation Registers*/ | ||
735 | struct iga1_fifo_depth_select { | ||
736 | int reg_num; | ||
737 | struct io_register reg[IGA1_FIFO_DEPTH_SELECT_REG_NUM]; | ||
738 | }; | ||
739 | |||
740 | struct iga1_fifo_threshold_select { | ||
741 | int reg_num; | ||
742 | struct io_register reg[IGA1_FIFO_THRESHOLD_REG_NUM]; | ||
743 | }; | ||
744 | |||
745 | struct iga1_fifo_high_threshold_select { | ||
746 | int reg_num; | ||
747 | struct io_register reg[IGA1_FIFO_HIGH_THRESHOLD_REG_NUM]; | ||
748 | }; | ||
749 | |||
750 | struct iga1_display_queue_expire_num { | ||
751 | int reg_num; | ||
752 | struct io_register reg[IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM]; | ||
753 | }; | ||
754 | |||
755 | struct iga2_fifo_depth_select { | ||
756 | int reg_num; | ||
757 | struct io_register reg[IGA2_FIFO_DEPTH_SELECT_REG_NUM]; | ||
758 | }; | ||
759 | |||
760 | struct iga2_fifo_threshold_select { | ||
761 | int reg_num; | ||
762 | struct io_register reg[IGA2_FIFO_THRESHOLD_REG_NUM]; | ||
763 | }; | ||
764 | |||
765 | struct iga2_fifo_high_threshold_select { | ||
766 | int reg_num; | ||
767 | struct io_register reg[IGA2_FIFO_HIGH_THRESHOLD_REG_NUM]; | ||
768 | }; | ||
769 | |||
770 | struct iga2_display_queue_expire_num { | ||
771 | int reg_num; | ||
772 | struct io_register reg[IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM]; | ||
773 | }; | ||
774 | |||
775 | struct fifo_depth_select { | ||
776 | struct iga1_fifo_depth_select iga1_fifo_depth_select_reg; | ||
777 | struct iga2_fifo_depth_select iga2_fifo_depth_select_reg; | ||
778 | }; | ||
779 | |||
780 | struct fifo_threshold_select { | ||
781 | struct iga1_fifo_threshold_select iga1_fifo_threshold_select_reg; | ||
782 | struct iga2_fifo_threshold_select iga2_fifo_threshold_select_reg; | ||
783 | }; | ||
784 | |||
785 | struct fifo_high_threshold_select { | ||
786 | struct iga1_fifo_high_threshold_select | ||
787 | iga1_fifo_high_threshold_select_reg; | ||
788 | struct iga2_fifo_high_threshold_select | ||
789 | iga2_fifo_high_threshold_select_reg; | ||
790 | }; | ||
791 | |||
792 | struct display_queue_expire_num { | ||
793 | struct iga1_display_queue_expire_num | ||
794 | iga1_display_queue_expire_num_reg; | ||
795 | struct iga2_display_queue_expire_num | ||
796 | iga2_display_queue_expire_num_reg; | ||
797 | }; | ||
798 | |||
799 | struct iga1_crtc_timing { | ||
800 | struct iga1_hor_total hor_total; | ||
801 | struct iga1_hor_addr hor_addr; | ||
802 | struct iga1_hor_blank_start hor_blank_start; | ||
803 | struct iga1_hor_blank_end hor_blank_end; | ||
804 | struct iga1_hor_sync_start hor_sync_start; | ||
805 | struct iga1_hor_sync_end hor_sync_end; | ||
806 | struct iga1_ver_total ver_total; | ||
807 | struct iga1_ver_addr ver_addr; | ||
808 | struct iga1_ver_blank_start ver_blank_start; | ||
809 | struct iga1_ver_blank_end ver_blank_end; | ||
810 | struct iga1_ver_sync_start ver_sync_start; | ||
811 | struct iga1_ver_sync_end ver_sync_end; | ||
812 | }; | ||
813 | |||
814 | struct iga2_shadow_crtc_timing { | ||
815 | struct iga2_shadow_hor_total hor_total_shadow; | ||
816 | struct iga2_shadow_hor_blank_end hor_blank_end_shadow; | ||
817 | struct iga2_shadow_ver_total ver_total_shadow; | ||
818 | struct iga2_shadow_ver_addr ver_addr_shadow; | ||
819 | struct iga2_shadow_ver_blank_start ver_blank_start_shadow; | ||
820 | struct iga2_shadow_ver_blank_end ver_blank_end_shadow; | ||
821 | struct iga2_shadow_ver_sync_start ver_sync_start_shadow; | ||
822 | struct iga2_shadow_ver_sync_end ver_sync_end_shadow; | ||
823 | }; | ||
824 | |||
825 | struct iga2_crtc_timing { | ||
826 | struct iga2_hor_total hor_total; | ||
827 | struct iga2_hor_addr hor_addr; | ||
828 | struct iga2_hor_blank_start hor_blank_start; | ||
829 | struct iga2_hor_blank_end hor_blank_end; | ||
830 | struct iga2_hor_sync_start hor_sync_start; | ||
831 | struct iga2_hor_sync_end hor_sync_end; | ||
832 | struct iga2_ver_total ver_total; | ||
833 | struct iga2_ver_addr ver_addr; | ||
834 | struct iga2_ver_blank_start ver_blank_start; | ||
835 | struct iga2_ver_blank_end ver_blank_end; | ||
836 | struct iga2_ver_sync_start ver_sync_start; | ||
837 | struct iga2_ver_sync_end ver_sync_end; | ||
838 | }; | ||
839 | |||
840 | /* device ID */ | ||
841 | #define CLE266 0x3123 | ||
842 | #define KM400 0x3205 | ||
843 | #define CN400_FUNCTION2 0x2259 | ||
844 | #define CN400_FUNCTION3 0x3259 | ||
845 | /* support VT3314 chipset */ | ||
846 | #define CN700_FUNCTION2 0x2314 | ||
847 | #define CN700_FUNCTION3 0x3208 | ||
848 | /* VT3324 chipset */ | ||
849 | #define CX700_FUNCTION2 0x2324 | ||
850 | #define CX700_FUNCTION3 0x3324 | ||
851 | /* VT3204 chipset*/ | ||
852 | #define KM800_FUNCTION3 0x3204 | ||
853 | /* VT3336 chipset*/ | ||
854 | #define KM890_FUNCTION3 0x3336 | ||
855 | /* VT3327 chipset*/ | ||
856 | #define P4M890_FUNCTION3 0x3327 | ||
857 | /* VT3293 chipset*/ | ||
858 | #define CN750_FUNCTION3 0x3208 | ||
859 | /* VT3364 chipset*/ | ||
860 | #define P4M900_FUNCTION3 0x3364 | ||
861 | /* VT3353 chipset*/ | ||
862 | #define VX800_FUNCTION3 0x3353 | ||
863 | |||
864 | #define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) | ||
865 | |||
866 | struct IODATA { | ||
867 | u8 Index; | ||
868 | u8 Mask; | ||
869 | u8 Data; | ||
870 | }; | ||
871 | |||
872 | struct pci_device_id_info { | ||
873 | u32 vendor; | ||
874 | u32 device; | ||
875 | u32 chip_index; | ||
876 | }; | ||
877 | |||
878 | extern unsigned int viafb_second_virtual_xres; | ||
879 | extern unsigned int viafb_second_offset; | ||
880 | extern int viafb_second_size; | ||
881 | extern int viafb_SAMM_ON; | ||
882 | extern int viafb_dual_fb; | ||
883 | extern int viafb_LCD2_ON; | ||
884 | extern int viafb_LCD_ON; | ||
885 | extern int viafb_DVI_ON; | ||
886 | extern int viafb_accel; | ||
887 | extern int viafb_hotplug; | ||
888 | |||
889 | void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask); | ||
890 | void viafb_set_output_path(int device, int set_iga, | ||
891 | int output_interface); | ||
892 | void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | ||
893 | int mode_index, int bpp_byte, int set_iga); | ||
894 | |||
895 | void viafb_set_vclock(u32 CLK, int set_iga); | ||
896 | void viafb_load_reg(int timing_value, int viafb_load_reg_num, | ||
897 | struct io_register *reg, | ||
898 | int io_type); | ||
899 | void viafb_crt_disable(void); | ||
900 | void viafb_crt_enable(void); | ||
901 | void init_ad9389(void); | ||
902 | /* Access I/O Function */ | ||
903 | void viafb_write_reg(u8 index, u16 io_port, u8 data); | ||
904 | u8 viafb_read_reg(int io_port, u8 index); | ||
905 | void viafb_lock_crt(void); | ||
906 | void viafb_unlock_crt(void); | ||
907 | void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga); | ||
908 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); | ||
909 | void viafb_write_regx(struct io_reg RegTable[], int ItemNum); | ||
910 | struct VideoModeTable *viafb_get_modetbl_pointer(int Index); | ||
911 | u32 viafb_get_clk_value(int clk); | ||
912 | void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); | ||
913 | void viafb_set_color_depth(int bpp_byte, int set_iga); | ||
914 | void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ | ||
915 | *p_gfx_dpa_setting); | ||
916 | |||
917 | int viafb_setmode(int vmode_index, int hor_res, int ver_res, | ||
918 | int video_bpp, int vmode_index1, int hor_res1, | ||
919 | int ver_res1, int video_bpp1); | ||
920 | void viafb_init_chip_info(void); | ||
921 | void viafb_init_dac(int set_iga); | ||
922 | int viafb_get_pixclock(int hres, int vres, int vmode_refresh); | ||
923 | int viafb_get_refresh(int hres, int vres, u32 float_refresh); | ||
924 | void viafb_update_device_setting(int hres, int vres, int bpp, | ||
925 | int vmode_refresh, int flag); | ||
926 | void viafb_get_mmio_info(unsigned long *mmio_base, | ||
927 | unsigned long *mmio_len); | ||
928 | |||
929 | void viafb_set_iga_path(void); | ||
930 | void viafb_set_start_addr(void); | ||
931 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); | ||
932 | |||
933 | #endif /* __HW_H__ */ | ||
diff --git a/drivers/video/via/iface.c b/drivers/video/via/iface.c new file mode 100644 index 000000000000..1570636c8d51 --- /dev/null +++ b/drivers/video/via/iface.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | |||
24 | /* Get frame buffer size from VGA BIOS */ | ||
25 | |||
26 | unsigned int viafb_get_memsize(void) | ||
27 | { | ||
28 | unsigned int m; | ||
29 | |||
30 | /* If memory size provided by user */ | ||
31 | if (viafb_memsize) | ||
32 | m = viafb_memsize * Mb; | ||
33 | else { | ||
34 | m = (unsigned int)viafb_read_reg(VIASR, SR39); | ||
35 | m = m * (4 * Mb); | ||
36 | |||
37 | if ((m < (16 * Mb)) || (m > (64 * Mb))) | ||
38 | m = 16 * Mb; | ||
39 | } | ||
40 | DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m / Mb); | ||
41 | return m; | ||
42 | } | ||
43 | |||
44 | /* Get Video Buffer Starting Physical Address(back door)*/ | ||
45 | |||
46 | unsigned long viafb_get_videobuf_addr(void) | ||
47 | { | ||
48 | struct pci_dev *pdev = NULL; | ||
49 | unsigned char sys_mem; | ||
50 | unsigned char video_mem; | ||
51 | unsigned long sys_mem_size; | ||
52 | unsigned long video_mem_size; | ||
53 | /*system memory = 256 MB, video memory 64 MB */ | ||
54 | unsigned long vmem_starting_adr = 0x0C000000; | ||
55 | |||
56 | pdev = | ||
57 | (struct pci_dev *)pci_get_device(VIA_K800_BRIDGE_VID, | ||
58 | VIA_K800_BRIDGE_DID, NULL); | ||
59 | if (pdev != NULL) { | ||
60 | pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG, | ||
61 | &sys_mem); | ||
62 | pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG, | ||
63 | &video_mem); | ||
64 | video_mem = (video_mem & 0x70) >> 4; | ||
65 | sys_mem_size = ((unsigned long)sys_mem) << 24; | ||
66 | if (video_mem != 0) | ||
67 | video_mem_size = (1 << (video_mem)) * 1024 * 1024; | ||
68 | else | ||
69 | video_mem_size = 0; | ||
70 | |||
71 | vmem_starting_adr = sys_mem_size - video_mem_size; | ||
72 | pci_dev_put(pdev); | ||
73 | } | ||
74 | |||
75 | DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n", | ||
76 | vmem_starting_adr); | ||
77 | return vmem_starting_adr; | ||
78 | } | ||
diff --git a/drivers/video/via/iface.h b/drivers/video/via/iface.h new file mode 100644 index 000000000000..790ec3e3aea2 --- /dev/null +++ b/drivers/video/via/iface.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __IFACE_H__ | ||
23 | #define __IFACE_H__ | ||
24 | |||
25 | #define Kb (1024) | ||
26 | #define Mb (Kb*Kb) | ||
27 | |||
28 | #define VIA_K800_BRIDGE_VID 0x1106 | ||
29 | #define VIA_K800_BRIDGE_DID 0x3204 | ||
30 | |||
31 | #define VIA_K800_SYSTEM_MEMORY_REG 0x47 | ||
32 | #define VIA_K800_VIDEO_MEMORY_REG 0xA1 | ||
33 | |||
34 | extern int viafb_memsize; | ||
35 | unsigned int viafb_get_memsize(void); | ||
36 | unsigned long viafb_get_videobuf_addr(void); | ||
37 | |||
38 | #endif /* __IFACE_H__ */ | ||
diff --git a/drivers/video/via/ioctl.c b/drivers/video/via/ioctl.c new file mode 100644 index 000000000000..da03c074e32a --- /dev/null +++ b/drivers/video/via/ioctl.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | |||
24 | int viafb_ioctl_get_viafb_info(u_long arg) | ||
25 | { | ||
26 | struct viafb_ioctl_info viainfo; | ||
27 | |||
28 | viainfo.viafb_id = VIAID; | ||
29 | viainfo.vendor_id = PCI_VIA_VENDOR_ID; | ||
30 | |||
31 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
32 | case UNICHROME_CLE266: | ||
33 | viainfo.device_id = UNICHROME_CLE266_DID; | ||
34 | break; | ||
35 | |||
36 | case UNICHROME_K400: | ||
37 | viainfo.device_id = UNICHROME_K400_DID; | ||
38 | break; | ||
39 | |||
40 | case UNICHROME_K800: | ||
41 | viainfo.device_id = UNICHROME_K800_DID; | ||
42 | break; | ||
43 | |||
44 | case UNICHROME_PM800: | ||
45 | viainfo.device_id = UNICHROME_PM800_DID; | ||
46 | break; | ||
47 | |||
48 | case UNICHROME_CN700: | ||
49 | viainfo.device_id = UNICHROME_CN700_DID; | ||
50 | break; | ||
51 | |||
52 | case UNICHROME_CX700: | ||
53 | viainfo.device_id = UNICHROME_CX700_DID; | ||
54 | break; | ||
55 | |||
56 | case UNICHROME_K8M890: | ||
57 | viainfo.device_id = UNICHROME_K8M890_DID; | ||
58 | break; | ||
59 | |||
60 | case UNICHROME_P4M890: | ||
61 | viainfo.device_id = UNICHROME_P4M890_DID; | ||
62 | break; | ||
63 | |||
64 | case UNICHROME_P4M900: | ||
65 | viainfo.device_id = UNICHROME_P4M900_DID; | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | viainfo.version = VERSION_MAJOR; | ||
70 | viainfo.revision = VERSION_MINOR; | ||
71 | |||
72 | if (copy_to_user((void __user *)arg, &viainfo, sizeof(viainfo))) | ||
73 | return -EFAULT; | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | /* Hot-Plug Priority: DVI > CRT*/ | ||
79 | int viafb_ioctl_hotplug(int hres, int vres, int bpp) | ||
80 | { | ||
81 | int DVIsense, status = 0; | ||
82 | DEBUG_MSG(KERN_INFO "viafb_ioctl_hotplug!!\n"); | ||
83 | |||
84 | if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name != | ||
85 | NON_TMDS_TRANSMITTER) { | ||
86 | DVIsense = viafb_dvi_sense(); | ||
87 | |||
88 | if (DVIsense) { | ||
89 | DEBUG_MSG(KERN_INFO "DVI Attached...\n"); | ||
90 | if (viafb_DeviceStatus != DVI_Device) { | ||
91 | viafb_DVI_ON = 1; | ||
92 | viafb_CRT_ON = 0; | ||
93 | viafb_LCD_ON = 0; | ||
94 | viafb_DeviceStatus = DVI_Device; | ||
95 | return viafb_DeviceStatus; | ||
96 | } | ||
97 | status = 1; | ||
98 | } else | ||
99 | DEBUG_MSG(KERN_INFO "DVI De-attached...\n"); | ||
100 | } | ||
101 | |||
102 | if ((viafb_DeviceStatus != CRT_Device) && (status == 0)) { | ||
103 | viafb_CRT_ON = 1; | ||
104 | viafb_DVI_ON = 0; | ||
105 | viafb_LCD_ON = 0; | ||
106 | |||
107 | viafb_DeviceStatus = CRT_Device; | ||
108 | return viafb_DeviceStatus; | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h new file mode 100644 index 000000000000..842fe30b9868 --- /dev/null +++ b/drivers/video/via/ioctl.h | |||
@@ -0,0 +1,210 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __IOCTL_H__ | ||
23 | #define __IOCTL_H__ | ||
24 | |||
25 | #ifndef __user | ||
26 | #define __user | ||
27 | #endif | ||
28 | |||
29 | /* VIAFB IOCTL definition */ | ||
30 | #define VIAFB_GET_INFO_SIZE 0x56494101 /* 'VIA\01' */ | ||
31 | #define VIAFB_GET_INFO 0x56494102 /* 'VIA\02' */ | ||
32 | #define VIAFB_HOTPLUG 0x56494103 /* 'VIA\03' */ | ||
33 | #define VIAFB_SET_HOTPLUG_FLAG 0x56494104 /* 'VIA\04' */ | ||
34 | #define VIAFB_GET_RESOLUTION 0x56494105 /* 'VIA\05' */ | ||
35 | #define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */ | ||
36 | #define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */ | ||
37 | #define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */ | ||
38 | #define VIAFB_SET_DEVICE 0x5649410A | ||
39 | #define VIAFB_GET_DEVICE 0x5649410B | ||
40 | #define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */ | ||
41 | #define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */ | ||
42 | #define VIAFB_SET_DEVICE_INFO 0x56494114 | ||
43 | #define VIAFB_GET_DEVICE_INFO 0x56494115 | ||
44 | |||
45 | #define VIAFB_GET_DEVICE_SUPPORT 0x56494118 | ||
46 | #define VIAFB_GET_DEVICE_CONNECT 0x56494119 | ||
47 | #define VIAFB_GET_PANEL_SUPPORT_EXPAND 0x5649411A | ||
48 | #define VIAFB_GET_DRIVER_NAME 0x56494122 | ||
49 | #define VIAFB_GET_DEVICE_SUPPORT_STATE 0x56494123 | ||
50 | #define VIAFB_GET_GAMMA_LUT 0x56494124 | ||
51 | #define VIAFB_SET_GAMMA_LUT 0x56494125 | ||
52 | #define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126 | ||
53 | #define VIAFB_SET_VIDEO_DEVICE 0x56494127 | ||
54 | #define VIAFB_GET_VIDEO_DEVICE 0x56494128 | ||
55 | #define VIAFB_SET_SECOND_MODE 0x56494129 | ||
56 | #define VIAFB_SYNC_SURFACE 0x56494130 | ||
57 | #define VIAFB_GET_DRIVER_CAPS 0x56494131 | ||
58 | #define VIAFB_GET_IGA_SCALING_INFO 0x56494132 | ||
59 | #define VIAFB_GET_PANEL_MAX_SIZE 0x56494133 | ||
60 | #define VIAFB_GET_PANEL_MAX_POSITION 0x56494134 | ||
61 | #define VIAFB_SET_PANEL_SIZE 0x56494135 | ||
62 | #define VIAFB_SET_PANEL_POSITION 0x56494136 | ||
63 | #define VIAFB_GET_PANEL_POSITION 0x56494137 | ||
64 | #define VIAFB_GET_PANEL_SIZE 0x56494138 | ||
65 | |||
66 | #define None_Device 0x00 | ||
67 | #define CRT_Device 0x01 | ||
68 | #define LCD_Device 0x02 | ||
69 | #define DVI_Device 0x08 | ||
70 | #define CRT2_Device 0x10 | ||
71 | #define LCD2_Device 0x40 | ||
72 | |||
73 | #define OP_LCD_CENTERING 0x01 | ||
74 | #define OP_LCD_PANEL_ID 0x02 | ||
75 | #define OP_LCD_MODE 0x03 | ||
76 | |||
77 | /*SAMM operation flag*/ | ||
78 | #define OP_SAMM 0x80 | ||
79 | |||
80 | #define LCD_PANEL_ID_MAXIMUM 22 | ||
81 | |||
82 | #define STATE_ON 0x1 | ||
83 | #define STATE_OFF 0x0 | ||
84 | #define STATE_DEFAULT 0xFFFF | ||
85 | |||
86 | #define MAX_ACTIVE_DEV_NUM 2 | ||
87 | |||
88 | struct device_t { | ||
89 | unsigned short crt:1; | ||
90 | unsigned short dvi:1; | ||
91 | unsigned short lcd:1; | ||
92 | unsigned short samm:1; | ||
93 | unsigned short lcd_dsp_cent:1; | ||
94 | unsigned char lcd_mode:1; | ||
95 | unsigned short epia_dvi:1; | ||
96 | unsigned short lcd_dual_edge:1; | ||
97 | unsigned short lcd2:1; | ||
98 | |||
99 | unsigned short primary_dev; | ||
100 | unsigned char lcd_panel_id; | ||
101 | unsigned short xres, yres; | ||
102 | unsigned short xres1, yres1; | ||
103 | unsigned short refresh; | ||
104 | unsigned short bpp; | ||
105 | unsigned short refresh1; | ||
106 | unsigned short bpp1; | ||
107 | unsigned short sequence; | ||
108 | unsigned short bus_width; | ||
109 | }; | ||
110 | |||
111 | struct viafb_ioctl_info { | ||
112 | u32 viafb_id; /* for identifying viafb */ | ||
113 | #define VIAID 0x56494146 /* Identify myself with 'VIAF' */ | ||
114 | u16 vendor_id; | ||
115 | u16 device_id; | ||
116 | u8 version; | ||
117 | u8 revision; | ||
118 | u8 reserved[246]; /* for future use */ | ||
119 | }; | ||
120 | |||
121 | struct viafb_ioctl_mode { | ||
122 | u32 xres; | ||
123 | u32 yres; | ||
124 | u32 refresh; | ||
125 | u32 bpp; | ||
126 | u32 xres_sec; | ||
127 | u32 yres_sec; | ||
128 | u32 virtual_xres_sec; | ||
129 | u32 virtual_yres_sec; | ||
130 | u32 refresh_sec; | ||
131 | u32 bpp_sec; | ||
132 | }; | ||
133 | struct viafb_ioctl_samm { | ||
134 | u32 samm_status; | ||
135 | u32 size_prim; | ||
136 | u32 size_sec; | ||
137 | u32 mem_base; | ||
138 | u32 offset_sec; | ||
139 | }; | ||
140 | |||
141 | struct viafb_driver_version { | ||
142 | int iMajorNum; | ||
143 | int iKernelNum; | ||
144 | int iOSNum; | ||
145 | int iMinorNum; | ||
146 | }; | ||
147 | |||
148 | struct viafb_ioctl_lcd_attribute { | ||
149 | unsigned int panel_id; | ||
150 | unsigned int display_center; | ||
151 | unsigned int lcd_mode; | ||
152 | }; | ||
153 | |||
154 | struct viafb_ioctl_setting { | ||
155 | /* Enable or disable active devices */ | ||
156 | unsigned short device_flag; | ||
157 | /* Indicate which device should be turn on or turn off. */ | ||
158 | unsigned short device_status; | ||
159 | unsigned int reserved; | ||
160 | /* Indicate which LCD's attribute can be changed. */ | ||
161 | unsigned short lcd_operation_flag; | ||
162 | /* 1: SAMM ON 0: SAMM OFF */ | ||
163 | unsigned short samm_status; | ||
164 | /* horizontal resolution of first device */ | ||
165 | unsigned short first_dev_hor_res; | ||
166 | /* vertical resolution of first device */ | ||
167 | unsigned short first_dev_ver_res; | ||
168 | /* horizontal resolution of second device */ | ||
169 | unsigned short second_dev_hor_res; | ||
170 | /* vertical resolution of second device */ | ||
171 | unsigned short second_dev_ver_res; | ||
172 | /* refresh rate of first device */ | ||
173 | unsigned short first_dev_refresh; | ||
174 | /* bpp of first device */ | ||
175 | unsigned short first_dev_bpp; | ||
176 | /* refresh rate of second device */ | ||
177 | unsigned short second_dev_refresh; | ||
178 | /* bpp of second device */ | ||
179 | unsigned short second_dev_bpp; | ||
180 | /* Indicate which device are primary display device. */ | ||
181 | unsigned int primary_device; | ||
182 | /* Indicate which device will show video. only valid in duoview mode */ | ||
183 | unsigned int video_device_status; | ||
184 | unsigned int struct_reserved[34]; | ||
185 | struct viafb_ioctl_lcd_attribute lcd_attributes; | ||
186 | }; | ||
187 | |||
188 | struct _UTFunctionCaps { | ||
189 | unsigned int dw3DScalingState; | ||
190 | unsigned int reserved[31]; | ||
191 | }; | ||
192 | |||
193 | struct _POSITIONVALUE { | ||
194 | unsigned int dwX; | ||
195 | unsigned int dwY; | ||
196 | }; | ||
197 | |||
198 | struct _panel_size_pos_info { | ||
199 | unsigned int device_type; | ||
200 | int x; | ||
201 | int y; | ||
202 | }; | ||
203 | |||
204 | extern int viafb_LCD_ON; | ||
205 | extern int viafb_DVI_ON; | ||
206 | |||
207 | int viafb_ioctl_get_viafb_info(u_long arg); | ||
208 | int viafb_ioctl_hotplug(int hres, int vres, int bpp); | ||
209 | |||
210 | #endif /* __IOCTL_H__ */ | ||
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c new file mode 100644 index 000000000000..6c7290a6a447 --- /dev/null +++ b/drivers/video/via/lcd.c | |||
@@ -0,0 +1,1821 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | #include "lcdtbl.h" | ||
24 | |||
25 | static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = { | ||
26 | /* IGA2 Shadow Horizontal Total */ | ||
27 | {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } }, | ||
28 | /* IGA2 Shadow Horizontal Blank End */ | ||
29 | {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } }, | ||
30 | /* IGA2 Shadow Vertical Total */ | ||
31 | {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } }, | ||
32 | /* IGA2 Shadow Vertical Addressable Video */ | ||
33 | {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } }, | ||
34 | /* IGA2 Shadow Vertical Blank Start */ | ||
35 | {IGA2_SHADOW_VER_BLANK_START_REG_NUM, | ||
36 | {{CR72, 0, 7}, {CR74, 4, 6} } }, | ||
37 | /* IGA2 Shadow Vertical Blank End */ | ||
38 | {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } }, | ||
39 | /* IGA2 Shadow Vertical Sync Start */ | ||
40 | {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } }, | ||
41 | /* IGA2 Shadow Vertical Sync End */ | ||
42 | {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } } | ||
43 | }; | ||
44 | |||
45 | static struct _lcd_scaling_factor lcd_scaling_factor = { | ||
46 | /* LCD Horizontal Scaling Factor Register */ | ||
47 | {LCD_HOR_SCALING_FACTOR_REG_NUM, | ||
48 | {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } }, | ||
49 | /* LCD Vertical Scaling Factor Register */ | ||
50 | {LCD_VER_SCALING_FACTOR_REG_NUM, | ||
51 | {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } } | ||
52 | }; | ||
53 | static struct _lcd_scaling_factor lcd_scaling_factor_CLE = { | ||
54 | /* LCD Horizontal Scaling Factor Register */ | ||
55 | {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } }, | ||
56 | /* LCD Vertical Scaling Factor Register */ | ||
57 | {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } } | ||
58 | }; | ||
59 | |||
60 | static int check_lvds_chip(int device_id_subaddr, int device_id); | ||
61 | static bool lvds_identify_integratedlvds(void); | ||
62 | static int fp_id_to_vindex(int panel_id); | ||
63 | static int lvds_register_read(int index); | ||
64 | static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, | ||
65 | int panel_vres); | ||
66 | static void load_lcd_k400_patch_tbl(int set_hres, int set_vres, | ||
67 | int panel_id); | ||
68 | static void load_lcd_p880_patch_tbl(int set_hres, int set_vres, | ||
69 | int panel_id); | ||
70 | static void load_lcd_patch_regs(int set_hres, int set_vres, | ||
71 | int panel_id, int set_iga); | ||
72 | static void via_pitch_alignment_patch_lcd( | ||
73 | struct lvds_setting_information *plvds_setting_info, | ||
74 | struct lvds_chip_information | ||
75 | *plvds_chip_info); | ||
76 | static void lcd_patch_skew_dvp0(struct lvds_setting_information | ||
77 | *plvds_setting_info, | ||
78 | struct lvds_chip_information *plvds_chip_info); | ||
79 | static void lcd_patch_skew_dvp1(struct lvds_setting_information | ||
80 | *plvds_setting_info, | ||
81 | struct lvds_chip_information *plvds_chip_info); | ||
82 | static void lcd_patch_skew(struct lvds_setting_information | ||
83 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); | ||
84 | |||
85 | static void integrated_lvds_disable(struct lvds_setting_information | ||
86 | *plvds_setting_info, | ||
87 | struct lvds_chip_information *plvds_chip_info); | ||
88 | static void integrated_lvds_enable(struct lvds_setting_information | ||
89 | *plvds_setting_info, | ||
90 | struct lvds_chip_information *plvds_chip_info); | ||
91 | static void lcd_powersequence_off(void); | ||
92 | static void lcd_powersequence_on(void); | ||
93 | static void fill_lcd_format(void); | ||
94 | static void check_diport_of_integrated_lvds( | ||
95 | struct lvds_chip_information *plvds_chip_info, | ||
96 | struct lvds_setting_information | ||
97 | *plvds_setting_info); | ||
98 | static struct display_timing lcd_centering_timging(struct display_timing | ||
99 | mode_crt_reg, | ||
100 | struct display_timing panel_crt_reg); | ||
101 | static void load_crtc_shadow_timing(struct display_timing mode_timing, | ||
102 | struct display_timing panel_timing); | ||
103 | static void viafb_load_scaling_factor_for_p4m900(int set_hres, | ||
104 | int set_vres, int panel_hres, int panel_vres); | ||
105 | |||
106 | static int check_lvds_chip(int device_id_subaddr, int device_id) | ||
107 | { | ||
108 | if (lvds_register_read(device_id_subaddr) == device_id) | ||
109 | return OK; | ||
110 | else | ||
111 | return FAIL; | ||
112 | } | ||
113 | |||
114 | void viafb_init_lcd_size(void) | ||
115 | { | ||
116 | DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); | ||
117 | DEBUG_MSG(KERN_INFO | ||
118 | "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n", | ||
119 | viaparinfo->lvds_setting_info->get_lcd_size_method); | ||
120 | |||
121 | switch (viaparinfo->lvds_setting_info->get_lcd_size_method) { | ||
122 | case GET_LCD_SIZE_BY_SYSTEM_BIOS: | ||
123 | break; | ||
124 | case GET_LCD_SZIE_BY_HW_STRAPPING: | ||
125 | break; | ||
126 | case GET_LCD_SIZE_BY_VGA_BIOS: | ||
127 | DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n"); | ||
128 | viaparinfo->lvds_setting_info->lcd_panel_size = | ||
129 | fp_id_to_vindex(viafb_lcd_panel_id); | ||
130 | DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", | ||
131 | viaparinfo->lvds_setting_info->lcd_panel_id); | ||
132 | DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", | ||
133 | viaparinfo->lvds_setting_info->lcd_panel_size); | ||
134 | break; | ||
135 | case GET_LCD_SIZE_BY_USER_SETTING: | ||
136 | DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n"); | ||
137 | viaparinfo->lvds_setting_info->lcd_panel_size = | ||
138 | fp_id_to_vindex(viafb_lcd_panel_id); | ||
139 | DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", | ||
140 | viaparinfo->lvds_setting_info->lcd_panel_id); | ||
141 | DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", | ||
142 | viaparinfo->lvds_setting_info->lcd_panel_size); | ||
143 | break; | ||
144 | default: | ||
145 | DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n"); | ||
146 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
147 | LCD_PANEL_ID1_800X600; | ||
148 | viaparinfo->lvds_setting_info->lcd_panel_size = | ||
149 | fp_id_to_vindex(LCD_PANEL_ID1_800X600); | ||
150 | } | ||
151 | viaparinfo->lvds_setting_info2->lcd_panel_id = | ||
152 | viaparinfo->lvds_setting_info->lcd_panel_id; | ||
153 | viaparinfo->lvds_setting_info2->lcd_panel_size = | ||
154 | viaparinfo->lvds_setting_info->lcd_panel_size; | ||
155 | viaparinfo->lvds_setting_info2->lcd_panel_hres = | ||
156 | viaparinfo->lvds_setting_info->lcd_panel_hres; | ||
157 | viaparinfo->lvds_setting_info2->lcd_panel_vres = | ||
158 | viaparinfo->lvds_setting_info->lcd_panel_vres; | ||
159 | viaparinfo->lvds_setting_info2->device_lcd_dualedge = | ||
160 | viaparinfo->lvds_setting_info->device_lcd_dualedge; | ||
161 | viaparinfo->lvds_setting_info2->LCDDithering = | ||
162 | viaparinfo->lvds_setting_info->LCDDithering; | ||
163 | } | ||
164 | |||
165 | static bool lvds_identify_integratedlvds(void) | ||
166 | { | ||
167 | if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) { | ||
168 | /* Two dual channel LCD (Internal LVDS + External LVDS): */ | ||
169 | /* If we have an external LVDS, such as VT1636, we should | ||
170 | have its chip ID already. */ | ||
171 | if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { | ||
172 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = | ||
173 | INTEGRATED_LVDS; | ||
174 | DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\ | ||
175 | (Internal LVDS + External LVDS)\n"); | ||
176 | } else { | ||
177 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | ||
178 | INTEGRATED_LVDS; | ||
179 | DEBUG_MSG(KERN_INFO "Not found external LVDS,\ | ||
180 | so can't support two dual channel LVDS!\n"); | ||
181 | } | ||
182 | } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) { | ||
183 | /* Two single channel LCD (Internal LVDS + Internal LVDS): */ | ||
184 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | ||
185 | INTEGRATED_LVDS; | ||
186 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = | ||
187 | INTEGRATED_LVDS; | ||
188 | DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\ | ||
189 | (Internal LVDS + Internal LVDS)\n"); | ||
190 | } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) { | ||
191 | /* If we have found external LVDS, just use it, | ||
192 | otherwise, we will use internal LVDS as default. */ | ||
193 | if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { | ||
194 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | ||
195 | INTEGRATED_LVDS; | ||
196 | DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n"); | ||
197 | } | ||
198 | } else { | ||
199 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | ||
200 | NON_LVDS_TRANSMITTER; | ||
201 | DEBUG_MSG(KERN_INFO "Do not support LVDS!\n"); | ||
202 | return false; | ||
203 | } | ||
204 | |||
205 | return true; | ||
206 | } | ||
207 | |||
208 | int viafb_lvds_trasmitter_identify(void) | ||
209 | { | ||
210 | viaparinfo->i2c_stuff.i2c_port = I2CPORTINDEX; | ||
211 | if (viafb_lvds_identify_vt1636()) { | ||
212 | viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX; | ||
213 | DEBUG_MSG(KERN_INFO | ||
214 | "Found VIA VT1636 LVDS on port i2c 0x31 \n"); | ||
215 | } else { | ||
216 | viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX; | ||
217 | if (viafb_lvds_identify_vt1636()) { | ||
218 | viaparinfo->chip_info->lvds_chip_info.i2c_port = | ||
219 | GPIOPORTINDEX; | ||
220 | DEBUG_MSG(KERN_INFO | ||
221 | "Found VIA VT1636 LVDS on port gpio 0x2c \n"); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) | ||
226 | lvds_identify_integratedlvds(); | ||
227 | |||
228 | if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) | ||
229 | return true; | ||
230 | /* Check for VT1631: */ | ||
231 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS; | ||
232 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = | ||
233 | VT1631_LVDS_I2C_ADDR; | ||
234 | |||
235 | if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) { | ||
236 | DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n"); | ||
237 | DEBUG_MSG(KERN_INFO "\n %2d", | ||
238 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); | ||
239 | DEBUG_MSG(KERN_INFO "\n %2d", | ||
240 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); | ||
241 | return OK; | ||
242 | } | ||
243 | |||
244 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | ||
245 | NON_LVDS_TRANSMITTER; | ||
246 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = | ||
247 | VT1631_LVDS_I2C_ADDR; | ||
248 | return FAIL; | ||
249 | } | ||
250 | |||
251 | static int fp_id_to_vindex(int panel_id) | ||
252 | { | ||
253 | DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); | ||
254 | |||
255 | if (panel_id > LCD_PANEL_ID_MAXIMUM) | ||
256 | viafb_lcd_panel_id = panel_id = | ||
257 | viafb_read_reg(VIACR, CR3F) & 0x0F; | ||
258 | |||
259 | switch (panel_id) { | ||
260 | case 0x0: | ||
261 | viaparinfo->lvds_setting_info->lcd_panel_hres = 640; | ||
262 | viaparinfo->lvds_setting_info->lcd_panel_vres = 480; | ||
263 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
264 | LCD_PANEL_ID0_640X480; | ||
265 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
266 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
267 | return VIA_RES_640X480; | ||
268 | break; | ||
269 | case 0x1: | ||
270 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | ||
271 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; | ||
272 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
273 | LCD_PANEL_ID1_800X600; | ||
274 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
275 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
276 | return VIA_RES_800X600; | ||
277 | break; | ||
278 | case 0x2: | ||
279 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | ||
280 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
281 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
282 | LCD_PANEL_ID2_1024X768; | ||
283 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
284 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
285 | return VIA_RES_1024X768; | ||
286 | break; | ||
287 | case 0x3: | ||
288 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | ||
289 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
290 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
291 | LCD_PANEL_ID3_1280X768; | ||
292 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
293 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
294 | return VIA_RES_1280X768; | ||
295 | break; | ||
296 | case 0x4: | ||
297 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | ||
298 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; | ||
299 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
300 | LCD_PANEL_ID4_1280X1024; | ||
301 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
302 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
303 | return VIA_RES_1280X1024; | ||
304 | break; | ||
305 | case 0x5: | ||
306 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; | ||
307 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; | ||
308 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
309 | LCD_PANEL_ID5_1400X1050; | ||
310 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
311 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
312 | return VIA_RES_1400X1050; | ||
313 | break; | ||
314 | case 0x6: | ||
315 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; | ||
316 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; | ||
317 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
318 | LCD_PANEL_ID6_1600X1200; | ||
319 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
320 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
321 | return VIA_RES_1600X1200; | ||
322 | break; | ||
323 | case 0x8: | ||
324 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | ||
325 | viaparinfo->lvds_setting_info->lcd_panel_vres = 480; | ||
326 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
327 | LCD_PANEL_IDA_800X480; | ||
328 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
329 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
330 | return VIA_RES_800X480; | ||
331 | break; | ||
332 | case 0x9: | ||
333 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | ||
334 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
335 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
336 | LCD_PANEL_ID2_1024X768; | ||
337 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
338 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
339 | return VIA_RES_1024X768; | ||
340 | break; | ||
341 | case 0xA: | ||
342 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | ||
343 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
344 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
345 | LCD_PANEL_ID2_1024X768; | ||
346 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
347 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
348 | return VIA_RES_1024X768; | ||
349 | break; | ||
350 | case 0xB: | ||
351 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | ||
352 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
353 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
354 | LCD_PANEL_ID2_1024X768; | ||
355 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
356 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
357 | return VIA_RES_1024X768; | ||
358 | break; | ||
359 | case 0xC: | ||
360 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | ||
361 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
362 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
363 | LCD_PANEL_ID3_1280X768; | ||
364 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
365 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
366 | return VIA_RES_1280X768; | ||
367 | break; | ||
368 | case 0xD: | ||
369 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | ||
370 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; | ||
371 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
372 | LCD_PANEL_ID4_1280X1024; | ||
373 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
374 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
375 | return VIA_RES_1280X1024; | ||
376 | break; | ||
377 | case 0xE: | ||
378 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; | ||
379 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; | ||
380 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
381 | LCD_PANEL_ID5_1400X1050; | ||
382 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
383 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
384 | return VIA_RES_1400X1050; | ||
385 | break; | ||
386 | case 0xF: | ||
387 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; | ||
388 | viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; | ||
389 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
390 | LCD_PANEL_ID6_1600X1200; | ||
391 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
392 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
393 | return VIA_RES_1600X1200; | ||
394 | break; | ||
395 | case 0x10: | ||
396 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; | ||
397 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
398 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
399 | LCD_PANEL_ID7_1366X768; | ||
400 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
401 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
402 | return VIA_RES_1368X768; | ||
403 | break; | ||
404 | case 0x11: | ||
405 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | ||
406 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; | ||
407 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
408 | LCD_PANEL_ID8_1024X600; | ||
409 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
410 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
411 | return VIA_RES_1024X600; | ||
412 | break; | ||
413 | case 0x12: | ||
414 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | ||
415 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
416 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
417 | LCD_PANEL_ID3_1280X768; | ||
418 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
419 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
420 | return VIA_RES_1280X768; | ||
421 | break; | ||
422 | case 0x13: | ||
423 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | ||
424 | viaparinfo->lvds_setting_info->lcd_panel_vres = 800; | ||
425 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
426 | LCD_PANEL_ID9_1280X800; | ||
427 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
428 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
429 | return VIA_RES_1280X800; | ||
430 | break; | ||
431 | case 0x14: | ||
432 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; | ||
433 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
434 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
435 | LCD_PANEL_IDB_1360X768; | ||
436 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
437 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
438 | return VIA_RES_1360X768; | ||
439 | break; | ||
440 | case 0x15: | ||
441 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | ||
442 | viaparinfo->lvds_setting_info->lcd_panel_vres = 768; | ||
443 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
444 | LCD_PANEL_ID3_1280X768; | ||
445 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | ||
446 | viaparinfo->lvds_setting_info->LCDDithering = 0; | ||
447 | return VIA_RES_1280X768; | ||
448 | break; | ||
449 | case 0x16: | ||
450 | viaparinfo->lvds_setting_info->lcd_panel_hres = 480; | ||
451 | viaparinfo->lvds_setting_info->lcd_panel_vres = 640; | ||
452 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
453 | LCD_PANEL_IDC_480X640; | ||
454 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
455 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
456 | return VIA_RES_480X640; | ||
457 | break; | ||
458 | default: | ||
459 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | ||
460 | viaparinfo->lvds_setting_info->lcd_panel_vres = 600; | ||
461 | viaparinfo->lvds_setting_info->lcd_panel_id = | ||
462 | LCD_PANEL_ID1_800X600; | ||
463 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | ||
464 | viaparinfo->lvds_setting_info->LCDDithering = 1; | ||
465 | return VIA_RES_800X600; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | static int lvds_register_read(int index) | ||
470 | { | ||
471 | u8 data; | ||
472 | |||
473 | viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX; | ||
474 | viafb_i2c_readbyte((u8) viaparinfo->chip_info-> | ||
475 | lvds_chip_info.lvds_chip_slave_addr, | ||
476 | (u8) index, &data); | ||
477 | return data; | ||
478 | } | ||
479 | |||
480 | static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, | ||
481 | int panel_vres) | ||
482 | { | ||
483 | int reg_value = 0; | ||
484 | int viafb_load_reg_num; | ||
485 | struct io_register *reg = NULL; | ||
486 | |||
487 | DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n"); | ||
488 | |||
489 | /* LCD Scaling Enable */ | ||
490 | viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2); | ||
491 | if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) { | ||
492 | viafb_load_scaling_factor_for_p4m900(set_hres, set_vres, | ||
493 | panel_hres, panel_vres); | ||
494 | return; | ||
495 | } | ||
496 | |||
497 | /* Check if expansion for horizontal */ | ||
498 | if (set_hres != panel_hres) { | ||
499 | /* Load Horizontal Scaling Factor */ | ||
500 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
501 | case UNICHROME_CLE266: | ||
502 | case UNICHROME_K400: | ||
503 | reg_value = | ||
504 | CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); | ||
505 | viafb_load_reg_num = | ||
506 | lcd_scaling_factor_CLE.lcd_hor_scaling_factor. | ||
507 | reg_num; | ||
508 | reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg; | ||
509 | viafb_load_reg(reg_value, | ||
510 | viafb_load_reg_num, reg, VIACR); | ||
511 | break; | ||
512 | case UNICHROME_K800: | ||
513 | case UNICHROME_PM800: | ||
514 | case UNICHROME_CN700: | ||
515 | case UNICHROME_CX700: | ||
516 | case UNICHROME_K8M890: | ||
517 | case UNICHROME_P4M890: | ||
518 | reg_value = | ||
519 | K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); | ||
520 | /* Horizontal scaling enabled */ | ||
521 | viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6); | ||
522 | viafb_load_reg_num = | ||
523 | lcd_scaling_factor.lcd_hor_scaling_factor.reg_num; | ||
524 | reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg; | ||
525 | viafb_load_reg(reg_value, | ||
526 | viafb_load_reg_num, reg, VIACR); | ||
527 | break; | ||
528 | } | ||
529 | |||
530 | DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value); | ||
531 | } else { | ||
532 | /* Horizontal scaling disabled */ | ||
533 | viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7); | ||
534 | } | ||
535 | |||
536 | /* Check if expansion for vertical */ | ||
537 | if (set_vres != panel_vres) { | ||
538 | /* Load Vertical Scaling Factor */ | ||
539 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
540 | case UNICHROME_CLE266: | ||
541 | case UNICHROME_K400: | ||
542 | reg_value = | ||
543 | CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres); | ||
544 | viafb_load_reg_num = | ||
545 | lcd_scaling_factor_CLE.lcd_ver_scaling_factor. | ||
546 | reg_num; | ||
547 | reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg; | ||
548 | viafb_load_reg(reg_value, | ||
549 | viafb_load_reg_num, reg, VIACR); | ||
550 | break; | ||
551 | case UNICHROME_K800: | ||
552 | case UNICHROME_PM800: | ||
553 | case UNICHROME_CN700: | ||
554 | case UNICHROME_CX700: | ||
555 | case UNICHROME_K8M890: | ||
556 | case UNICHROME_P4M890: | ||
557 | reg_value = | ||
558 | K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); | ||
559 | /* Vertical scaling enabled */ | ||
560 | viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3); | ||
561 | viafb_load_reg_num = | ||
562 | lcd_scaling_factor.lcd_ver_scaling_factor.reg_num; | ||
563 | reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg; | ||
564 | viafb_load_reg(reg_value, | ||
565 | viafb_load_reg_num, reg, VIACR); | ||
566 | break; | ||
567 | } | ||
568 | |||
569 | DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value); | ||
570 | } else { | ||
571 | /* Vertical scaling disabled */ | ||
572 | viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | static void load_lcd_k400_patch_tbl(int set_hres, int set_vres, | ||
577 | int panel_id) | ||
578 | { | ||
579 | int vmode_index; | ||
580 | int reg_num = 0; | ||
581 | struct io_reg *lcd_patch_reg = NULL; | ||
582 | |||
583 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) | ||
584 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); | ||
585 | else | ||
586 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); | ||
587 | switch (panel_id) { | ||
588 | /* LCD 800x600 */ | ||
589 | case LCD_PANEL_ID1_800X600: | ||
590 | switch (vmode_index) { | ||
591 | case VIA_RES_640X400: | ||
592 | case VIA_RES_640X480: | ||
593 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6; | ||
594 | lcd_patch_reg = K400_LCD_RES_6X4_8X6; | ||
595 | break; | ||
596 | case VIA_RES_720X480: | ||
597 | case VIA_RES_720X576: | ||
598 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6; | ||
599 | lcd_patch_reg = K400_LCD_RES_7X4_8X6; | ||
600 | break; | ||
601 | } | ||
602 | break; | ||
603 | |||
604 | /* LCD 1024x768 */ | ||
605 | case LCD_PANEL_ID2_1024X768: | ||
606 | switch (vmode_index) { | ||
607 | case VIA_RES_640X400: | ||
608 | case VIA_RES_640X480: | ||
609 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7; | ||
610 | lcd_patch_reg = K400_LCD_RES_6X4_10X7; | ||
611 | break; | ||
612 | case VIA_RES_720X480: | ||
613 | case VIA_RES_720X576: | ||
614 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7; | ||
615 | lcd_patch_reg = K400_LCD_RES_7X4_10X7; | ||
616 | break; | ||
617 | case VIA_RES_800X600: | ||
618 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7; | ||
619 | lcd_patch_reg = K400_LCD_RES_8X6_10X7; | ||
620 | break; | ||
621 | } | ||
622 | break; | ||
623 | |||
624 | /* LCD 1280x1024 */ | ||
625 | case LCD_PANEL_ID4_1280X1024: | ||
626 | switch (vmode_index) { | ||
627 | case VIA_RES_640X400: | ||
628 | case VIA_RES_640X480: | ||
629 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10; | ||
630 | lcd_patch_reg = K400_LCD_RES_6X4_12X10; | ||
631 | break; | ||
632 | case VIA_RES_720X480: | ||
633 | case VIA_RES_720X576: | ||
634 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10; | ||
635 | lcd_patch_reg = K400_LCD_RES_7X4_12X10; | ||
636 | break; | ||
637 | case VIA_RES_800X600: | ||
638 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10; | ||
639 | lcd_patch_reg = K400_LCD_RES_8X6_12X10; | ||
640 | break; | ||
641 | case VIA_RES_1024X768: | ||
642 | reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10; | ||
643 | lcd_patch_reg = K400_LCD_RES_10X7_12X10; | ||
644 | break; | ||
645 | |||
646 | } | ||
647 | break; | ||
648 | |||
649 | /* LCD 1400x1050 */ | ||
650 | case LCD_PANEL_ID5_1400X1050: | ||
651 | switch (vmode_index) { | ||
652 | case VIA_RES_640X480: | ||
653 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10; | ||
654 | lcd_patch_reg = K400_LCD_RES_6X4_14X10; | ||
655 | break; | ||
656 | case VIA_RES_800X600: | ||
657 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10; | ||
658 | lcd_patch_reg = K400_LCD_RES_8X6_14X10; | ||
659 | break; | ||
660 | case VIA_RES_1024X768: | ||
661 | reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10; | ||
662 | lcd_patch_reg = K400_LCD_RES_10X7_14X10; | ||
663 | break; | ||
664 | case VIA_RES_1280X768: | ||
665 | case VIA_RES_1280X800: | ||
666 | case VIA_RES_1280X960: | ||
667 | case VIA_RES_1280X1024: | ||
668 | reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10; | ||
669 | lcd_patch_reg = K400_LCD_RES_12X10_14X10; | ||
670 | break; | ||
671 | } | ||
672 | break; | ||
673 | |||
674 | /* LCD 1600x1200 */ | ||
675 | case LCD_PANEL_ID6_1600X1200: | ||
676 | switch (vmode_index) { | ||
677 | case VIA_RES_640X400: | ||
678 | case VIA_RES_640X480: | ||
679 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12; | ||
680 | lcd_patch_reg = K400_LCD_RES_6X4_16X12; | ||
681 | break; | ||
682 | case VIA_RES_720X480: | ||
683 | case VIA_RES_720X576: | ||
684 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12; | ||
685 | lcd_patch_reg = K400_LCD_RES_7X4_16X12; | ||
686 | break; | ||
687 | case VIA_RES_800X600: | ||
688 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12; | ||
689 | lcd_patch_reg = K400_LCD_RES_8X6_16X12; | ||
690 | break; | ||
691 | case VIA_RES_1024X768: | ||
692 | reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12; | ||
693 | lcd_patch_reg = K400_LCD_RES_10X7_16X12; | ||
694 | break; | ||
695 | case VIA_RES_1280X768: | ||
696 | case VIA_RES_1280X800: | ||
697 | case VIA_RES_1280X960: | ||
698 | case VIA_RES_1280X1024: | ||
699 | reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12; | ||
700 | lcd_patch_reg = K400_LCD_RES_12X10_16X12; | ||
701 | break; | ||
702 | } | ||
703 | break; | ||
704 | |||
705 | /* LCD 1366x768 */ | ||
706 | case LCD_PANEL_ID7_1366X768: | ||
707 | switch (vmode_index) { | ||
708 | case VIA_RES_640X480: | ||
709 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7; | ||
710 | lcd_patch_reg = K400_LCD_RES_6X4_1366X7; | ||
711 | break; | ||
712 | case VIA_RES_720X480: | ||
713 | case VIA_RES_720X576: | ||
714 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7; | ||
715 | lcd_patch_reg = K400_LCD_RES_7X4_1366X7; | ||
716 | break; | ||
717 | case VIA_RES_800X600: | ||
718 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7; | ||
719 | lcd_patch_reg = K400_LCD_RES_8X6_1366X7; | ||
720 | break; | ||
721 | case VIA_RES_1024X768: | ||
722 | reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7; | ||
723 | lcd_patch_reg = K400_LCD_RES_10X7_1366X7; | ||
724 | break; | ||
725 | case VIA_RES_1280X768: | ||
726 | case VIA_RES_1280X800: | ||
727 | case VIA_RES_1280X960: | ||
728 | case VIA_RES_1280X1024: | ||
729 | reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7; | ||
730 | lcd_patch_reg = K400_LCD_RES_12X10_1366X7; | ||
731 | break; | ||
732 | } | ||
733 | break; | ||
734 | |||
735 | /* LCD 1360x768 */ | ||
736 | case LCD_PANEL_IDB_1360X768: | ||
737 | break; | ||
738 | } | ||
739 | if (reg_num != 0) { | ||
740 | /* H.W. Reset : ON */ | ||
741 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | ||
742 | |||
743 | viafb_write_regx(lcd_patch_reg, reg_num); | ||
744 | |||
745 | /* H.W. Reset : OFF */ | ||
746 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | ||
747 | |||
748 | /* Reset PLL */ | ||
749 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); | ||
750 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); | ||
751 | |||
752 | /* Fire! */ | ||
753 | outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc); | ||
754 | } | ||
755 | } | ||
756 | |||
757 | static void load_lcd_p880_patch_tbl(int set_hres, int set_vres, | ||
758 | int panel_id) | ||
759 | { | ||
760 | int vmode_index; | ||
761 | int reg_num = 0; | ||
762 | struct io_reg *lcd_patch_reg = NULL; | ||
763 | |||
764 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) | ||
765 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); | ||
766 | else | ||
767 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); | ||
768 | |||
769 | switch (panel_id) { | ||
770 | case LCD_PANEL_ID5_1400X1050: | ||
771 | switch (vmode_index) { | ||
772 | case VIA_RES_640X480: | ||
773 | reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10; | ||
774 | lcd_patch_reg = P880_LCD_RES_6X4_14X10; | ||
775 | break; | ||
776 | case VIA_RES_800X600: | ||
777 | reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10; | ||
778 | lcd_patch_reg = P880_LCD_RES_8X6_14X10; | ||
779 | break; | ||
780 | } | ||
781 | break; | ||
782 | case LCD_PANEL_ID6_1600X1200: | ||
783 | switch (vmode_index) { | ||
784 | case VIA_RES_640X400: | ||
785 | case VIA_RES_640X480: | ||
786 | reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12; | ||
787 | lcd_patch_reg = P880_LCD_RES_6X4_16X12; | ||
788 | break; | ||
789 | case VIA_RES_720X480: | ||
790 | case VIA_RES_720X576: | ||
791 | reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12; | ||
792 | lcd_patch_reg = P880_LCD_RES_7X4_16X12; | ||
793 | break; | ||
794 | case VIA_RES_800X600: | ||
795 | reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12; | ||
796 | lcd_patch_reg = P880_LCD_RES_8X6_16X12; | ||
797 | break; | ||
798 | case VIA_RES_1024X768: | ||
799 | reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12; | ||
800 | lcd_patch_reg = P880_LCD_RES_10X7_16X12; | ||
801 | break; | ||
802 | case VIA_RES_1280X768: | ||
803 | case VIA_RES_1280X960: | ||
804 | case VIA_RES_1280X1024: | ||
805 | reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12; | ||
806 | lcd_patch_reg = P880_LCD_RES_12X10_16X12; | ||
807 | break; | ||
808 | } | ||
809 | break; | ||
810 | |||
811 | } | ||
812 | if (reg_num != 0) { | ||
813 | /* H.W. Reset : ON */ | ||
814 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | ||
815 | |||
816 | viafb_write_regx(lcd_patch_reg, reg_num); | ||
817 | |||
818 | /* H.W. Reset : OFF */ | ||
819 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | ||
820 | |||
821 | /* Reset PLL */ | ||
822 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); | ||
823 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); | ||
824 | |||
825 | /* Fire! */ | ||
826 | outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc); | ||
827 | } | ||
828 | } | ||
829 | |||
830 | static void load_lcd_patch_regs(int set_hres, int set_vres, | ||
831 | int panel_id, int set_iga) | ||
832 | { | ||
833 | int vmode_index; | ||
834 | |||
835 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) | ||
836 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); | ||
837 | else | ||
838 | vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); | ||
839 | |||
840 | viafb_unlock_crt(); | ||
841 | |||
842 | /* Patch for simultaneous & Expansion */ | ||
843 | if ((set_iga == IGA1_IGA2) && | ||
844 | (viaparinfo->lvds_setting_info->display_method == | ||
845 | LCD_EXPANDSION)) { | ||
846 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
847 | case UNICHROME_CLE266: | ||
848 | case UNICHROME_K400: | ||
849 | load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id); | ||
850 | break; | ||
851 | case UNICHROME_K800: | ||
852 | break; | ||
853 | case UNICHROME_PM800: | ||
854 | case UNICHROME_CN700: | ||
855 | case UNICHROME_CX700: | ||
856 | load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id); | ||
857 | } | ||
858 | } | ||
859 | |||
860 | viafb_lock_crt(); | ||
861 | } | ||
862 | |||
863 | static void via_pitch_alignment_patch_lcd( | ||
864 | struct lvds_setting_information *plvds_setting_info, | ||
865 | struct lvds_chip_information | ||
866 | *plvds_chip_info) | ||
867 | { | ||
868 | unsigned char cr13, cr35, cr65, cr66, cr67; | ||
869 | unsigned long dwScreenPitch = 0; | ||
870 | unsigned long dwPitch; | ||
871 | |||
872 | dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3); | ||
873 | if (dwPitch & 0x1F) { | ||
874 | dwScreenPitch = ((dwPitch + 31) & ~31) >> 3; | ||
875 | if (plvds_setting_info->iga_path == IGA2) { | ||
876 | if (plvds_setting_info->bpp > 8) { | ||
877 | cr66 = (unsigned char)(dwScreenPitch & 0xFF); | ||
878 | viafb_write_reg(CR66, VIACR, cr66); | ||
879 | cr67 = viafb_read_reg(VIACR, CR67) & 0xFC; | ||
880 | cr67 |= | ||
881 | (unsigned | ||
882 | char)((dwScreenPitch & 0x300) >> 8); | ||
883 | viafb_write_reg(CR67, VIACR, cr67); | ||
884 | } | ||
885 | |||
886 | /* Fetch Count */ | ||
887 | cr67 = viafb_read_reg(VIACR, CR67) & 0xF3; | ||
888 | cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7); | ||
889 | viafb_write_reg(CR67, VIACR, cr67); | ||
890 | cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF); | ||
891 | cr65 += 2; | ||
892 | viafb_write_reg(CR65, VIACR, cr65); | ||
893 | } else { | ||
894 | if (plvds_setting_info->bpp > 8) { | ||
895 | cr13 = (unsigned char)(dwScreenPitch & 0xFF); | ||
896 | viafb_write_reg(CR13, VIACR, cr13); | ||
897 | cr35 = viafb_read_reg(VIACR, CR35) & 0x1F; | ||
898 | cr35 |= | ||
899 | (unsigned | ||
900 | char)((dwScreenPitch & 0x700) >> 3); | ||
901 | viafb_write_reg(CR35, VIACR, cr35); | ||
902 | } | ||
903 | } | ||
904 | } | ||
905 | } | ||
906 | static void lcd_patch_skew_dvp0(struct lvds_setting_information | ||
907 | *plvds_setting_info, | ||
908 | struct lvds_chip_information *plvds_chip_info) | ||
909 | { | ||
910 | if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) { | ||
911 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
912 | case UNICHROME_P4M900: | ||
913 | viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info, | ||
914 | plvds_chip_info); | ||
915 | break; | ||
916 | case UNICHROME_P4M890: | ||
917 | viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info, | ||
918 | plvds_chip_info); | ||
919 | break; | ||
920 | } | ||
921 | } | ||
922 | } | ||
923 | static void lcd_patch_skew_dvp1(struct lvds_setting_information | ||
924 | *plvds_setting_info, | ||
925 | struct lvds_chip_information *plvds_chip_info) | ||
926 | { | ||
927 | if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) { | ||
928 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
929 | case UNICHROME_CX700: | ||
930 | viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info, | ||
931 | plvds_chip_info); | ||
932 | break; | ||
933 | } | ||
934 | } | ||
935 | } | ||
936 | static void lcd_patch_skew(struct lvds_setting_information | ||
937 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) | ||
938 | { | ||
939 | DEBUG_MSG(KERN_INFO "lcd_patch_skew\n"); | ||
940 | switch (plvds_chip_info->output_interface) { | ||
941 | case INTERFACE_DVP0: | ||
942 | lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info); | ||
943 | break; | ||
944 | case INTERFACE_DVP1: | ||
945 | lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info); | ||
946 | break; | ||
947 | case INTERFACE_DFP_LOW: | ||
948 | if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) { | ||
949 | viafb_write_reg_mask(CR99, VIACR, 0x08, | ||
950 | BIT0 + BIT1 + BIT2 + BIT3); | ||
951 | } | ||
952 | break; | ||
953 | } | ||
954 | } | ||
955 | |||
956 | /* LCD Set Mode */ | ||
957 | void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | ||
958 | struct lvds_setting_information *plvds_setting_info, | ||
959 | struct lvds_chip_information *plvds_chip_info) | ||
960 | { | ||
961 | int video_index = plvds_setting_info->lcd_panel_size; | ||
962 | int set_iga = plvds_setting_info->iga_path; | ||
963 | int mode_bpp = plvds_setting_info->bpp; | ||
964 | int viafb_load_reg_num = 0; | ||
965 | int reg_value = 0; | ||
966 | int set_hres, set_vres; | ||
967 | int panel_hres, panel_vres; | ||
968 | u32 pll_D_N; | ||
969 | int offset; | ||
970 | struct io_register *reg = NULL; | ||
971 | struct display_timing mode_crt_reg, panel_crt_reg; | ||
972 | struct crt_mode_table *panel_crt_table = NULL; | ||
973 | struct VideoModeTable *vmode_tbl = NULL; | ||
974 | |||
975 | DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n"); | ||
976 | /* Get mode table */ | ||
977 | mode_crt_reg = mode_crt_table->crtc; | ||
978 | /* Get panel table Pointer */ | ||
979 | vmode_tbl = viafb_get_modetbl_pointer(video_index); | ||
980 | panel_crt_table = vmode_tbl->crtc; | ||
981 | panel_crt_reg = panel_crt_table->crtc; | ||
982 | DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n"); | ||
983 | set_hres = plvds_setting_info->h_active; | ||
984 | set_vres = plvds_setting_info->v_active; | ||
985 | panel_hres = plvds_setting_info->lcd_panel_hres; | ||
986 | panel_vres = plvds_setting_info->lcd_panel_vres; | ||
987 | if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) | ||
988 | viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info); | ||
989 | plvds_setting_info->vclk = panel_crt_table->clk; | ||
990 | if (set_iga == IGA1) { | ||
991 | /* IGA1 doesn't have LCD scaling, so set it as centering. */ | ||
992 | viafb_load_crtc_timing(lcd_centering_timging | ||
993 | (mode_crt_reg, panel_crt_reg), IGA1); | ||
994 | } else { | ||
995 | /* Expansion */ | ||
996 | if ((plvds_setting_info->display_method == | ||
997 | LCD_EXPANDSION) & ((set_hres != panel_hres) | ||
998 | || (set_vres != panel_vres))) { | ||
999 | /* expansion timing IGA2 loaded panel set timing*/ | ||
1000 | viafb_load_crtc_timing(panel_crt_reg, IGA2); | ||
1001 | DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n"); | ||
1002 | load_lcd_scaling(set_hres, set_vres, panel_hres, | ||
1003 | panel_vres); | ||
1004 | DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n"); | ||
1005 | } else { /* Centering */ | ||
1006 | /* centering timing IGA2 always loaded panel | ||
1007 | and mode releative timing */ | ||
1008 | viafb_load_crtc_timing(lcd_centering_timging | ||
1009 | (mode_crt_reg, panel_crt_reg), IGA2); | ||
1010 | viafb_write_reg_mask(CR79, VIACR, 0x00, | ||
1011 | BIT0 + BIT1 + BIT2); | ||
1012 | /* LCD scaling disabled */ | ||
1013 | } | ||
1014 | } | ||
1015 | |||
1016 | if (set_iga == IGA1_IGA2) { | ||
1017 | load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg); | ||
1018 | /* Fill shadow registers */ | ||
1019 | |||
1020 | switch (plvds_setting_info->lcd_panel_id) { | ||
1021 | case LCD_PANEL_ID0_640X480: | ||
1022 | offset = 80; | ||
1023 | break; | ||
1024 | case LCD_PANEL_ID1_800X600: | ||
1025 | case LCD_PANEL_IDA_800X480: | ||
1026 | offset = 110; | ||
1027 | break; | ||
1028 | case LCD_PANEL_ID2_1024X768: | ||
1029 | offset = 150; | ||
1030 | break; | ||
1031 | case LCD_PANEL_ID3_1280X768: | ||
1032 | case LCD_PANEL_ID4_1280X1024: | ||
1033 | case LCD_PANEL_ID5_1400X1050: | ||
1034 | case LCD_PANEL_ID9_1280X800: | ||
1035 | offset = 190; | ||
1036 | break; | ||
1037 | case LCD_PANEL_ID6_1600X1200: | ||
1038 | offset = 250; | ||
1039 | break; | ||
1040 | case LCD_PANEL_ID7_1366X768: | ||
1041 | case LCD_PANEL_IDB_1360X768: | ||
1042 | offset = 212; | ||
1043 | break; | ||
1044 | default: | ||
1045 | offset = 140; | ||
1046 | break; | ||
1047 | } | ||
1048 | |||
1049 | /* Offset for simultaneous */ | ||
1050 | reg_value = offset; | ||
1051 | viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num; | ||
1052 | reg = offset_reg.iga2_offset_reg.reg; | ||
1053 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
1054 | DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n"); | ||
1055 | viafb_load_fetch_count_reg(set_hres, 4, IGA2); | ||
1056 | /* Fetch count for simultaneous */ | ||
1057 | } else { /* SAMM */ | ||
1058 | /* Offset for IGA2 only */ | ||
1059 | viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga); | ||
1060 | /* Fetch count for IGA2 only */ | ||
1061 | viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); | ||
1062 | |||
1063 | if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) | ||
1064 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) | ||
1065 | viafb_load_FIFO_reg(set_iga, set_hres, set_vres); | ||
1066 | |||
1067 | viafb_set_color_depth(mode_bpp / 8, set_iga); | ||
1068 | } | ||
1069 | |||
1070 | fill_lcd_format(); | ||
1071 | |||
1072 | pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk); | ||
1073 | DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); | ||
1074 | viafb_set_vclock(pll_D_N, set_iga); | ||
1075 | |||
1076 | viafb_set_output_path(DEVICE_LCD, set_iga, | ||
1077 | plvds_chip_info->output_interface); | ||
1078 | lcd_patch_skew(plvds_setting_info, plvds_chip_info); | ||
1079 | |||
1080 | /* If K8M800, enable LCD Prefetch Mode. */ | ||
1081 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) | ||
1082 | || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)) | ||
1083 | viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0); | ||
1084 | |||
1085 | load_lcd_patch_regs(set_hres, set_vres, | ||
1086 | plvds_setting_info->lcd_panel_id, set_iga); | ||
1087 | |||
1088 | DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n"); | ||
1089 | |||
1090 | /* Patch for non 32bit alignment mode */ | ||
1091 | via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info); | ||
1092 | } | ||
1093 | |||
1094 | static void integrated_lvds_disable(struct lvds_setting_information | ||
1095 | *plvds_setting_info, | ||
1096 | struct lvds_chip_information *plvds_chip_info) | ||
1097 | { | ||
1098 | bool turn_off_first_powersequence = false; | ||
1099 | bool turn_off_second_powersequence = false; | ||
1100 | if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface) | ||
1101 | turn_off_first_powersequence = true; | ||
1102 | if (INTERFACE_LVDS0 == plvds_chip_info->output_interface) | ||
1103 | turn_off_first_powersequence = true; | ||
1104 | if (INTERFACE_LVDS1 == plvds_chip_info->output_interface) | ||
1105 | turn_off_second_powersequence = true; | ||
1106 | if (turn_off_second_powersequence) { | ||
1107 | /* Use second power sequence control: */ | ||
1108 | |||
1109 | /* Turn off power sequence. */ | ||
1110 | viafb_write_reg_mask(CRD4, VIACR, 0, BIT1); | ||
1111 | |||
1112 | /* Turn off back light. */ | ||
1113 | viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7); | ||
1114 | } | ||
1115 | if (turn_off_first_powersequence) { | ||
1116 | /* Use first power sequence control: */ | ||
1117 | |||
1118 | /* Turn off power sequence. */ | ||
1119 | viafb_write_reg_mask(CR6A, VIACR, 0, BIT3); | ||
1120 | |||
1121 | /* Turn off back light. */ | ||
1122 | viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7); | ||
1123 | } | ||
1124 | |||
1125 | /* Turn DFP High/Low Pad off. */ | ||
1126 | viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3); | ||
1127 | |||
1128 | /* Power off LVDS channel. */ | ||
1129 | switch (plvds_chip_info->output_interface) { | ||
1130 | case INTERFACE_LVDS0: | ||
1131 | { | ||
1132 | viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7); | ||
1133 | break; | ||
1134 | } | ||
1135 | |||
1136 | case INTERFACE_LVDS1: | ||
1137 | { | ||
1138 | viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6); | ||
1139 | break; | ||
1140 | } | ||
1141 | |||
1142 | case INTERFACE_LVDS0LVDS1: | ||
1143 | { | ||
1144 | viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7); | ||
1145 | break; | ||
1146 | } | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | static void integrated_lvds_enable(struct lvds_setting_information | ||
1151 | *plvds_setting_info, | ||
1152 | struct lvds_chip_information *plvds_chip_info) | ||
1153 | { | ||
1154 | bool turn_on_first_powersequence = false; | ||
1155 | bool turn_on_second_powersequence = false; | ||
1156 | |||
1157 | DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n", | ||
1158 | plvds_chip_info->output_interface); | ||
1159 | if (plvds_setting_info->lcd_mode == LCD_SPWG) | ||
1160 | viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1); | ||
1161 | else | ||
1162 | viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1); | ||
1163 | if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface) | ||
1164 | turn_on_first_powersequence = true; | ||
1165 | if (INTERFACE_LVDS0 == plvds_chip_info->output_interface) | ||
1166 | turn_on_first_powersequence = true; | ||
1167 | if (INTERFACE_LVDS1 == plvds_chip_info->output_interface) | ||
1168 | turn_on_second_powersequence = true; | ||
1169 | |||
1170 | if (turn_on_second_powersequence) { | ||
1171 | /* Use second power sequence control: */ | ||
1172 | |||
1173 | /* Use hardware control power sequence. */ | ||
1174 | viafb_write_reg_mask(CRD3, VIACR, 0, BIT0); | ||
1175 | |||
1176 | /* Turn on back light. */ | ||
1177 | viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7); | ||
1178 | |||
1179 | /* Turn on hardware power sequence. */ | ||
1180 | viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1); | ||
1181 | } | ||
1182 | if (turn_on_first_powersequence) { | ||
1183 | /* Use first power sequence control: */ | ||
1184 | |||
1185 | /* Use hardware control power sequence. */ | ||
1186 | viafb_write_reg_mask(CR91, VIACR, 0, BIT0); | ||
1187 | |||
1188 | /* Turn on back light. */ | ||
1189 | viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7); | ||
1190 | |||
1191 | /* Turn on hardware power sequence. */ | ||
1192 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); | ||
1193 | } | ||
1194 | |||
1195 | /* Turn DFP High/Low pad on. */ | ||
1196 | viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3); | ||
1197 | |||
1198 | /* Power on LVDS channel. */ | ||
1199 | switch (plvds_chip_info->output_interface) { | ||
1200 | case INTERFACE_LVDS0: | ||
1201 | { | ||
1202 | viafb_write_reg_mask(CRD2, VIACR, 0, BIT7); | ||
1203 | break; | ||
1204 | } | ||
1205 | |||
1206 | case INTERFACE_LVDS1: | ||
1207 | { | ||
1208 | viafb_write_reg_mask(CRD2, VIACR, 0, BIT6); | ||
1209 | break; | ||
1210 | } | ||
1211 | |||
1212 | case INTERFACE_LVDS0LVDS1: | ||
1213 | { | ||
1214 | viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7); | ||
1215 | break; | ||
1216 | } | ||
1217 | } | ||
1218 | } | ||
1219 | |||
1220 | void viafb_lcd_disable(void) | ||
1221 | { | ||
1222 | |||
1223 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | ||
1224 | lcd_powersequence_off(); | ||
1225 | /* DI1 pad off */ | ||
1226 | viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30); | ||
1227 | } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { | ||
1228 | if (viafb_LCD2_ON | ||
1229 | && (INTEGRATED_LVDS == | ||
1230 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name)) | ||
1231 | integrated_lvds_disable(viaparinfo->lvds_setting_info, | ||
1232 | &viaparinfo->chip_info->lvds_chip_info2); | ||
1233 | if (INTEGRATED_LVDS == | ||
1234 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) | ||
1235 | integrated_lvds_disable(viaparinfo->lvds_setting_info, | ||
1236 | &viaparinfo->chip_info->lvds_chip_info); | ||
1237 | if (VT1636_LVDS == viaparinfo->chip_info-> | ||
1238 | lvds_chip_info.lvds_chip_name) | ||
1239 | viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, | ||
1240 | &viaparinfo->chip_info->lvds_chip_info); | ||
1241 | } else if (VT1636_LVDS == | ||
1242 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { | ||
1243 | viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, | ||
1244 | &viaparinfo->chip_info->lvds_chip_info); | ||
1245 | } else { | ||
1246 | /* DFP-HL pad off */ | ||
1247 | viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F); | ||
1248 | /* Backlight off */ | ||
1249 | viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20); | ||
1250 | /* 24 bit DI data paht off */ | ||
1251 | viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80); | ||
1252 | /* Simultaneout disabled */ | ||
1253 | viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); | ||
1254 | } | ||
1255 | |||
1256 | /* Disable expansion bit */ | ||
1257 | viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01); | ||
1258 | /* CRT path set to IGA1 */ | ||
1259 | viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40); | ||
1260 | /* Simultaneout disabled */ | ||
1261 | viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); | ||
1262 | /* IGA2 path disabled */ | ||
1263 | viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80); | ||
1264 | |||
1265 | } | ||
1266 | |||
1267 | void viafb_lcd_enable(void) | ||
1268 | { | ||
1269 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | ||
1270 | /* DI1 pad on */ | ||
1271 | viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); | ||
1272 | lcd_powersequence_on(); | ||
1273 | } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { | ||
1274 | if (viafb_LCD2_ON && (INTEGRATED_LVDS == | ||
1275 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name)) | ||
1276 | integrated_lvds_enable(viaparinfo->lvds_setting_info2, \ | ||
1277 | &viaparinfo->chip_info->lvds_chip_info2); | ||
1278 | if (INTEGRATED_LVDS == | ||
1279 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) | ||
1280 | integrated_lvds_enable(viaparinfo->lvds_setting_info, | ||
1281 | &viaparinfo->chip_info->lvds_chip_info); | ||
1282 | if (VT1636_LVDS == viaparinfo->chip_info-> | ||
1283 | lvds_chip_info.lvds_chip_name) | ||
1284 | viafb_enable_lvds_vt1636(viaparinfo-> | ||
1285 | lvds_setting_info, &viaparinfo->chip_info-> | ||
1286 | lvds_chip_info); | ||
1287 | } else if (VT1636_LVDS == | ||
1288 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { | ||
1289 | viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info, | ||
1290 | &viaparinfo->chip_info->lvds_chip_info); | ||
1291 | } else { | ||
1292 | /* DFP-HL pad on */ | ||
1293 | viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F); | ||
1294 | /* Backlight on */ | ||
1295 | viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20); | ||
1296 | /* 24 bit DI data paht on */ | ||
1297 | viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80); | ||
1298 | |||
1299 | /* Set data source selection bit by iga path */ | ||
1300 | if (viaparinfo->lvds_setting_info->iga_path == IGA1) { | ||
1301 | /* DFP-H set to IGA1 */ | ||
1302 | viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10); | ||
1303 | /* DFP-L set to IGA1 */ | ||
1304 | viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10); | ||
1305 | } else { | ||
1306 | /* DFP-H set to IGA2 */ | ||
1307 | viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10); | ||
1308 | /* DFP-L set to IGA2 */ | ||
1309 | viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10); | ||
1310 | } | ||
1311 | /* LCD enabled */ | ||
1312 | viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48); | ||
1313 | } | ||
1314 | |||
1315 | if ((viaparinfo->lvds_setting_info->iga_path == IGA1) | ||
1316 | || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) { | ||
1317 | /* CRT path set to IGA2 */ | ||
1318 | viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40); | ||
1319 | /* IGA2 path disabled */ | ||
1320 | viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80); | ||
1321 | /* IGA2 path enabled */ | ||
1322 | } else { /* IGA2 */ | ||
1323 | viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80); | ||
1324 | } | ||
1325 | |||
1326 | } | ||
1327 | |||
1328 | static void lcd_powersequence_off(void) | ||
1329 | { | ||
1330 | int i, mask, data; | ||
1331 | |||
1332 | /* Software control power sequence */ | ||
1333 | viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11); | ||
1334 | |||
1335 | for (i = 0; i < 3; i++) { | ||
1336 | mask = PowerSequenceOff[0][i]; | ||
1337 | data = PowerSequenceOff[1][i] & mask; | ||
1338 | viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask); | ||
1339 | udelay(PowerSequenceOff[2][i]); | ||
1340 | } | ||
1341 | |||
1342 | /* Disable LCD */ | ||
1343 | viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08); | ||
1344 | } | ||
1345 | |||
1346 | static void lcd_powersequence_on(void) | ||
1347 | { | ||
1348 | int i, mask, data; | ||
1349 | |||
1350 | /* Software control power sequence */ | ||
1351 | viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11); | ||
1352 | |||
1353 | /* Enable LCD */ | ||
1354 | viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08); | ||
1355 | |||
1356 | for (i = 0; i < 3; i++) { | ||
1357 | mask = PowerSequenceOn[0][i]; | ||
1358 | data = PowerSequenceOn[1][i] & mask; | ||
1359 | viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask); | ||
1360 | udelay(PowerSequenceOn[2][i]); | ||
1361 | } | ||
1362 | |||
1363 | udelay(1); | ||
1364 | } | ||
1365 | |||
1366 | static void fill_lcd_format(void) | ||
1367 | { | ||
1368 | u8 bdithering = 0, bdual = 0; | ||
1369 | |||
1370 | if (viaparinfo->lvds_setting_info->device_lcd_dualedge) | ||
1371 | bdual = BIT4; | ||
1372 | if (viaparinfo->lvds_setting_info->LCDDithering) | ||
1373 | bdithering = BIT0; | ||
1374 | /* Dual & Dithering */ | ||
1375 | viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0); | ||
1376 | } | ||
1377 | |||
1378 | static void check_diport_of_integrated_lvds( | ||
1379 | struct lvds_chip_information *plvds_chip_info, | ||
1380 | struct lvds_setting_information | ||
1381 | *plvds_setting_info) | ||
1382 | { | ||
1383 | /* Determine LCD DI Port by hardware layout. */ | ||
1384 | switch (viafb_display_hardware_layout) { | ||
1385 | case HW_LAYOUT_LCD_ONLY: | ||
1386 | { | ||
1387 | if (plvds_setting_info->device_lcd_dualedge) { | ||
1388 | plvds_chip_info->output_interface = | ||
1389 | INTERFACE_LVDS0LVDS1; | ||
1390 | } else { | ||
1391 | plvds_chip_info->output_interface = | ||
1392 | INTERFACE_LVDS0; | ||
1393 | } | ||
1394 | |||
1395 | break; | ||
1396 | } | ||
1397 | |||
1398 | case HW_LAYOUT_DVI_ONLY: | ||
1399 | { | ||
1400 | plvds_chip_info->output_interface = INTERFACE_NONE; | ||
1401 | break; | ||
1402 | } | ||
1403 | |||
1404 | case HW_LAYOUT_LCD1_LCD2: | ||
1405 | case HW_LAYOUT_LCD_EXTERNAL_LCD2: | ||
1406 | { | ||
1407 | plvds_chip_info->output_interface = | ||
1408 | INTERFACE_LVDS0LVDS1; | ||
1409 | break; | ||
1410 | } | ||
1411 | |||
1412 | case HW_LAYOUT_LCD_DVI: | ||
1413 | { | ||
1414 | plvds_chip_info->output_interface = INTERFACE_LVDS1; | ||
1415 | break; | ||
1416 | } | ||
1417 | |||
1418 | default: | ||
1419 | { | ||
1420 | plvds_chip_info->output_interface = INTERFACE_LVDS1; | ||
1421 | break; | ||
1422 | } | ||
1423 | } | ||
1424 | |||
1425 | DEBUG_MSG(KERN_INFO | ||
1426 | "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n", | ||
1427 | viafb_display_hardware_layout, | ||
1428 | plvds_chip_info->output_interface); | ||
1429 | } | ||
1430 | |||
1431 | void viafb_init_lvds_output_interface(struct lvds_chip_information | ||
1432 | *plvds_chip_info, | ||
1433 | struct lvds_setting_information | ||
1434 | *plvds_setting_info) | ||
1435 | { | ||
1436 | if (INTERFACE_NONE != plvds_chip_info->output_interface) { | ||
1437 | /*Do nothing, lcd port is specified by module parameter */ | ||
1438 | return; | ||
1439 | } | ||
1440 | |||
1441 | switch (plvds_chip_info->lvds_chip_name) { | ||
1442 | |||
1443 | case VT1636_LVDS: | ||
1444 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
1445 | case UNICHROME_CX700: | ||
1446 | plvds_chip_info->output_interface = INTERFACE_DVP1; | ||
1447 | break; | ||
1448 | case UNICHROME_CN700: | ||
1449 | plvds_chip_info->output_interface = INTERFACE_DFP_LOW; | ||
1450 | break; | ||
1451 | default: | ||
1452 | plvds_chip_info->output_interface = INTERFACE_DVP0; | ||
1453 | break; | ||
1454 | } | ||
1455 | break; | ||
1456 | |||
1457 | case INTEGRATED_LVDS: | ||
1458 | check_diport_of_integrated_lvds(plvds_chip_info, | ||
1459 | plvds_setting_info); | ||
1460 | break; | ||
1461 | |||
1462 | default: | ||
1463 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
1464 | case UNICHROME_K8M890: | ||
1465 | case UNICHROME_P4M900: | ||
1466 | case UNICHROME_P4M890: | ||
1467 | plvds_chip_info->output_interface = INTERFACE_DFP_LOW; | ||
1468 | break; | ||
1469 | default: | ||
1470 | plvds_chip_info->output_interface = INTERFACE_DFP; | ||
1471 | break; | ||
1472 | } | ||
1473 | break; | ||
1474 | } | ||
1475 | } | ||
1476 | |||
1477 | static struct display_timing lcd_centering_timging(struct display_timing | ||
1478 | mode_crt_reg, | ||
1479 | struct display_timing panel_crt_reg) | ||
1480 | { | ||
1481 | struct display_timing crt_reg; | ||
1482 | |||
1483 | crt_reg.hor_total = panel_crt_reg.hor_total; | ||
1484 | crt_reg.hor_addr = mode_crt_reg.hor_addr; | ||
1485 | crt_reg.hor_blank_start = | ||
1486 | (panel_crt_reg.hor_addr - mode_crt_reg.hor_addr) / 2 + | ||
1487 | crt_reg.hor_addr; | ||
1488 | crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end; | ||
1489 | crt_reg.hor_sync_start = | ||
1490 | (panel_crt_reg.hor_sync_start - | ||
1491 | panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start; | ||
1492 | crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end; | ||
1493 | |||
1494 | crt_reg.ver_total = panel_crt_reg.ver_total; | ||
1495 | crt_reg.ver_addr = mode_crt_reg.ver_addr; | ||
1496 | crt_reg.ver_blank_start = | ||
1497 | (panel_crt_reg.ver_addr - mode_crt_reg.ver_addr) / 2 + | ||
1498 | crt_reg.ver_addr; | ||
1499 | crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end; | ||
1500 | crt_reg.ver_sync_start = | ||
1501 | (panel_crt_reg.ver_sync_start - | ||
1502 | panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start; | ||
1503 | crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end; | ||
1504 | |||
1505 | return crt_reg; | ||
1506 | } | ||
1507 | |||
1508 | static void load_crtc_shadow_timing(struct display_timing mode_timing, | ||
1509 | struct display_timing panel_timing) | ||
1510 | { | ||
1511 | struct io_register *reg = NULL; | ||
1512 | int i; | ||
1513 | int viafb_load_reg_Num = 0; | ||
1514 | int reg_value = 0; | ||
1515 | |||
1516 | if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) { | ||
1517 | /* Expansion */ | ||
1518 | for (i = 12; i < 20; i++) { | ||
1519 | switch (i) { | ||
1520 | case H_TOTAL_SHADOW_INDEX: | ||
1521 | reg_value = | ||
1522 | IGA2_HOR_TOTAL_SHADOW_FORMULA | ||
1523 | (panel_timing.hor_total); | ||
1524 | viafb_load_reg_Num = | ||
1525 | iga2_shadow_crtc_reg.hor_total_shadow. | ||
1526 | reg_num; | ||
1527 | reg = iga2_shadow_crtc_reg.hor_total_shadow.reg; | ||
1528 | break; | ||
1529 | case H_BLANK_END_SHADOW_INDEX: | ||
1530 | reg_value = | ||
1531 | IGA2_HOR_BLANK_END_SHADOW_FORMULA | ||
1532 | (panel_timing.hor_blank_start, | ||
1533 | panel_timing.hor_blank_end); | ||
1534 | viafb_load_reg_Num = | ||
1535 | iga2_shadow_crtc_reg. | ||
1536 | hor_blank_end_shadow.reg_num; | ||
1537 | reg = | ||
1538 | iga2_shadow_crtc_reg. | ||
1539 | hor_blank_end_shadow.reg; | ||
1540 | break; | ||
1541 | case V_TOTAL_SHADOW_INDEX: | ||
1542 | reg_value = | ||
1543 | IGA2_VER_TOTAL_SHADOW_FORMULA | ||
1544 | (panel_timing.ver_total); | ||
1545 | viafb_load_reg_Num = | ||
1546 | iga2_shadow_crtc_reg.ver_total_shadow. | ||
1547 | reg_num; | ||
1548 | reg = iga2_shadow_crtc_reg.ver_total_shadow.reg; | ||
1549 | break; | ||
1550 | case V_ADDR_SHADOW_INDEX: | ||
1551 | reg_value = | ||
1552 | IGA2_VER_ADDR_SHADOW_FORMULA | ||
1553 | (panel_timing.ver_addr); | ||
1554 | viafb_load_reg_Num = | ||
1555 | iga2_shadow_crtc_reg.ver_addr_shadow. | ||
1556 | reg_num; | ||
1557 | reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg; | ||
1558 | break; | ||
1559 | case V_BLANK_SATRT_SHADOW_INDEX: | ||
1560 | reg_value = | ||
1561 | IGA2_VER_BLANK_START_SHADOW_FORMULA | ||
1562 | (panel_timing.ver_blank_start); | ||
1563 | viafb_load_reg_Num = | ||
1564 | iga2_shadow_crtc_reg. | ||
1565 | ver_blank_start_shadow.reg_num; | ||
1566 | reg = | ||
1567 | iga2_shadow_crtc_reg. | ||
1568 | ver_blank_start_shadow.reg; | ||
1569 | break; | ||
1570 | case V_BLANK_END_SHADOW_INDEX: | ||
1571 | reg_value = | ||
1572 | IGA2_VER_BLANK_END_SHADOW_FORMULA | ||
1573 | (panel_timing.ver_blank_start, | ||
1574 | panel_timing.ver_blank_end); | ||
1575 | viafb_load_reg_Num = | ||
1576 | iga2_shadow_crtc_reg. | ||
1577 | ver_blank_end_shadow.reg_num; | ||
1578 | reg = | ||
1579 | iga2_shadow_crtc_reg. | ||
1580 | ver_blank_end_shadow.reg; | ||
1581 | break; | ||
1582 | case V_SYNC_SATRT_SHADOW_INDEX: | ||
1583 | reg_value = | ||
1584 | IGA2_VER_SYNC_START_SHADOW_FORMULA | ||
1585 | (panel_timing.ver_sync_start); | ||
1586 | viafb_load_reg_Num = | ||
1587 | iga2_shadow_crtc_reg. | ||
1588 | ver_sync_start_shadow.reg_num; | ||
1589 | reg = | ||
1590 | iga2_shadow_crtc_reg. | ||
1591 | ver_sync_start_shadow.reg; | ||
1592 | break; | ||
1593 | case V_SYNC_END_SHADOW_INDEX: | ||
1594 | reg_value = | ||
1595 | IGA2_VER_SYNC_END_SHADOW_FORMULA | ||
1596 | (panel_timing.ver_sync_start, | ||
1597 | panel_timing.ver_sync_end); | ||
1598 | viafb_load_reg_Num = | ||
1599 | iga2_shadow_crtc_reg. | ||
1600 | ver_sync_end_shadow.reg_num; | ||
1601 | reg = | ||
1602 | iga2_shadow_crtc_reg. | ||
1603 | ver_sync_end_shadow.reg; | ||
1604 | break; | ||
1605 | } | ||
1606 | viafb_load_reg(reg_value, | ||
1607 | viafb_load_reg_Num, reg, VIACR); | ||
1608 | } | ||
1609 | } else { /* Centering */ | ||
1610 | for (i = 12; i < 20; i++) { | ||
1611 | switch (i) { | ||
1612 | case H_TOTAL_SHADOW_INDEX: | ||
1613 | reg_value = | ||
1614 | IGA2_HOR_TOTAL_SHADOW_FORMULA | ||
1615 | (panel_timing.hor_total); | ||
1616 | viafb_load_reg_Num = | ||
1617 | iga2_shadow_crtc_reg.hor_total_shadow. | ||
1618 | reg_num; | ||
1619 | reg = iga2_shadow_crtc_reg.hor_total_shadow.reg; | ||
1620 | break; | ||
1621 | case H_BLANK_END_SHADOW_INDEX: | ||
1622 | reg_value = | ||
1623 | IGA2_HOR_BLANK_END_SHADOW_FORMULA | ||
1624 | (panel_timing.hor_blank_start, | ||
1625 | panel_timing.hor_blank_end); | ||
1626 | viafb_load_reg_Num = | ||
1627 | iga2_shadow_crtc_reg. | ||
1628 | hor_blank_end_shadow.reg_num; | ||
1629 | reg = | ||
1630 | iga2_shadow_crtc_reg. | ||
1631 | hor_blank_end_shadow.reg; | ||
1632 | break; | ||
1633 | case V_TOTAL_SHADOW_INDEX: | ||
1634 | reg_value = | ||
1635 | IGA2_VER_TOTAL_SHADOW_FORMULA | ||
1636 | (panel_timing.ver_total); | ||
1637 | viafb_load_reg_Num = | ||
1638 | iga2_shadow_crtc_reg.ver_total_shadow. | ||
1639 | reg_num; | ||
1640 | reg = iga2_shadow_crtc_reg.ver_total_shadow.reg; | ||
1641 | break; | ||
1642 | case V_ADDR_SHADOW_INDEX: | ||
1643 | reg_value = | ||
1644 | IGA2_VER_ADDR_SHADOW_FORMULA | ||
1645 | (mode_timing.ver_addr); | ||
1646 | viafb_load_reg_Num = | ||
1647 | iga2_shadow_crtc_reg.ver_addr_shadow. | ||
1648 | reg_num; | ||
1649 | reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg; | ||
1650 | break; | ||
1651 | case V_BLANK_SATRT_SHADOW_INDEX: | ||
1652 | reg_value = | ||
1653 | IGA2_VER_BLANK_START_SHADOW_FORMULA | ||
1654 | (mode_timing.ver_blank_start); | ||
1655 | viafb_load_reg_Num = | ||
1656 | iga2_shadow_crtc_reg. | ||
1657 | ver_blank_start_shadow.reg_num; | ||
1658 | reg = | ||
1659 | iga2_shadow_crtc_reg. | ||
1660 | ver_blank_start_shadow.reg; | ||
1661 | break; | ||
1662 | case V_BLANK_END_SHADOW_INDEX: | ||
1663 | reg_value = | ||
1664 | IGA2_VER_BLANK_END_SHADOW_FORMULA | ||
1665 | (panel_timing.ver_blank_start, | ||
1666 | panel_timing.ver_blank_end); | ||
1667 | viafb_load_reg_Num = | ||
1668 | iga2_shadow_crtc_reg. | ||
1669 | ver_blank_end_shadow.reg_num; | ||
1670 | reg = | ||
1671 | iga2_shadow_crtc_reg. | ||
1672 | ver_blank_end_shadow.reg; | ||
1673 | break; | ||
1674 | case V_SYNC_SATRT_SHADOW_INDEX: | ||
1675 | reg_value = | ||
1676 | IGA2_VER_SYNC_START_SHADOW_FORMULA( | ||
1677 | (panel_timing.ver_sync_start - | ||
1678 | panel_timing.ver_blank_start) + | ||
1679 | (panel_timing.ver_addr - | ||
1680 | mode_timing.ver_addr) / 2 + | ||
1681 | mode_timing.ver_addr); | ||
1682 | viafb_load_reg_Num = | ||
1683 | iga2_shadow_crtc_reg.ver_sync_start_shadow. | ||
1684 | reg_num; | ||
1685 | reg = | ||
1686 | iga2_shadow_crtc_reg.ver_sync_start_shadow. | ||
1687 | reg; | ||
1688 | break; | ||
1689 | case V_SYNC_END_SHADOW_INDEX: | ||
1690 | reg_value = | ||
1691 | IGA2_VER_SYNC_END_SHADOW_FORMULA( | ||
1692 | (panel_timing.ver_sync_start - | ||
1693 | panel_timing.ver_blank_start) + | ||
1694 | (panel_timing.ver_addr - | ||
1695 | mode_timing.ver_addr) / 2 + | ||
1696 | mode_timing.ver_addr, | ||
1697 | panel_timing.ver_sync_end); | ||
1698 | viafb_load_reg_Num = | ||
1699 | iga2_shadow_crtc_reg.ver_sync_end_shadow. | ||
1700 | reg_num; | ||
1701 | reg = | ||
1702 | iga2_shadow_crtc_reg.ver_sync_end_shadow. | ||
1703 | reg; | ||
1704 | break; | ||
1705 | } | ||
1706 | viafb_load_reg(reg_value, | ||
1707 | viafb_load_reg_Num, reg, VIACR); | ||
1708 | } | ||
1709 | } | ||
1710 | } | ||
1711 | |||
1712 | bool viafb_lcd_get_mobile_state(bool *mobile) | ||
1713 | { | ||
1714 | unsigned char *romptr, *tableptr; | ||
1715 | u8 core_base; | ||
1716 | unsigned char *biosptr; | ||
1717 | /* Rom address */ | ||
1718 | u32 romaddr = 0x000C0000; | ||
1719 | u16 start_pattern = 0; | ||
1720 | |||
1721 | biosptr = ioremap(romaddr, 0x10000); | ||
1722 | |||
1723 | memcpy(&start_pattern, biosptr, 2); | ||
1724 | /* Compare pattern */ | ||
1725 | if (start_pattern == 0xAA55) { | ||
1726 | /* Get the start of Table */ | ||
1727 | /* 0x1B means BIOS offset position */ | ||
1728 | romptr = biosptr + 0x1B; | ||
1729 | tableptr = biosptr + *((u16 *) romptr); | ||
1730 | |||
1731 | /* Get the start of biosver structure */ | ||
1732 | /* 18 means BIOS version position. */ | ||
1733 | romptr = tableptr + 18; | ||
1734 | romptr = biosptr + *((u16 *) romptr); | ||
1735 | |||
1736 | /* The offset should be 44, but the | ||
1737 | actual image is less three char. */ | ||
1738 | /* pRom += 44; */ | ||
1739 | romptr += 41; | ||
1740 | |||
1741 | core_base = *romptr++; | ||
1742 | |||
1743 | if (core_base & 0x8) | ||
1744 | *mobile = false; | ||
1745 | else | ||
1746 | *mobile = true; | ||
1747 | /* release memory */ | ||
1748 | iounmap(biosptr); | ||
1749 | |||
1750 | return true; | ||
1751 | } else { | ||
1752 | iounmap(biosptr); | ||
1753 | return false; | ||
1754 | } | ||
1755 | } | ||
1756 | |||
1757 | static void viafb_load_scaling_factor_for_p4m900(int set_hres, | ||
1758 | int set_vres, int panel_hres, int panel_vres) | ||
1759 | { | ||
1760 | int h_scaling_factor; | ||
1761 | int v_scaling_factor; | ||
1762 | u8 cra2 = 0; | ||
1763 | u8 cr77 = 0; | ||
1764 | u8 cr78 = 0; | ||
1765 | u8 cr79 = 0; | ||
1766 | u8 cr9f = 0; | ||
1767 | /* Check if expansion for horizontal */ | ||
1768 | if (set_hres < panel_hres) { | ||
1769 | /* Load Horizontal Scaling Factor */ | ||
1770 | |||
1771 | /* For VIA_K8M800 or later chipsets. */ | ||
1772 | h_scaling_factor = | ||
1773 | K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); | ||
1774 | /* HSCaleFactor[1:0] at CR9F[1:0] */ | ||
1775 | cr9f = h_scaling_factor & 0x0003; | ||
1776 | /* HSCaleFactor[9:2] at CR77[7:0] */ | ||
1777 | cr77 = (h_scaling_factor & 0x03FC) >> 2; | ||
1778 | /* HSCaleFactor[11:10] at CR79[5:4] */ | ||
1779 | cr79 = (h_scaling_factor & 0x0C00) >> 10; | ||
1780 | cr79 <<= 4; | ||
1781 | |||
1782 | /* Horizontal scaling enabled */ | ||
1783 | cra2 = 0xC0; | ||
1784 | |||
1785 | DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n", | ||
1786 | h_scaling_factor); | ||
1787 | } else { | ||
1788 | /* Horizontal scaling disabled */ | ||
1789 | cra2 = 0x00; | ||
1790 | } | ||
1791 | |||
1792 | /* Check if expansion for vertical */ | ||
1793 | if (set_vres < panel_vres) { | ||
1794 | /* Load Vertical Scaling Factor */ | ||
1795 | |||
1796 | /* For VIA_K8M800 or later chipsets. */ | ||
1797 | v_scaling_factor = | ||
1798 | K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); | ||
1799 | |||
1800 | /* Vertical scaling enabled */ | ||
1801 | cra2 |= 0x08; | ||
1802 | /* VSCaleFactor[0] at CR79[3] */ | ||
1803 | cr79 |= ((v_scaling_factor & 0x0001) << 3); | ||
1804 | /* VSCaleFactor[8:1] at CR78[7:0] */ | ||
1805 | cr78 |= (v_scaling_factor & 0x01FE) >> 1; | ||
1806 | /* VSCaleFactor[10:9] at CR79[7:6] */ | ||
1807 | cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6; | ||
1808 | |||
1809 | DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n", | ||
1810 | v_scaling_factor); | ||
1811 | } else { | ||
1812 | /* Vertical scaling disabled */ | ||
1813 | cra2 |= 0x00; | ||
1814 | } | ||
1815 | |||
1816 | viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7); | ||
1817 | viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF); | ||
1818 | viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF); | ||
1819 | viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8); | ||
1820 | viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1); | ||
1821 | } | ||
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h new file mode 100644 index 000000000000..071f47cf5be1 --- /dev/null +++ b/drivers/video/via/lcd.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #ifndef __LCD_H__ | ||
22 | #define __LCD_H__ | ||
23 | |||
24 | /*Definition TMDS Device ID register*/ | ||
25 | #define VT1631_DEVICE_ID_REG 0x02 | ||
26 | #define VT1631_DEVICE_ID 0x92 | ||
27 | |||
28 | #define VT3271_DEVICE_ID_REG 0x02 | ||
29 | #define VT3271_DEVICE_ID 0x71 | ||
30 | |||
31 | #define GET_LCD_SIZE_BY_SYSTEM_BIOS 0x01 | ||
32 | #define GET_LCD_SIZE_BY_VGA_BIOS 0x02 | ||
33 | #define GET_LCD_SZIE_BY_HW_STRAPPING 0x03 | ||
34 | #define GET_LCD_SIZE_BY_USER_SETTING 0x04 | ||
35 | |||
36 | /* Definition DVI Panel ID*/ | ||
37 | /* Resolution: 640x480, Channel: single, Dithering: Enable */ | ||
38 | #define LCD_PANEL_ID0_640X480 0x00 | ||
39 | /* Resolution: 800x600, Channel: single, Dithering: Enable */ | ||
40 | #define LCD_PANEL_ID1_800X600 0x01 | ||
41 | /* Resolution: 1024x768, Channel: single, Dithering: Enable */ | ||
42 | #define LCD_PANEL_ID2_1024X768 0x02 | ||
43 | /* Resolution: 1280x768, Channel: single, Dithering: Enable */ | ||
44 | #define LCD_PANEL_ID3_1280X768 0x03 | ||
45 | /* Resolution: 1280x1024, Channel: dual, Dithering: Enable */ | ||
46 | #define LCD_PANEL_ID4_1280X1024 0x04 | ||
47 | /* Resolution: 1400x1050, Channel: dual, Dithering: Enable */ | ||
48 | #define LCD_PANEL_ID5_1400X1050 0x05 | ||
49 | /* Resolution: 1600x1200, Channel: dual, Dithering: Enable */ | ||
50 | #define LCD_PANEL_ID6_1600X1200 0x06 | ||
51 | /* Resolution: 1366x768, Channel: single, Dithering: Disable */ | ||
52 | #define LCD_PANEL_ID7_1366X768 0x07 | ||
53 | /* Resolution: 1024x600, Channel: single, Dithering: Enable*/ | ||
54 | #define LCD_PANEL_ID8_1024X600 0x08 | ||
55 | /* Resolution: 1280x800, Channel: single, Dithering: Enable*/ | ||
56 | #define LCD_PANEL_ID9_1280X800 0x09 | ||
57 | /* Resolution: 800x480, Channel: single, Dithering: Enable*/ | ||
58 | #define LCD_PANEL_IDA_800X480 0x0A | ||
59 | /* Resolution: 1360x768, Channel: single, Dithering: Disable*/ | ||
60 | #define LCD_PANEL_IDB_1360X768 0x0B | ||
61 | /* Resolution: 480x640, Channel: single, Dithering: Enable */ | ||
62 | #define LCD_PANEL_IDC_480X640 0x0C | ||
63 | |||
64 | |||
65 | extern int viafb_LCD2_ON; | ||
66 | extern int viafb_LCD_ON; | ||
67 | extern int viafb_DVI_ON; | ||
68 | |||
69 | void viafb_disable_lvds_vt1636(struct lvds_setting_information | ||
70 | *plvds_setting_info, | ||
71 | struct lvds_chip_information *plvds_chip_info); | ||
72 | void viafb_enable_lvds_vt1636(struct lvds_setting_information | ||
73 | *plvds_setting_info, | ||
74 | struct lvds_chip_information *plvds_chip_info); | ||
75 | void viafb_lcd_disable(void); | ||
76 | void viafb_lcd_enable(void); | ||
77 | void viafb_init_lcd_size(void); | ||
78 | void viafb_init_lvds_output_interface(struct lvds_chip_information | ||
79 | *plvds_chip_info, | ||
80 | struct lvds_setting_information | ||
81 | *plvds_setting_info); | ||
82 | void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | ||
83 | struct lvds_setting_information *plvds_setting_info, | ||
84 | struct lvds_chip_information *plvds_chip_info); | ||
85 | int viafb_lvds_trasmitter_identify(void); | ||
86 | void viafb_init_lvds_output_interface(struct lvds_chip_information | ||
87 | *plvds_chip_info, | ||
88 | struct lvds_setting_information | ||
89 | *plvds_setting_info); | ||
90 | bool viafb_lcd_get_mobile_state(bool *mobile); | ||
91 | void viafb_load_crtc_timing(struct display_timing device_timing, | ||
92 | int set_iga); | ||
93 | |||
94 | #endif /* __LCD_H__ */ | ||
diff --git a/drivers/video/via/lcdtbl.h b/drivers/video/via/lcdtbl.h new file mode 100644 index 000000000000..6f3dd800be59 --- /dev/null +++ b/drivers/video/via/lcdtbl.h | |||
@@ -0,0 +1,591 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #ifndef __LCDTBL_H__ | ||
22 | #define __LCDTBL_H__ | ||
23 | |||
24 | #include "share.h" | ||
25 | |||
26 | /* CLE266 Software Power Sequence */ | ||
27 | /* {Mask}, {Data}, {Delay} */ | ||
28 | int PowerSequenceOn[3][3] = | ||
29 | { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} }; | ||
30 | int PowerSequenceOff[3][3] = | ||
31 | { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} }; | ||
32 | |||
33 | /* ++++++ P880 ++++++ */ | ||
34 | /* Panel 1600x1200 */ | ||
35 | struct io_reg P880_LCD_RES_6X4_16X12[] = { | ||
36 | /*IGA2 Horizontal Total */ | ||
37 | {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08}, | ||
38 | /*IGA2 Horizontal Blank End */ | ||
39 | {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00}, | ||
40 | {VIACR, CR5D, 0x40, 0x40}, | ||
41 | /*IGA2 Horizontal Total Shadow */ | ||
42 | {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00}, | ||
43 | /*IGA2 Horizontal Blank End Shadow */ | ||
44 | {VIACR, CR6E, 0xFF, 0x5E}, | ||
45 | /*IGA2 Offset */ | ||
46 | {VIACR, CR66, 0xFF, 0xD6}, {VIACR, CR67, 0x03, 0x00}, | ||
47 | /*VCLK*/ {VIASR, SR44, 0xFF, 0x7D}, {VIASR, SR45, 0xFF, 0x8C}, | ||
48 | {VIASR, SR46, 0xFF, 0x02} | ||
49 | |||
50 | }; | ||
51 | |||
52 | #define NUM_TOTAL_P880_LCD_RES_6X4_16X12 ARRAY_SIZE(P880_LCD_RES_6X4_16X12) | ||
53 | |||
54 | struct io_reg P880_LCD_RES_7X4_16X12[] = { | ||
55 | /*IGA2 Horizontal Total */ | ||
56 | {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08}, | ||
57 | /*IGA2 Horizontal Blank End */ | ||
58 | {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00}, | ||
59 | {VIACR, CR5D, 0x40, 0x40}, | ||
60 | /*IGA2 Horizontal Total Shadow */ | ||
61 | {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00}, | ||
62 | /*IGA2 Horizontal Blank End Shadow */ | ||
63 | {VIACR, CR6E, 0xFF, 0x78}, | ||
64 | /*IGA2 Offset */ | ||
65 | {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00}, | ||
66 | /*VCLK*/ {VIASR, SR44, 0xFF, 0x78}, {VIASR, SR45, 0xFF, 0x8C}, | ||
67 | {VIASR, SR46, 0xFF, 0x01} | ||
68 | |||
69 | }; | ||
70 | |||
71 | #define NUM_TOTAL_P880_LCD_RES_7X4_16X12 ARRAY_SIZE(P880_LCD_RES_7X4_16X12) | ||
72 | |||
73 | struct io_reg P880_LCD_RES_8X6_16X12[] = { | ||
74 | /*IGA2 Horizontal Total */ | ||
75 | {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08}, | ||
76 | /*IGA2 Horizontal Blank End */ | ||
77 | {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00}, | ||
78 | {VIACR, CR5D, 0x40, 0x40}, | ||
79 | /*IGA2 Horizontal Total Shadow */ | ||
80 | {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00}, | ||
81 | /*IGA2 Horizontal Blank End Shadow */ | ||
82 | {VIACR, CR6E, 0xFF, 0x83}, | ||
83 | /*IGA2 Offset */ | ||
84 | {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00}, | ||
85 | /*VCLK*/ {VIASR, SR44, 0xFF, 0x6D}, {VIASR, SR45, 0xFF, 0x88}, | ||
86 | {VIASR, SR46, 0xFF, 0x03} | ||
87 | |||
88 | }; | ||
89 | |||
90 | #define NUM_TOTAL_P880_LCD_RES_8X6_16X12 ARRAY_SIZE(P880_LCD_RES_8X6_16X12) | ||
91 | |||
92 | struct io_reg P880_LCD_RES_10X7_16X12[] = { | ||
93 | /*IGA2 Horizontal Total */ | ||
94 | {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08}, | ||
95 | /*IGA2 Horizontal Blank End */ | ||
96 | {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00}, | ||
97 | {VIACR, CR5D, 0x40, 0x40}, | ||
98 | /*IGA2 Horizontal Total Shadow */ | ||
99 | {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00}, | ||
100 | /*IGA2 Horizontal Blank End Shadow */ | ||
101 | {VIACR, CR6E, 0xFF, 0xAF}, | ||
102 | /*IGA2 Offset */ | ||
103 | {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00}, | ||
104 | /*VCLK*/ {VIASR, SR44, 0xFF, 0x92}, {VIASR, SR45, 0xFF, 0x88}, | ||
105 | {VIASR, SR46, 0xFF, 0x03} | ||
106 | |||
107 | }; | ||
108 | |||
109 | #define NUM_TOTAL_P880_LCD_RES_10X7_16X12 ARRAY_SIZE(P880_LCD_RES_10X7_16X12) | ||
110 | |||
111 | struct io_reg P880_LCD_RES_12X10_16X12[] = { | ||
112 | /*IGA2 Horizontal Total */ | ||
113 | {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08}, | ||
114 | /*IGA2 Horizontal Blank End */ | ||
115 | {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00}, | ||
116 | {VIACR, CR5D, 0x40, 0x40}, | ||
117 | /*IGA2 Horizontal Total Shadow */ | ||
118 | {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00}, | ||
119 | /*IGA2 Horizontal Blank End Shadow */ | ||
120 | {VIACR, CR6E, 0xFF, 0xD4}, | ||
121 | /*IGA2 Offset */ | ||
122 | {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00}, | ||
123 | /*VCLK*/ {VIASR, SR44, 0xFF, 0xF6}, {VIASR, SR45, 0xFF, 0x88}, | ||
124 | {VIASR, SR46, 0xFF, 0x05} | ||
125 | |||
126 | }; | ||
127 | |||
128 | #define NUM_TOTAL_P880_LCD_RES_12X10_16X12 ARRAY_SIZE(P880_LCD_RES_12X10_16X12) | ||
129 | |||
130 | /* Panel 1400x1050 */ | ||
131 | struct io_reg P880_LCD_RES_6X4_14X10[] = { | ||
132 | /* 640x480 */ | ||
133 | /* IGA2 Horizontal Total */ | ||
134 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, | ||
135 | /* IGA2 Horizontal Blank End */ | ||
136 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, | ||
137 | {VIACR, CR5D, 0x40, 0x24}, | ||
138 | /* IGA2 Horizontal Total Shadow */ | ||
139 | {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44}, | ||
140 | /* IGA2 Horizontal Blank End Shadow */ | ||
141 | {VIACR, CR6E, 0xFF, 0x63}, | ||
142 | /* IGA2 Offset */ | ||
143 | {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00}, | ||
144 | /* VCLK */ | ||
145 | {VIASR, SR44, 0xFF, 0xC6}, {VIASR, SR45, 0xFF, 0x8C}, | ||
146 | {VIASR, SR46, 0xFF, 0x05} | ||
147 | }; | ||
148 | |||
149 | #define NUM_TOTAL_P880_LCD_RES_6X4_14X10 ARRAY_SIZE(P880_LCD_RES_6X4_14X10) | ||
150 | |||
151 | struct io_reg P880_LCD_RES_8X6_14X10[] = { | ||
152 | /* 800x600 */ | ||
153 | /* IGA2 Horizontal Total */ | ||
154 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, | ||
155 | /* IGA2 Horizontal Blank End */ | ||
156 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, | ||
157 | {VIACR, CR5D, 0x40, 0x24}, | ||
158 | /* IGA2 Horizontal Total Shadow */ | ||
159 | {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44}, | ||
160 | /* IGA2 Horizontal Blank End Shadow */ | ||
161 | {VIACR, CR6E, 0xFF, 0x83}, | ||
162 | /* IGA2 Offset */ | ||
163 | {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00}, | ||
164 | /* VCLK */ | ||
165 | {VIASR, SR44, 0xFF, 0x06}, {VIASR, SR45, 0xFF, 0x8D}, | ||
166 | {VIASR, SR46, 0xFF, 0x05} | ||
167 | }; | ||
168 | |||
169 | #define NUM_TOTAL_P880_LCD_RES_8X6_14X10 ARRAY_SIZE(P880_LCD_RES_8X6_14X10) | ||
170 | |||
171 | /* ++++++ K400 ++++++ */ | ||
172 | /* Panel 1600x1200 */ | ||
173 | struct io_reg K400_LCD_RES_6X4_16X12[] = { | ||
174 | /*IGA2 Horizontal Total */ | ||
175 | {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08}, | ||
176 | /*IGA2 Horizontal Blank End */ | ||
177 | {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00}, | ||
178 | {VIACR, CR5D, 0x40, 0x40}, | ||
179 | /*IGA2 Horizontal Total Shadow */ | ||
180 | {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00}, | ||
181 | /*IGA2 Horizontal Blank End Shadow */ | ||
182 | {VIACR, CR6E, 0xFF, 0x5E}, | ||
183 | /*IGA2 Offset */ | ||
184 | {VIACR, CR66, 0xFF, 0xDA}, {VIACR, CR67, 0x03, 0x00}, | ||
185 | /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x7F} | ||
186 | }; | ||
187 | |||
188 | #define NUM_TOTAL_K400_LCD_RES_6X4_16X12 ARRAY_SIZE(K400_LCD_RES_6X4_16X12) | ||
189 | |||
190 | struct io_reg K400_LCD_RES_7X4_16X12[] = { | ||
191 | /*IGA2 Horizontal Total */ | ||
192 | {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08}, | ||
193 | /*IGA2 Horizontal Blank End */ | ||
194 | {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00}, | ||
195 | {VIACR, CR5D, 0x40, 0x40}, | ||
196 | /*IGA2 Horizontal Total Shadow */ | ||
197 | {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00}, | ||
198 | /*IGA2 Horizontal Blank End Shadow */ | ||
199 | {VIACR, CR6E, 0xFF, 0x78}, | ||
200 | /*IGA2 Offset */ | ||
201 | {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00}, | ||
202 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x46}, {VIASR, SR47, 0xFF, 0x3D} | ||
203 | }; | ||
204 | |||
205 | #define NUM_TOTAL_K400_LCD_RES_7X4_16X12 ARRAY_SIZE(K400_LCD_RES_7X4_16X12) | ||
206 | |||
207 | struct io_reg K400_LCD_RES_8X6_16X12[] = { | ||
208 | /*IGA2 Horizontal Total */ | ||
209 | {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08}, | ||
210 | /*IGA2 Horizontal Blank End */ | ||
211 | {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00}, | ||
212 | {VIACR, CR5D, 0x40, 0x40}, | ||
213 | /*IGA2 Horizontal Total Shadow */ | ||
214 | {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00}, | ||
215 | /*IGA2 Horizontal Blank End Shadow */ | ||
216 | {VIACR, CR6E, 0xFF, 0x83}, | ||
217 | /*IGA2 Offset */ | ||
218 | {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00}, | ||
219 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x85}, {VIASR, SR47, 0xFF, 0x6F} | ||
220 | }; | ||
221 | |||
222 | #define NUM_TOTAL_K400_LCD_RES_8X6_16X12 ARRAY_SIZE(K400_LCD_RES_8X6_16X12) | ||
223 | |||
224 | struct io_reg K400_LCD_RES_10X7_16X12[] = { | ||
225 | /*IGA2 Horizontal Total */ | ||
226 | {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08}, | ||
227 | /*IGA2 Horizontal Blank End */ | ||
228 | {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00}, | ||
229 | {VIACR, CR5D, 0x40, 0x40}, | ||
230 | /*IGA2 Horizontal Total Shadow */ | ||
231 | {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00}, | ||
232 | /*IGA2 Horizontal Blank End Shadow */ | ||
233 | {VIACR, CR6E, 0xFF, 0xAF}, | ||
234 | /*IGA2 Offset */ | ||
235 | {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00}, | ||
236 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x45}, {VIASR, SR47, 0xFF, 0x4A} | ||
237 | }; | ||
238 | |||
239 | #define NUM_TOTAL_K400_LCD_RES_10X7_16X12 ARRAY_SIZE(K400_LCD_RES_10X7_16X12) | ||
240 | |||
241 | struct io_reg K400_LCD_RES_12X10_16X12[] = { | ||
242 | /*IGA2 Horizontal Total */ | ||
243 | {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08}, | ||
244 | /*IGA2 Horizontal Blank End */ | ||
245 | {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00}, | ||
246 | {VIACR, CR5D, 0x40, 0x40}, | ||
247 | /*IGA2 Horizontal Total Shadow */ | ||
248 | {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00}, | ||
249 | /*IGA2 Horizontal Blank End Shadow */ | ||
250 | {VIACR, CR6E, 0xFF, 0xD4}, | ||
251 | /*IGA2 Offset */ | ||
252 | {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00}, | ||
253 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x47}, {VIASR, SR47, 0xFF, 0x7C} | ||
254 | }; | ||
255 | |||
256 | #define NUM_TOTAL_K400_LCD_RES_12X10_16X12 ARRAY_SIZE(K400_LCD_RES_12X10_16X12) | ||
257 | |||
258 | /* Panel 1400x1050 */ | ||
259 | struct io_reg K400_LCD_RES_6X4_14X10[] = { | ||
260 | /* 640x400 */ | ||
261 | /* IGA2 Horizontal Total */ | ||
262 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, | ||
263 | /* IGA2 Horizontal Blank End */ | ||
264 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, | ||
265 | {VIACR, CR5D, 0x40, 0x24}, | ||
266 | /* IGA2 Horizontal Total Shadow */ | ||
267 | {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44}, | ||
268 | /* IGA2 Horizontal Blank End Shadow */ | ||
269 | {VIACR, CR6E, 0xFF, 0x63}, | ||
270 | /* IGA2 Offset */ | ||
271 | {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00}, | ||
272 | /* VCLK */ | ||
273 | {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19} | ||
274 | }; | ||
275 | |||
276 | #define NUM_TOTAL_K400_LCD_RES_6X4_14X10 ARRAY_SIZE(K400_LCD_RES_6X4_14X10) | ||
277 | |||
278 | struct io_reg K400_LCD_RES_8X6_14X10[] = { | ||
279 | /* 800x600 */ | ||
280 | /* IGA2 Horizontal Total */ | ||
281 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, | ||
282 | /* IGA2 Horizontal Blank End */ | ||
283 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, | ||
284 | {VIACR, CR5D, 0x40, 0x24}, | ||
285 | /* IGA2 Horizontal Total Shadow */ | ||
286 | {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44}, | ||
287 | /* IGA2 Horizontal Blank End Shadow */ | ||
288 | {VIACR, CR6E, 0xFF, 0x83}, | ||
289 | /* IGA2 Offset */ | ||
290 | {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00}, | ||
291 | /* VCLK */ | ||
292 | {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21} | ||
293 | }; | ||
294 | |||
295 | #define NUM_TOTAL_K400_LCD_RES_8X6_14X10 ARRAY_SIZE(K400_LCD_RES_8X6_14X10) | ||
296 | |||
297 | struct io_reg K400_LCD_RES_10X7_14X10[] = { | ||
298 | /* 1024x768 */ | ||
299 | /* IGA2 Horizontal Total */ | ||
300 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, | ||
301 | /* IGA2 Horizontal Blank End */ | ||
302 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, | ||
303 | {VIACR, CR5D, 0x40, 0x24}, | ||
304 | /* IGA2 Horizontal Total Shadow */ | ||
305 | {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44}, | ||
306 | /* IGA2 Horizontal Blank End Shadow */ | ||
307 | {VIACR, CR6E, 0xFF, 0xA7}, | ||
308 | /* IGA2 Offset */ | ||
309 | {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04}, | ||
310 | /* VCLK */ | ||
311 | {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E} | ||
312 | }; | ||
313 | |||
314 | #define NUM_TOTAL_K400_LCD_RES_10X7_14X10 ARRAY_SIZE(K400_LCD_RES_10X7_14X10) | ||
315 | |||
316 | struct io_reg K400_LCD_RES_12X10_14X10[] = { | ||
317 | /* 1280x768, 1280x960, 1280x1024 */ | ||
318 | /* IGA2 Horizontal Total */ | ||
319 | {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56}, | ||
320 | /* IGA2 Horizontal Blank End */ | ||
321 | {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75}, | ||
322 | {VIACR, CR5D, 0x40, 0x24}, | ||
323 | /* IGA2 Horizontal Total Shadow */ | ||
324 | {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44}, | ||
325 | /* IGA2 Horizontal Blank End Shadow */ | ||
326 | {VIACR, CR6E, 0xFF, 0xD2}, | ||
327 | /* IGA2 Offset */ | ||
328 | {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04}, | ||
329 | /* VCLK */ | ||
330 | {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79} | ||
331 | }; | ||
332 | |||
333 | #define NUM_TOTAL_K400_LCD_RES_12X10_14X10 ARRAY_SIZE(K400_LCD_RES_12X10_14X10) | ||
334 | |||
335 | /* ++++++ K400 ++++++ */ | ||
336 | /* Panel 1366x768 */ | ||
337 | struct io_reg K400_LCD_RES_6X4_1366X7[] = { | ||
338 | /* 640x400 */ | ||
339 | /* IGA2 Horizontal Total */ | ||
340 | {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35}, | ||
341 | /* IGA2 Horizontal Blank End */ | ||
342 | {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B}, | ||
343 | {VIACR, CR5D, 0x40, 0x13}, | ||
344 | /* IGA2 Horizontal Total Shadow */ | ||
345 | {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23}, | ||
346 | /* IGA2 Horizontal Blank End Shadow */ | ||
347 | {VIACR, CR6E, 0xFF, 0x64}, | ||
348 | /* IGA2 Offset */ | ||
349 | {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00}, | ||
350 | /* VCLK */ | ||
351 | {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C} | ||
352 | }; | ||
353 | |||
354 | #define NUM_TOTAL_K400_LCD_RES_6X4_1366X7 ARRAY_SIZE(K400_LCD_RES_6X4_1366X7) | ||
355 | |||
356 | struct io_reg K400_LCD_RES_7X4_1366X7[] = { | ||
357 | /* IGA2 Horizontal Total */ | ||
358 | {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35}, | ||
359 | /* IGA2 Horizontal Blank End */ | ||
360 | {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B}, | ||
361 | {VIACR, CR5D, 0x40, 0x13}, | ||
362 | /* IGA2 Horizontal Total Shadow */ | ||
363 | {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23}, | ||
364 | /* IGA2 Horizontal Blank End Shadow */ | ||
365 | {VIACR, CR6E, 0xFF, 0x75}, | ||
366 | /* IGA2 Offset */ | ||
367 | {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00}, | ||
368 | /* VCLK */ | ||
369 | {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10} | ||
370 | }; | ||
371 | |||
372 | #define NUM_TOTAL_K400_LCD_RES_7X4_1366X7 ARRAY_SIZE(K400_LCD_RES_7X4_1366X7) | ||
373 | |||
374 | struct io_reg K400_LCD_RES_8X6_1366X7[] = { | ||
375 | /* 800x600 */ | ||
376 | /* IGA2 Horizontal Total */ | ||
377 | {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35}, | ||
378 | /* IGA2 Horizontal Blank End */ | ||
379 | {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B}, | ||
380 | {VIACR, CR5D, 0x40, 0x13}, | ||
381 | /* IGA2 Horizontal Total Shadow */ | ||
382 | {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23}, | ||
383 | /* IGA2 Horizontal Blank End Shadow */ | ||
384 | {VIACR, CR6E, 0xFF, 0x82}, | ||
385 | /* IGA2 Offset */ | ||
386 | {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00}, | ||
387 | /* VCLK */ | ||
388 | {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9} | ||
389 | }; | ||
390 | |||
391 | #define NUM_TOTAL_K400_LCD_RES_8X6_1366X7 ARRAY_SIZE(K400_LCD_RES_8X6_1366X7) | ||
392 | |||
393 | struct io_reg K400_LCD_RES_10X7_1366X7[] = { | ||
394 | /* 1024x768 */ | ||
395 | /* IGA2 Horizontal Total */ | ||
396 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, | ||
397 | /* IGA2 Horizontal Blank End */ | ||
398 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, | ||
399 | {VIACR, CR5D, 0x40, 0x24}, | ||
400 | /* IGA2 Horizontal Total Shadow */ | ||
401 | {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44}, | ||
402 | /* IGA2 Horizontal Blank End Shadow */ | ||
403 | {VIACR, CR6E, 0xFF, 0xA7}, | ||
404 | /* IGA2 Offset */ | ||
405 | {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04}, | ||
406 | /* VCLK */ | ||
407 | {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E} | ||
408 | }; | ||
409 | |||
410 | #define NUM_TOTAL_K400_LCD_RES_10X7_1366X7 ARRAY_SIZE(K400_LCD_RES_10X7_1366X7) | ||
411 | |||
412 | struct io_reg K400_LCD_RES_12X10_1366X7[] = { | ||
413 | /* 1280x768, 1280x960, 1280x1024 */ | ||
414 | /* IGA2 Horizontal Total */ | ||
415 | {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56}, | ||
416 | /* IGA2 Horizontal Blank End */ | ||
417 | {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75}, | ||
418 | {VIACR, CR5D, 0x40, 0x24}, | ||
419 | /* IGA2 Horizontal Total Shadow */ | ||
420 | {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44}, | ||
421 | /* IGA2 Horizontal Blank End Shadow */ | ||
422 | {VIACR, CR6E, 0xFF, 0xD2}, | ||
423 | /* IGA2 Offset */ | ||
424 | {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04}, | ||
425 | /* VCLK */ | ||
426 | {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79} | ||
427 | }; | ||
428 | |||
429 | #define NUM_TOTAL_K400_LCD_RES_12X10_1366X7\ | ||
430 | ARRAY_SIZE(K400_LCD_RES_12X10_1366X7) | ||
431 | |||
432 | /* ++++++ K400 ++++++ */ | ||
433 | /* Panel 1280x1024 */ | ||
434 | struct io_reg K400_LCD_RES_6X4_12X10[] = { | ||
435 | /*IGA2 Horizontal Total */ | ||
436 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46}, | ||
437 | /*IGA2 Horizontal Blank End */ | ||
438 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74}, | ||
439 | {VIACR, CR5D, 0x40, 0x1C}, | ||
440 | /*IGA2 Horizontal Total Shadow */ | ||
441 | {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x34}, | ||
442 | /*IGA2 Horizontal Blank End Shadow */ | ||
443 | {VIACR, CR6E, 0xFF, 0x63}, | ||
444 | /*IGA2 Offset */ | ||
445 | {VIACR, CR66, 0xFF, 0xAA}, {VIACR, CR67, 0x03, 0x00}, | ||
446 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19} | ||
447 | }; | ||
448 | |||
449 | #define NUM_TOTAL_K400_LCD_RES_6X4_12X10 ARRAY_SIZE(K400_LCD_RES_6X4_12X10) | ||
450 | |||
451 | struct io_reg K400_LCD_RES_7X4_12X10[] = { | ||
452 | /*IGA2 Horizontal Total */ | ||
453 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46}, | ||
454 | /*IGA2 Horizontal Blank End */ | ||
455 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74}, | ||
456 | {VIACR, CR5D, 0x40, 0x1C}, | ||
457 | /*IGA2 Horizontal Total Shadow */ | ||
458 | {VIACR, CR6D, 0xFF, 0x68}, {VIACR, CR71, 0x08, 0x34}, | ||
459 | /*IGA2 Horizontal Blank End Shadow */ | ||
460 | {VIACR, CR6E, 0xFF, 0x6C}, | ||
461 | /*IGA2 Offset */ | ||
462 | {VIACR, CR66, 0xFF, 0xA8}, {VIACR, CR67, 0x03, 0x00}, | ||
463 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0xED} | ||
464 | }; | ||
465 | |||
466 | #define NUM_TOTAL_K400_LCD_RES_7X4_12X10 ARRAY_SIZE(K400_LCD_RES_7X4_12X10) | ||
467 | |||
468 | struct io_reg K400_LCD_RES_8X6_12X10[] = { | ||
469 | /*IGA2 Horizontal Total */ | ||
470 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46}, | ||
471 | /*IGA2 Horizontal Blank End */ | ||
472 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74}, | ||
473 | {VIACR, CR5D, 0x40, 0x1C}, | ||
474 | /*IGA2 Horizontal Total Shadow */ | ||
475 | {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x34}, | ||
476 | /*IGA2 Horizontal Blank End Shadow */ | ||
477 | {VIACR, CR6E, 0xFF, 0x83}, | ||
478 | /*IGA2 Offset */ | ||
479 | {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00}, | ||
480 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21} | ||
481 | }; | ||
482 | |||
483 | #define NUM_TOTAL_K400_LCD_RES_8X6_12X10 ARRAY_SIZE(K400_LCD_RES_8X6_12X10) | ||
484 | |||
485 | struct io_reg K400_LCD_RES_10X7_12X10[] = { | ||
486 | /*IGA2 Horizontal Total */ | ||
487 | {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46}, | ||
488 | /*IGA2 Horizontal Blank End */ | ||
489 | {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74}, | ||
490 | {VIACR, CR5D, 0x40, 0x1C}, | ||
491 | /*IGA2 Horizontal Total Shadow */ | ||
492 | {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x34}, | ||
493 | /*IGA2 Horizontal Blank End Shadow */ | ||
494 | {VIACR, CR6E, 0xFF, 0xA7}, | ||
495 | /*IGA2 Offset */ | ||
496 | {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x04}, | ||
497 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E} | ||
498 | }; | ||
499 | |||
500 | #define NUM_TOTAL_K400_LCD_RES_10X7_12X10 ARRAY_SIZE(K400_LCD_RES_10X7_12X10) | ||
501 | |||
502 | /* ++++++ K400 ++++++ */ | ||
503 | /* Panel 1024x768 */ | ||
504 | struct io_reg K400_LCD_RES_6X4_10X7[] = { | ||
505 | /*IGA2 Horizontal Total */ | ||
506 | {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35}, | ||
507 | /*IGA2 Horizontal Blank End */ | ||
508 | {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B}, | ||
509 | {VIACR, CR5D, 0x40, 0x13}, | ||
510 | /*IGA2 Horizontal Total Shadow */ | ||
511 | {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23}, | ||
512 | /*IGA2 Horizontal Blank End Shadow */ | ||
513 | {VIACR, CR6E, 0xFF, 0x64}, | ||
514 | /*IGA2 Offset */ | ||
515 | {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00}, | ||
516 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C} | ||
517 | }; | ||
518 | |||
519 | #define NUM_TOTAL_K400_LCD_RES_6X4_10X7 ARRAY_SIZE(K400_LCD_RES_6X4_10X7) | ||
520 | |||
521 | struct io_reg K400_LCD_RES_7X4_10X7[] = { | ||
522 | /*IGA2 Horizontal Total */ | ||
523 | {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35}, | ||
524 | /*IGA2 Horizontal Blank End */ | ||
525 | {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B}, | ||
526 | {VIACR, CR5D, 0x40, 0x13}, | ||
527 | /*IGA2 Horizontal Total Shadow */ | ||
528 | {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23}, | ||
529 | /*IGA2 Horizontal Blank End Shadow */ | ||
530 | {VIACR, CR6E, 0xFF, 0x75}, | ||
531 | /*IGA2 Offset */ | ||
532 | {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00}, | ||
533 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10} | ||
534 | }; | ||
535 | |||
536 | #define NUM_TOTAL_K400_LCD_RES_7X4_10X7 ARRAY_SIZE(K400_LCD_RES_7X4_10X7) | ||
537 | |||
538 | struct io_reg K400_LCD_RES_8X6_10X7[] = { | ||
539 | /*IGA2 Horizontal Total */ | ||
540 | {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35}, | ||
541 | /*IGA2 Horizontal Blank End */ | ||
542 | {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B}, | ||
543 | {VIACR, CR5D, 0x40, 0x13}, | ||
544 | /*IGA2 Horizontal Total Shadow */ | ||
545 | {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23}, | ||
546 | /*IGA2 Horizontal Blank End Shadow */ | ||
547 | {VIACR, CR6E, 0xFF, 0x82}, | ||
548 | /*IGA2 Offset */ | ||
549 | {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00}, | ||
550 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9} | ||
551 | }; | ||
552 | |||
553 | #define NUM_TOTAL_K400_LCD_RES_8X6_10X7 ARRAY_SIZE(K400_LCD_RES_8X6_10X7) | ||
554 | |||
555 | /* ++++++ K400 ++++++ */ | ||
556 | /* Panel 800x600 */ | ||
557 | struct io_reg K400_LCD_RES_6X4_8X6[] = { | ||
558 | /*IGA2 Horizontal Total */ | ||
559 | {VIACR, CR50, 0xFF, 0x1A}, {VIACR, CR55, 0x0F, 0x34}, | ||
560 | /*IGA2 Horizontal Blank End */ | ||
561 | {VIACR, CR53, 0xFF, 0x1A}, {VIACR, CR54, 0x38, 0xE3}, | ||
562 | {VIACR, CR5D, 0x40, 0x12}, | ||
563 | /*IGA2 Horizontal Total Shadow */ | ||
564 | {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x22}, | ||
565 | /*IGA2 Horizontal Blank End Shadow */ | ||
566 | {VIACR, CR6E, 0xFF, 0x63}, | ||
567 | /*IGA2 Offset */ | ||
568 | {VIACR, CR66, 0xFF, 0x6E}, {VIACR, CR67, 0x03, 0x00}, | ||
569 | /*VCLK*/ {VIASR, SR46, 0xFF, 0x86}, {VIASR, SR47, 0xFF, 0xB3} | ||
570 | }; | ||
571 | |||
572 | #define NUM_TOTAL_K400_LCD_RES_6X4_8X6 ARRAY_SIZE(K400_LCD_RES_6X4_8X6) | ||
573 | |||
574 | struct io_reg K400_LCD_RES_7X4_8X6[] = { | ||
575 | /*IGA2 Horizontal Total */ | ||
576 | {VIACR, CR50, 0xFF, 0x1F}, {VIACR, CR55, 0x0F, 0x34}, | ||
577 | /*IGA2 Horizontal Blank End */ | ||
578 | {VIACR, CR53, 0xFF, 0x1F}, {VIACR, CR54, 0x38, 0xE3}, | ||
579 | {VIACR, CR5D, 0x40, 0x12}, | ||
580 | /*IGA2 Horizontal Total Shadow */ | ||
581 | {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x22}, | ||
582 | /*IGA2 Horizontal Blank End Shadow */ | ||
583 | {VIACR, CR6E, 0xFF, 0x83}, | ||
584 | /*IGA2 Offset */ | ||
585 | {VIACR, CR66, 0xFF, 0x78}, {VIACR, CR67, 0x03, 0x00}, | ||
586 | /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x59} | ||
587 | }; | ||
588 | |||
589 | #define NUM_TOTAL_K400_LCD_RES_7X4_8X6 ARRAY_SIZE(K400_LCD_RES_7X4_8X6) | ||
590 | |||
591 | #endif /* __LCDTBL_H__ */ | ||
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h new file mode 100644 index 000000000000..2e1254da9c8c --- /dev/null +++ b/drivers/video/via/share.h | |||
@@ -0,0 +1,1105 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __SHARE_H__ | ||
23 | #define __SHARE_H__ | ||
24 | |||
25 | /* Define Return Value */ | ||
26 | #define FAIL -1 | ||
27 | #define OK 1 | ||
28 | |||
29 | #ifndef NULL | ||
30 | #define NULL 0 | ||
31 | #endif | ||
32 | |||
33 | /* Define Bit Field */ | ||
34 | #define BIT0 0x01 | ||
35 | #define BIT1 0x02 | ||
36 | #define BIT2 0x04 | ||
37 | #define BIT3 0x08 | ||
38 | #define BIT4 0x10 | ||
39 | #define BIT5 0x20 | ||
40 | #define BIT6 0x40 | ||
41 | #define BIT7 0x80 | ||
42 | |||
43 | /* Video Memory Size */ | ||
44 | #define VIDEO_MEMORY_SIZE_16M 0x1000000 | ||
45 | |||
46 | /* Definition Mode Index | ||
47 | */ | ||
48 | #define VIA_RES_640X480 0 | ||
49 | #define VIA_RES_800X600 1 | ||
50 | #define VIA_RES_1024X768 2 | ||
51 | #define VIA_RES_1152X864 3 | ||
52 | #define VIA_RES_1280X1024 4 | ||
53 | #define VIA_RES_1600X1200 5 | ||
54 | #define VIA_RES_1440X1050 6 | ||
55 | #define VIA_RES_1280X768 7 | ||
56 | #define VIA_RES_1280X960 8 | ||
57 | #define VIA_RES_1920X1440 9 | ||
58 | #define VIA_RES_848X480 10 | ||
59 | #define VIA_RES_1400X1050 11 | ||
60 | #define VIA_RES_720X480 12 | ||
61 | #define VIA_RES_720X576 13 | ||
62 | #define VIA_RES_1024X512 14 | ||
63 | #define VIA_RES_856X480 15 | ||
64 | #define VIA_RES_1024X576 16 | ||
65 | #define VIA_RES_640X400 17 | ||
66 | #define VIA_RES_1280X720 18 | ||
67 | #define VIA_RES_1920X1080 19 | ||
68 | #define VIA_RES_800X480 20 | ||
69 | #define VIA_RES_1368X768 21 | ||
70 | #define VIA_RES_1024X600 22 | ||
71 | #define VIA_RES_1280X800 23 | ||
72 | #define VIA_RES_1680X1050 24 | ||
73 | #define VIA_RES_960X600 25 | ||
74 | #define VIA_RES_1000X600 26 | ||
75 | #define VIA_RES_1088X612 27 | ||
76 | #define VIA_RES_1152X720 28 | ||
77 | #define VIA_RES_1200X720 29 | ||
78 | #define VIA_RES_1280X600 30 | ||
79 | #define VIA_RES_1360X768 31 | ||
80 | #define VIA_RES_1366X768 32 | ||
81 | #define VIA_RES_1440X900 33 | ||
82 | #define VIA_RES_1600X900 34 | ||
83 | #define VIA_RES_1600X1024 35 | ||
84 | #define VIA_RES_1792X1344 36 | ||
85 | #define VIA_RES_1856X1392 37 | ||
86 | #define VIA_RES_1920X1200 38 | ||
87 | #define VIA_RES_2048X1536 39 | ||
88 | #define VIA_RES_480X640 40 | ||
89 | |||
90 | /*Reduce Blanking*/ | ||
91 | #define VIA_RES_1360X768_RB 131 | ||
92 | #define VIA_RES_1440X900_RB 133 | ||
93 | #define VIA_RES_1400X1050_RB 111 | ||
94 | #define VIA_RES_1600X900_RB 134 | ||
95 | #define VIA_RES_1680X1050_RB 124 | ||
96 | #define VIA_RES_1920X1080_RB 119 | ||
97 | #define VIA_RES_1920X1200_RB 138 | ||
98 | |||
99 | #define VIA_RES_INVALID 255 | ||
100 | |||
101 | /* standard VGA IO port | ||
102 | */ | ||
103 | #define VIARMisc 0x3CC | ||
104 | #define VIAWMisc 0x3C2 | ||
105 | #define VIAStatus 0x3DA | ||
106 | #define VIACR 0x3D4 | ||
107 | #define VIASR 0x3C4 | ||
108 | #define VIAGR 0x3CE | ||
109 | #define VIAAR 0x3C0 | ||
110 | |||
111 | #define StdCR 0x19 | ||
112 | #define StdSR 0x04 | ||
113 | #define StdGR 0x09 | ||
114 | #define StdAR 0x14 | ||
115 | |||
116 | #define PatchCR 11 | ||
117 | |||
118 | /* Display path */ | ||
119 | #define IGA1 1 | ||
120 | #define IGA2 2 | ||
121 | #define IGA1_IGA2 3 | ||
122 | |||
123 | /* Define Color Depth */ | ||
124 | #define MODE_8BPP 1 | ||
125 | #define MODE_16BPP 2 | ||
126 | #define MODE_32BPP 4 | ||
127 | |||
128 | #define GR20 0x20 | ||
129 | #define GR21 0x21 | ||
130 | #define GR22 0x22 | ||
131 | |||
132 | /* Sequencer Registers */ | ||
133 | #define SR01 0x01 | ||
134 | #define SR10 0x10 | ||
135 | #define SR12 0x12 | ||
136 | #define SR15 0x15 | ||
137 | #define SR16 0x16 | ||
138 | #define SR17 0x17 | ||
139 | #define SR18 0x18 | ||
140 | #define SR1B 0x1B | ||
141 | #define SR1A 0x1A | ||
142 | #define SR1C 0x1C | ||
143 | #define SR1D 0x1D | ||
144 | #define SR1E 0x1E | ||
145 | #define SR1F 0x1F | ||
146 | #define SR20 0x20 | ||
147 | #define SR21 0x21 | ||
148 | #define SR22 0x22 | ||
149 | #define SR2A 0x2A | ||
150 | #define SR2D 0x2D | ||
151 | #define SR2E 0x2E | ||
152 | |||
153 | #define SR30 0x30 | ||
154 | #define SR39 0x39 | ||
155 | #define SR3D 0x3D | ||
156 | #define SR3E 0x3E | ||
157 | #define SR3F 0x3F | ||
158 | #define SR40 0x40 | ||
159 | #define SR43 0x43 | ||
160 | #define SR44 0x44 | ||
161 | #define SR45 0x45 | ||
162 | #define SR46 0x46 | ||
163 | #define SR47 0x47 | ||
164 | #define SR48 0x48 | ||
165 | #define SR49 0x49 | ||
166 | #define SR4A 0x4A | ||
167 | #define SR4B 0x4B | ||
168 | #define SR4C 0x4C | ||
169 | #define SR52 0x52 | ||
170 | #define SR5E 0x5E | ||
171 | #define SR65 0x65 | ||
172 | |||
173 | /* CRT Controller Registers */ | ||
174 | #define CR00 0x00 | ||
175 | #define CR01 0x01 | ||
176 | #define CR02 0x02 | ||
177 | #define CR03 0x03 | ||
178 | #define CR04 0x04 | ||
179 | #define CR05 0x05 | ||
180 | #define CR06 0x06 | ||
181 | #define CR07 0x07 | ||
182 | #define CR08 0x08 | ||
183 | #define CR09 0x09 | ||
184 | #define CR0A 0x0A | ||
185 | #define CR0B 0x0B | ||
186 | #define CR0C 0x0C | ||
187 | #define CR0D 0x0D | ||
188 | #define CR0E 0x0E | ||
189 | #define CR0F 0x0F | ||
190 | #define CR10 0x10 | ||
191 | #define CR11 0x11 | ||
192 | #define CR12 0x12 | ||
193 | #define CR13 0x13 | ||
194 | #define CR14 0x14 | ||
195 | #define CR15 0x15 | ||
196 | #define CR16 0x16 | ||
197 | #define CR17 0x17 | ||
198 | #define CR18 0x18 | ||
199 | |||
200 | /* Extend CRT Controller Registers */ | ||
201 | #define CR30 0x30 | ||
202 | #define CR31 0x31 | ||
203 | #define CR32 0x32 | ||
204 | #define CR33 0x33 | ||
205 | #define CR34 0x34 | ||
206 | #define CR35 0x35 | ||
207 | #define CR36 0x36 | ||
208 | #define CR37 0x37 | ||
209 | #define CR38 0x38 | ||
210 | #define CR39 0x39 | ||
211 | #define CR3A 0x3A | ||
212 | #define CR3B 0x3B | ||
213 | #define CR3C 0x3C | ||
214 | #define CR3D 0x3D | ||
215 | #define CR3E 0x3E | ||
216 | #define CR3F 0x3F | ||
217 | #define CR40 0x40 | ||
218 | #define CR41 0x41 | ||
219 | #define CR42 0x42 | ||
220 | #define CR43 0x43 | ||
221 | #define CR44 0x44 | ||
222 | #define CR45 0x45 | ||
223 | #define CR46 0x46 | ||
224 | #define CR47 0x47 | ||
225 | #define CR48 0x48 | ||
226 | #define CR49 0x49 | ||
227 | #define CR4A 0x4A | ||
228 | #define CR4B 0x4B | ||
229 | #define CR4C 0x4C | ||
230 | #define CR4D 0x4D | ||
231 | #define CR4E 0x4E | ||
232 | #define CR4F 0x4F | ||
233 | #define CR50 0x50 | ||
234 | #define CR51 0x51 | ||
235 | #define CR52 0x52 | ||
236 | #define CR53 0x53 | ||
237 | #define CR54 0x54 | ||
238 | #define CR55 0x55 | ||
239 | #define CR56 0x56 | ||
240 | #define CR57 0x57 | ||
241 | #define CR58 0x58 | ||
242 | #define CR59 0x59 | ||
243 | #define CR5A 0x5A | ||
244 | #define CR5B 0x5B | ||
245 | #define CR5C 0x5C | ||
246 | #define CR5D 0x5D | ||
247 | #define CR5E 0x5E | ||
248 | #define CR5F 0x5F | ||
249 | #define CR60 0x60 | ||
250 | #define CR61 0x61 | ||
251 | #define CR62 0x62 | ||
252 | #define CR63 0x63 | ||
253 | #define CR64 0x64 | ||
254 | #define CR65 0x65 | ||
255 | #define CR66 0x66 | ||
256 | #define CR67 0x67 | ||
257 | #define CR68 0x68 | ||
258 | #define CR69 0x69 | ||
259 | #define CR6A 0x6A | ||
260 | #define CR6B 0x6B | ||
261 | #define CR6C 0x6C | ||
262 | #define CR6D 0x6D | ||
263 | #define CR6E 0x6E | ||
264 | #define CR6F 0x6F | ||
265 | #define CR70 0x70 | ||
266 | #define CR71 0x71 | ||
267 | #define CR72 0x72 | ||
268 | #define CR73 0x73 | ||
269 | #define CR74 0x74 | ||
270 | #define CR75 0x75 | ||
271 | #define CR76 0x76 | ||
272 | #define CR77 0x77 | ||
273 | #define CR78 0x78 | ||
274 | #define CR79 0x79 | ||
275 | #define CR7A 0x7A | ||
276 | #define CR7B 0x7B | ||
277 | #define CR7C 0x7C | ||
278 | #define CR7D 0x7D | ||
279 | #define CR7E 0x7E | ||
280 | #define CR7F 0x7F | ||
281 | #define CR80 0x80 | ||
282 | #define CR81 0x81 | ||
283 | #define CR82 0x82 | ||
284 | #define CR83 0x83 | ||
285 | #define CR84 0x84 | ||
286 | #define CR85 0x85 | ||
287 | #define CR86 0x86 | ||
288 | #define CR87 0x87 | ||
289 | #define CR88 0x88 | ||
290 | #define CR89 0x89 | ||
291 | #define CR8A 0x8A | ||
292 | #define CR8B 0x8B | ||
293 | #define CR8C 0x8C | ||
294 | #define CR8D 0x8D | ||
295 | #define CR8E 0x8E | ||
296 | #define CR8F 0x8F | ||
297 | #define CR90 0x90 | ||
298 | #define CR91 0x91 | ||
299 | #define CR92 0x92 | ||
300 | #define CR93 0x93 | ||
301 | #define CR94 0x94 | ||
302 | #define CR95 0x95 | ||
303 | #define CR96 0x96 | ||
304 | #define CR97 0x97 | ||
305 | #define CR98 0x98 | ||
306 | #define CR99 0x99 | ||
307 | #define CR9A 0x9A | ||
308 | #define CR9B 0x9B | ||
309 | #define CR9C 0x9C | ||
310 | #define CR9D 0x9D | ||
311 | #define CR9E 0x9E | ||
312 | #define CR9F 0x9F | ||
313 | #define CRA0 0xA0 | ||
314 | #define CRA1 0xA1 | ||
315 | #define CRA2 0xA2 | ||
316 | #define CRA3 0xA3 | ||
317 | #define CRD2 0xD2 | ||
318 | #define CRD3 0xD3 | ||
319 | #define CRD4 0xD4 | ||
320 | |||
321 | /* LUT Table*/ | ||
322 | #define LUT_DATA 0x3C9 /* DACDATA */ | ||
323 | #define LUT_INDEX_READ 0x3C7 /* DACRX */ | ||
324 | #define LUT_INDEX_WRITE 0x3C8 /* DACWX */ | ||
325 | #define DACMASK 0x3C6 | ||
326 | |||
327 | /* Definition Device */ | ||
328 | #define DEVICE_CRT 0x01 | ||
329 | #define DEVICE_DVI 0x03 | ||
330 | #define DEVICE_LCD 0x04 | ||
331 | |||
332 | /* Device output interface */ | ||
333 | #define INTERFACE_NONE 0x00 | ||
334 | #define INTERFACE_ANALOG_RGB 0x01 | ||
335 | #define INTERFACE_DVP0 0x02 | ||
336 | #define INTERFACE_DVP1 0x03 | ||
337 | #define INTERFACE_DFP_HIGH 0x04 | ||
338 | #define INTERFACE_DFP_LOW 0x05 | ||
339 | #define INTERFACE_DFP 0x06 | ||
340 | #define INTERFACE_LVDS0 0x07 | ||
341 | #define INTERFACE_LVDS1 0x08 | ||
342 | #define INTERFACE_LVDS0LVDS1 0x09 | ||
343 | #define INTERFACE_TMDS 0x0A | ||
344 | |||
345 | #define HW_LAYOUT_LCD_ONLY 0x01 | ||
346 | #define HW_LAYOUT_DVI_ONLY 0x02 | ||
347 | #define HW_LAYOUT_LCD_DVI 0x03 | ||
348 | #define HW_LAYOUT_LCD1_LCD2 0x04 | ||
349 | #define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10 | ||
350 | |||
351 | /* Definition Refresh Rate */ | ||
352 | #define REFRESH_50 50 | ||
353 | #define REFRESH_60 60 | ||
354 | #define REFRESH_75 75 | ||
355 | #define REFRESH_85 85 | ||
356 | #define REFRESH_100 100 | ||
357 | #define REFRESH_120 120 | ||
358 | |||
359 | /* Definition Sync Polarity*/ | ||
360 | #define NEGATIVE 1 | ||
361 | #define POSITIVE 0 | ||
362 | |||
363 | /*480x640@60 Sync Polarity (GTF) | ||
364 | */ | ||
365 | #define M480X640_R60_HSP NEGATIVE | ||
366 | #define M480X640_R60_VSP POSITIVE | ||
367 | |||
368 | /*640x480@60 Sync Polarity (VESA Mode) | ||
369 | */ | ||
370 | #define M640X480_R60_HSP NEGATIVE | ||
371 | #define M640X480_R60_VSP NEGATIVE | ||
372 | |||
373 | /*640x480@75 Sync Polarity (VESA Mode) | ||
374 | */ | ||
375 | #define M640X480_R75_HSP NEGATIVE | ||
376 | #define M640X480_R75_VSP NEGATIVE | ||
377 | |||
378 | /*640x480@85 Sync Polarity (VESA Mode) | ||
379 | */ | ||
380 | #define M640X480_R85_HSP NEGATIVE | ||
381 | #define M640X480_R85_VSP NEGATIVE | ||
382 | |||
383 | /*640x480@100 Sync Polarity (GTF Mode) | ||
384 | */ | ||
385 | #define M640X480_R100_HSP NEGATIVE | ||
386 | #define M640X480_R100_VSP POSITIVE | ||
387 | |||
388 | /*640x480@120 Sync Polarity (GTF Mode) | ||
389 | */ | ||
390 | #define M640X480_R120_HSP NEGATIVE | ||
391 | #define M640X480_R120_VSP POSITIVE | ||
392 | |||
393 | /*720x480@60 Sync Polarity (GTF Mode) | ||
394 | */ | ||
395 | #define M720X480_R60_HSP NEGATIVE | ||
396 | #define M720X480_R60_VSP POSITIVE | ||
397 | |||
398 | /*720x576@60 Sync Polarity (GTF Mode) | ||
399 | */ | ||
400 | #define M720X576_R60_HSP NEGATIVE | ||
401 | #define M720X576_R60_VSP POSITIVE | ||
402 | |||
403 | /*800x600@60 Sync Polarity (VESA Mode) | ||
404 | */ | ||
405 | #define M800X600_R60_HSP POSITIVE | ||
406 | #define M800X600_R60_VSP POSITIVE | ||
407 | |||
408 | /*800x600@75 Sync Polarity (VESA Mode) | ||
409 | */ | ||
410 | #define M800X600_R75_HSP POSITIVE | ||
411 | #define M800X600_R75_VSP POSITIVE | ||
412 | |||
413 | /*800x600@85 Sync Polarity (VESA Mode) | ||
414 | */ | ||
415 | #define M800X600_R85_HSP POSITIVE | ||
416 | #define M800X600_R85_VSP POSITIVE | ||
417 | |||
418 | /*800x600@100 Sync Polarity (GTF Mode) | ||
419 | */ | ||
420 | #define M800X600_R100_HSP NEGATIVE | ||
421 | #define M800X600_R100_VSP POSITIVE | ||
422 | |||
423 | /*800x600@120 Sync Polarity (GTF Mode) | ||
424 | */ | ||
425 | #define M800X600_R120_HSP NEGATIVE | ||
426 | #define M800X600_R120_VSP POSITIVE | ||
427 | |||
428 | /*800x480@60 Sync Polarity (CVT Mode) | ||
429 | */ | ||
430 | #define M800X480_R60_HSP NEGATIVE | ||
431 | #define M800X480_R60_VSP POSITIVE | ||
432 | |||
433 | /*848x480@60 Sync Polarity (CVT Mode) | ||
434 | */ | ||
435 | #define M848X480_R60_HSP NEGATIVE | ||
436 | #define M848X480_R60_VSP POSITIVE | ||
437 | |||
438 | /*852x480@60 Sync Polarity (GTF Mode) | ||
439 | */ | ||
440 | #define M852X480_R60_HSP NEGATIVE | ||
441 | #define M852X480_R60_VSP POSITIVE | ||
442 | |||
443 | /*1024x512@60 Sync Polarity (GTF Mode) | ||
444 | */ | ||
445 | #define M1024X512_R60_HSP NEGATIVE | ||
446 | #define M1024X512_R60_VSP POSITIVE | ||
447 | |||
448 | /*1024x600@60 Sync Polarity (GTF Mode) | ||
449 | */ | ||
450 | #define M1024X600_R60_HSP NEGATIVE | ||
451 | #define M1024X600_R60_VSP POSITIVE | ||
452 | |||
453 | /*1024x768@60 Sync Polarity (VESA Mode) | ||
454 | */ | ||
455 | #define M1024X768_R60_HSP NEGATIVE | ||
456 | #define M1024X768_R60_VSP NEGATIVE | ||
457 | |||
458 | /*1024x768@75 Sync Polarity (VESA Mode) | ||
459 | */ | ||
460 | #define M1024X768_R75_HSP POSITIVE | ||
461 | #define M1024X768_R75_VSP POSITIVE | ||
462 | |||
463 | /*1024x768@85 Sync Polarity (VESA Mode) | ||
464 | */ | ||
465 | #define M1024X768_R85_HSP POSITIVE | ||
466 | #define M1024X768_R85_VSP POSITIVE | ||
467 | |||
468 | /*1024x768@100 Sync Polarity (GTF Mode) | ||
469 | */ | ||
470 | #define M1024X768_R100_HSP NEGATIVE | ||
471 | #define M1024X768_R100_VSP POSITIVE | ||
472 | |||
473 | /*1152x864@75 Sync Polarity (VESA Mode) | ||
474 | */ | ||
475 | #define M1152X864_R75_HSP POSITIVE | ||
476 | #define M1152X864_R75_VSP POSITIVE | ||
477 | |||
478 | /*1280x720@60 Sync Polarity (GTF Mode) | ||
479 | */ | ||
480 | #define M1280X720_R60_HSP NEGATIVE | ||
481 | #define M1280X720_R60_VSP POSITIVE | ||
482 | |||
483 | /* 1280x768@50 Sync Polarity (GTF Mode) */ | ||
484 | #define M1280X768_R50_HSP NEGATIVE | ||
485 | #define M1280X768_R50_VSP POSITIVE | ||
486 | |||
487 | /*1280x768@60 Sync Polarity (GTF Mode) | ||
488 | */ | ||
489 | #define M1280X768_R60_HSP NEGATIVE | ||
490 | #define M1280X768_R60_VSP POSITIVE | ||
491 | |||
492 | /*1280x800@60 Sync Polarity (CVT Mode) | ||
493 | */ | ||
494 | #define M1280X800_R60_HSP NEGATIVE | ||
495 | #define M1280X800_R60_VSP POSITIVE | ||
496 | |||
497 | /*1280x960@60 Sync Polarity (VESA Mode) | ||
498 | */ | ||
499 | #define M1280X960_R60_HSP POSITIVE | ||
500 | #define M1280X960_R60_VSP POSITIVE | ||
501 | |||
502 | /*1280x1024@60 Sync Polarity (VESA Mode) | ||
503 | */ | ||
504 | #define M1280X1024_R60_HSP POSITIVE | ||
505 | #define M1280X1024_R60_VSP POSITIVE | ||
506 | |||
507 | /* 1360x768@60 Sync Polarity (CVT Mode) */ | ||
508 | #define M1360X768_R60_HSP POSITIVE | ||
509 | #define M1360X768_R60_VSP POSITIVE | ||
510 | |||
511 | /* 1360x768@60 Sync Polarity (CVT Reduce Blanking Mode) */ | ||
512 | #define M1360X768_RB_R60_HSP POSITIVE | ||
513 | #define M1360X768_RB_R60_VSP NEGATIVE | ||
514 | |||
515 | /* 1368x768@50 Sync Polarity (GTF Mode) */ | ||
516 | #define M1368X768_R50_HSP NEGATIVE | ||
517 | #define M1368X768_R50_VSP POSITIVE | ||
518 | |||
519 | /* 1368x768@60 Sync Polarity (VESA Mode) */ | ||
520 | #define M1368X768_R60_HSP NEGATIVE | ||
521 | #define M1368X768_R60_VSP POSITIVE | ||
522 | |||
523 | /*1280x1024@75 Sync Polarity (VESA Mode) | ||
524 | */ | ||
525 | #define M1280X1024_R75_HSP POSITIVE | ||
526 | #define M1280X1024_R75_VSP POSITIVE | ||
527 | |||
528 | /*1280x1024@85 Sync Polarity (VESA Mode) | ||
529 | */ | ||
530 | #define M1280X1024_R85_HSP POSITIVE | ||
531 | #define M1280X1024_R85_VSP POSITIVE | ||
532 | |||
533 | /*1440x1050@60 Sync Polarity (GTF Mode) | ||
534 | */ | ||
535 | #define M1440X1050_R60_HSP NEGATIVE | ||
536 | #define M1440X1050_R60_VSP POSITIVE | ||
537 | |||
538 | /*1600x1200@60 Sync Polarity (VESA Mode) | ||
539 | */ | ||
540 | #define M1600X1200_R60_HSP POSITIVE | ||
541 | #define M1600X1200_R60_VSP POSITIVE | ||
542 | |||
543 | /*1600x1200@75 Sync Polarity (VESA Mode) | ||
544 | */ | ||
545 | #define M1600X1200_R75_HSP POSITIVE | ||
546 | #define M1600X1200_R75_VSP POSITIVE | ||
547 | |||
548 | /* 1680x1050@60 Sync Polarity (CVT Mode) */ | ||
549 | #define M1680x1050_R60_HSP NEGATIVE | ||
550 | #define M1680x1050_R60_VSP NEGATIVE | ||
551 | |||
552 | /* 1680x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */ | ||
553 | #define M1680x1050_RB_R60_HSP POSITIVE | ||
554 | #define M1680x1050_RB_R60_VSP NEGATIVE | ||
555 | |||
556 | /* 1680x1050@75 Sync Polarity (CVT Mode) */ | ||
557 | #define M1680x1050_R75_HSP NEGATIVE | ||
558 | #define M1680x1050_R75_VSP POSITIVE | ||
559 | |||
560 | /*1920x1080@60 Sync Polarity (CVT Mode) | ||
561 | */ | ||
562 | #define M1920X1080_R60_HSP NEGATIVE | ||
563 | #define M1920X1080_R60_VSP POSITIVE | ||
564 | |||
565 | /* 1920x1080@60 Sync Polarity (CVT Reduce Blanking Mode) */ | ||
566 | #define M1920X1080_RB_R60_HSP POSITIVE | ||
567 | #define M1920X1080_RB_R60_VSP NEGATIVE | ||
568 | |||
569 | /*1920x1440@60 Sync Polarity (VESA Mode) | ||
570 | */ | ||
571 | #define M1920X1440_R60_HSP NEGATIVE | ||
572 | #define M1920X1440_R60_VSP POSITIVE | ||
573 | |||
574 | /*1920x1440@75 Sync Polarity (VESA Mode) | ||
575 | */ | ||
576 | #define M1920X1440_R75_HSP NEGATIVE | ||
577 | #define M1920X1440_R75_VSP POSITIVE | ||
578 | |||
579 | #if 0 | ||
580 | /* 1400x1050@60 Sync Polarity (VESA Mode) */ | ||
581 | #define M1400X1050_R60_HSP NEGATIVE | ||
582 | #define M1400X1050_R60_VSP NEGATIVE | ||
583 | #endif | ||
584 | |||
585 | /* 1400x1050@60 Sync Polarity (CVT Mode) */ | ||
586 | #define M1400X1050_R60_HSP NEGATIVE | ||
587 | #define M1400X1050_R60_VSP POSITIVE | ||
588 | |||
589 | /* 1400x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */ | ||
590 | #define M1400X1050_RB_R60_HSP POSITIVE | ||
591 | #define M1400X1050_RB_R60_VSP NEGATIVE | ||
592 | |||
593 | /* 1400x1050@75 Sync Polarity (CVT Mode) */ | ||
594 | #define M1400X1050_R75_HSP NEGATIVE | ||
595 | #define M1400X1050_R75_VSP POSITIVE | ||
596 | |||
597 | /* 960x600@60 Sync Polarity (CVT Mode) */ | ||
598 | #define M960X600_R60_HSP NEGATIVE | ||
599 | #define M960X600_R60_VSP POSITIVE | ||
600 | |||
601 | /* 1000x600@60 Sync Polarity (GTF Mode) */ | ||
602 | #define M1000X600_R60_HSP NEGATIVE | ||
603 | #define M1000X600_R60_VSP POSITIVE | ||
604 | |||
605 | /* 1024x576@60 Sync Polarity (GTF Mode) */ | ||
606 | #define M1024X576_R60_HSP NEGATIVE | ||
607 | #define M1024X576_R60_VSP POSITIVE | ||
608 | |||
609 | /*1024x600@60 Sync Polarity (GTF Mode)*/ | ||
610 | #define M1024X600_R60_HSP NEGATIVE | ||
611 | #define M1024X600_R60_VSP POSITIVE | ||
612 | |||
613 | /* 1088x612@60 Sync Polarity (CVT Mode) */ | ||
614 | #define M1088X612_R60_HSP NEGATIVE | ||
615 | #define M1088X612_R60_VSP POSITIVE | ||
616 | |||
617 | /* 1152x720@60 Sync Polarity (CVT Mode) */ | ||
618 | #define M1152X720_R60_HSP NEGATIVE | ||
619 | #define M1152X720_R60_VSP POSITIVE | ||
620 | |||
621 | /* 1200x720@60 Sync Polarity (GTF Mode) */ | ||
622 | #define M1200X720_R60_HSP NEGATIVE | ||
623 | #define M1200X720_R60_VSP POSITIVE | ||
624 | |||
625 | /* 1280x600@60 Sync Polarity (GTF Mode) */ | ||
626 | #define M1280x600_R60_HSP NEGATIVE | ||
627 | #define M1280x600_R60_VSP POSITIVE | ||
628 | |||
629 | /* 1280x720@50 Sync Polarity (GTF Mode) */ | ||
630 | #define M1280X720_R50_HSP NEGATIVE | ||
631 | #define M1280X720_R50_VSP POSITIVE | ||
632 | |||
633 | /* 1280x720@60 Sync Polarity (CEA Mode) */ | ||
634 | #define M1280X720_CEA_R60_HSP POSITIVE | ||
635 | #define M1280X720_CEA_R60_VSP POSITIVE | ||
636 | |||
637 | /* 1440x900@60 Sync Polarity (CVT Mode) */ | ||
638 | #define M1440X900_R60_HSP NEGATIVE | ||
639 | #define M1440X900_R60_VSP POSITIVE | ||
640 | |||
641 | /* 1440x900@75 Sync Polarity (CVT Mode) */ | ||
642 | #define M1440X900_R75_HSP NEGATIVE | ||
643 | #define M1440X900_R75_VSP POSITIVE | ||
644 | |||
645 | /* 1440x900@60 Sync Polarity (CVT Reduce Blanking Mode) */ | ||
646 | #define M1440X900_RB_R60_HSP POSITIVE | ||
647 | #define M1440X900_RB_R60_VSP NEGATIVE | ||
648 | |||
649 | /* 1600x900@60 Sync Polarity (CVT Mode) */ | ||
650 | #define M1600X900_R60_HSP NEGATIVE | ||
651 | #define M1600X900_R60_VSP POSITIVE | ||
652 | |||
653 | /* 1600x900@60 Sync Polarity (CVT Reduce Blanking Mode) */ | ||
654 | #define M1600X900_RB_R60_HSP POSITIVE | ||
655 | #define M1600X900_RB_R60_VSP NEGATIVE | ||
656 | |||
657 | /* 1600x1024@60 Sync Polarity (GTF Mode) */ | ||
658 | #define M1600X1024_R60_HSP NEGATIVE | ||
659 | #define M1600X1024_R60_VSP POSITIVE | ||
660 | |||
661 | /* 1792x1344@60 Sync Polarity (DMT Mode) */ | ||
662 | #define M1792x1344_R60_HSP NEGATIVE | ||
663 | #define M1792x1344_R60_VSP POSITIVE | ||
664 | |||
665 | /* 1856x1392@60 Sync Polarity (DMT Mode) */ | ||
666 | #define M1856x1392_R60_HSP NEGATIVE | ||
667 | #define M1856x1392_R60_VSP POSITIVE | ||
668 | |||
669 | /* 1920x1200@60 Sync Polarity (CVT Mode) */ | ||
670 | #define M1920X1200_R60_HSP NEGATIVE | ||
671 | #define M1920X1200_R60_VSP POSITIVE | ||
672 | |||
673 | /* 1920x1200@60 Sync Polarity (CVT Reduce Blanking Mode) */ | ||
674 | #define M1920X1200_RB_R60_HSP POSITIVE | ||
675 | #define M1920X1200_RB_R60_VSP NEGATIVE | ||
676 | |||
677 | /* 1920x1080@60 Sync Polarity (CEA Mode) */ | ||
678 | #define M1920X1080_CEA_R60_HSP POSITIVE | ||
679 | #define M1920X1080_CEA_R60_VSP POSITIVE | ||
680 | |||
681 | /* 2048x1536@60 Sync Polarity (CVT Mode) */ | ||
682 | #define M2048x1536_R60_HSP NEGATIVE | ||
683 | #define M2048x1536_R60_VSP POSITIVE | ||
684 | |||
685 | /* define PLL index: */ | ||
686 | #define CLK_25_175M 25175000 | ||
687 | #define CLK_26_880M 26880000 | ||
688 | #define CLK_29_581M 29581000 | ||
689 | #define CLK_31_490M 31490000 | ||
690 | #define CLK_31_500M 31500000 | ||
691 | #define CLK_31_728M 31728000 | ||
692 | #define CLK_32_668M 32688000 | ||
693 | #define CLK_36_000M 36000000 | ||
694 | #define CLK_40_000M 40000000 | ||
695 | #define CLK_41_291M 41291000 | ||
696 | #define CLK_43_163M 43163000 | ||
697 | #define CLK_45_250M 45250000 /* 45.46MHz */ | ||
698 | #define CLK_46_000M 46000000 | ||
699 | #define CLK_46_996M 46996000 | ||
700 | #define CLK_48_000M 48000000 | ||
701 | #define CLK_48_875M 48875000 | ||
702 | #define CLK_49_500M 49500000 | ||
703 | #define CLK_52_406M 52406000 | ||
704 | #define CLK_52_977M 52977000 | ||
705 | #define CLK_56_250M 56250000 | ||
706 | #define CLK_60_466M 60466000 | ||
707 | #define CLK_61_500M 61500000 | ||
708 | #define CLK_65_000M 65000000 | ||
709 | #define CLK_65_178M 65178000 | ||
710 | #define CLK_66_750M 66750000 /* 67.116MHz */ | ||
711 | #define CLK_68_179M 68179000 | ||
712 | #define CLK_69_924M 69924000 | ||
713 | #define CLK_70_159M 70159000 | ||
714 | #define CLK_72_000M 72000000 | ||
715 | #define CLK_74_270M 74270000 | ||
716 | #define CLK_78_750M 78750000 | ||
717 | #define CLK_80_136M 80136000 | ||
718 | #define CLK_83_375M 83375000 | ||
719 | #define CLK_83_950M 83950000 | ||
720 | #define CLK_84_750M 84750000 /* 84.537Mhz */ | ||
721 | #define CLK_85_860M 85860000 | ||
722 | #define CLK_88_750M 88750000 | ||
723 | #define CLK_94_500M 94500000 | ||
724 | #define CLK_97_750M 97750000 | ||
725 | #define CLK_101_000M 101000000 | ||
726 | #define CLK_106_500M 106500000 | ||
727 | #define CLK_108_000M 108000000 | ||
728 | #define CLK_113_309M 113309000 | ||
729 | #define CLK_118_840M 118840000 | ||
730 | #define CLK_119_000M 119000000 | ||
731 | #define CLK_121_750M 121750000 /* 121.704MHz */ | ||
732 | #define CLK_125_104M 125104000 | ||
733 | #define CLK_133_308M 133308000 | ||
734 | #define CLK_135_000M 135000000 | ||
735 | #define CLK_136_700M 136700000 | ||
736 | #define CLK_138_400M 138400000 | ||
737 | #define CLK_146_760M 146760000 | ||
738 | #define CLK_148_500M 148500000 | ||
739 | |||
740 | #define CLK_153_920M 153920000 | ||
741 | #define CLK_156_000M 156000000 | ||
742 | #define CLK_157_500M 157500000 | ||
743 | #define CLK_162_000M 162000000 | ||
744 | #define CLK_187_000M 187000000 | ||
745 | #define CLK_193_295M 193295000 | ||
746 | #define CLK_202_500M 202500000 | ||
747 | #define CLK_204_000M 204000000 | ||
748 | #define CLK_218_500M 218500000 | ||
749 | #define CLK_234_000M 234000000 | ||
750 | #define CLK_267_250M 267250000 | ||
751 | #define CLK_297_500M 297500000 | ||
752 | #define CLK_74_481M 74481000 | ||
753 | #define CLK_172_798M 172798000 | ||
754 | #define CLK_122_614M 122614000 | ||
755 | |||
756 | /* CLE266 PLL value | ||
757 | */ | ||
758 | #define CLE266_PLL_25_175M 0x0000C763 | ||
759 | #define CLE266_PLL_26_880M 0x0000440F | ||
760 | #define CLE266_PLL_29_581M 0x00008421 | ||
761 | #define CLE266_PLL_31_490M 0x00004721 | ||
762 | #define CLE266_PLL_31_500M 0x0000C3B5 | ||
763 | #define CLE266_PLL_31_728M 0x0000471F | ||
764 | #define CLE266_PLL_32_668M 0x0000C449 | ||
765 | #define CLE266_PLL_36_000M 0x0000C5E5 | ||
766 | #define CLE266_PLL_40_000M 0x0000C459 | ||
767 | #define CLE266_PLL_41_291M 0x00004417 | ||
768 | #define CLE266_PLL_43_163M 0x0000C579 | ||
769 | #define CLE266_PLL_45_250M 0x0000C57F /* 45.46MHz */ | ||
770 | #define CLE266_PLL_46_000M 0x0000875A | ||
771 | #define CLE266_PLL_46_996M 0x0000C4E9 | ||
772 | #define CLE266_PLL_48_000M 0x00001443 | ||
773 | #define CLE266_PLL_48_875M 0x00001D63 | ||
774 | #define CLE266_PLL_49_500M 0x00008653 | ||
775 | #define CLE266_PLL_52_406M 0x0000C475 | ||
776 | #define CLE266_PLL_52_977M 0x00004525 | ||
777 | #define CLE266_PLL_56_250M 0x000047B7 | ||
778 | #define CLE266_PLL_60_466M 0x0000494C | ||
779 | #define CLE266_PLL_61_500M 0x00001456 | ||
780 | #define CLE266_PLL_65_000M 0x000086ED | ||
781 | #define CLE266_PLL_65_178M 0x0000855B | ||
782 | #define CLE266_PLL_66_750M 0x0000844B /* 67.116MHz */ | ||
783 | #define CLE266_PLL_68_179M 0x00000413 | ||
784 | #define CLE266_PLL_69_924M 0x00001153 | ||
785 | #define CLE266_PLL_70_159M 0x00001462 | ||
786 | #define CLE266_PLL_72_000M 0x00001879 | ||
787 | #define CLE266_PLL_74_270M 0x00004853 | ||
788 | #define CLE266_PLL_78_750M 0x00004321 | ||
789 | #define CLE266_PLL_80_136M 0x0000051C | ||
790 | #define CLE266_PLL_83_375M 0x0000C25D | ||
791 | #define CLE266_PLL_83_950M 0x00000729 | ||
792 | #define CLE266_PLL_84_750M 0x00008576 /* 84.537MHz */ | ||
793 | #define CLE266_PLL_85_860M 0x00004754 | ||
794 | #define CLE266_PLL_88_750M 0x0000051F | ||
795 | #define CLE266_PLL_94_500M 0x00000521 | ||
796 | #define CLE266_PLL_97_750M 0x00004652 | ||
797 | #define CLE266_PLL_101_000M 0x0000497F | ||
798 | #define CLE266_PLL_106_500M 0x00008477 /* 106.491463 MHz */ | ||
799 | #define CLE266_PLL_108_000M 0x00008479 | ||
800 | #define CLE266_PLL_113_309M 0x00000C5F | ||
801 | #define CLE266_PLL_118_840M 0x00004553 | ||
802 | #define CLE266_PLL_119_000M 0x00000D6C | ||
803 | #define CLE266_PLL_121_750M 0x00004555 /* 121.704MHz */ | ||
804 | #define CLE266_PLL_125_104M 0x000006B5 | ||
805 | #define CLE266_PLL_133_308M 0x0000465F | ||
806 | #define CLE266_PLL_135_000M 0x0000455E | ||
807 | #define CLE266_PLL_136_700M 0x00000C73 | ||
808 | #define CLE266_PLL_138_400M 0x00000957 | ||
809 | #define CLE266_PLL_146_760M 0x00004567 | ||
810 | #define CLE266_PLL_148_500M 0x00000853 | ||
811 | #define CLE266_PLL_153_920M 0x00000856 | ||
812 | #define CLE266_PLL_156_000M 0x0000456D | ||
813 | #define CLE266_PLL_157_500M 0x000005B7 | ||
814 | #define CLE266_PLL_162_000M 0x00004571 | ||
815 | #define CLE266_PLL_187_000M 0x00000976 | ||
816 | #define CLE266_PLL_193_295M 0x0000086C | ||
817 | #define CLE266_PLL_202_500M 0x00000763 | ||
818 | #define CLE266_PLL_204_000M 0x00000764 | ||
819 | #define CLE266_PLL_218_500M 0x0000065C | ||
820 | #define CLE266_PLL_234_000M 0x00000662 | ||
821 | #define CLE266_PLL_267_250M 0x00000670 | ||
822 | #define CLE266_PLL_297_500M 0x000005E6 | ||
823 | #define CLE266_PLL_74_481M 0x0000051A | ||
824 | #define CLE266_PLL_172_798M 0x00004579 | ||
825 | #define CLE266_PLL_122_614M 0x0000073C | ||
826 | |||
827 | /* K800 PLL value | ||
828 | */ | ||
829 | #define K800_PLL_25_175M 0x00539001 | ||
830 | #define K800_PLL_26_880M 0x001C8C80 | ||
831 | #define K800_PLL_29_581M 0x00409080 | ||
832 | #define K800_PLL_31_490M 0x006F9001 | ||
833 | #define K800_PLL_31_500M 0x008B9002 | ||
834 | #define K800_PLL_31_728M 0x00AF9003 | ||
835 | #define K800_PLL_32_668M 0x00909002 | ||
836 | #define K800_PLL_36_000M 0x009F9002 | ||
837 | #define K800_PLL_40_000M 0x00578C02 | ||
838 | #define K800_PLL_41_291M 0x00438C01 | ||
839 | #define K800_PLL_43_163M 0x00778C03 | ||
840 | #define K800_PLL_45_250M 0x007D8C83 /* 45.46MHz */ | ||
841 | #define K800_PLL_46_000M 0x00658C02 | ||
842 | #define K800_PLL_46_996M 0x00818C83 | ||
843 | #define K800_PLL_48_000M 0x00848C83 | ||
844 | #define K800_PLL_48_875M 0x00508C81 | ||
845 | #define K800_PLL_49_500M 0x00518C01 | ||
846 | #define K800_PLL_52_406M 0x00738C02 | ||
847 | #define K800_PLL_52_977M 0x00928C83 | ||
848 | #define K800_PLL_56_250M 0x007C8C02 | ||
849 | #define K800_PLL_60_466M 0x00A78C83 | ||
850 | #define K800_PLL_61_500M 0x00AA8C83 | ||
851 | #define K800_PLL_65_000M 0x006B8C01 | ||
852 | #define K800_PLL_65_178M 0x00B48C83 | ||
853 | #define K800_PLL_66_750M 0x00948C82 /* 67.116MHz */ | ||
854 | #define K800_PLL_68_179M 0x00708C01 | ||
855 | #define K800_PLL_69_924M 0x00C18C83 | ||
856 | #define K800_PLL_70_159M 0x00C28C83 | ||
857 | #define K800_PLL_72_000M 0x009F8C82 | ||
858 | #define K800_PLL_74_270M 0x00ce0c03 | ||
859 | #define K800_PLL_78_750M 0x00408801 | ||
860 | #define K800_PLL_80_136M 0x00428801 | ||
861 | #define K800_PLL_83_375M 0x005B0882 | ||
862 | #define K800_PLL_83_950M 0x00738803 | ||
863 | #define K800_PLL_84_750M 0x00748883 /* 84.477MHz */ | ||
864 | #define K800_PLL_85_860M 0x00768883 | ||
865 | #define K800_PLL_88_750M 0x007A8883 | ||
866 | #define K800_PLL_94_500M 0x00828803 | ||
867 | #define K800_PLL_97_750M 0x00878883 | ||
868 | #define K800_PLL_101_000M 0x008B8883 | ||
869 | #define K800_PLL_106_500M 0x00758882 /* 106.491463 MHz */ | ||
870 | #define K800_PLL_108_000M 0x00778882 | ||
871 | #define K800_PLL_113_309M 0x005D8881 | ||
872 | #define K800_PLL_118_840M 0x00A48883 | ||
873 | #define K800_PLL_119_000M 0x00838882 | ||
874 | #define K800_PLL_121_750M 0x00A88883 /* 121.704MHz */ | ||
875 | #define K800_PLL_125_104M 0x00688801 | ||
876 | #define K800_PLL_133_308M 0x005D8801 | ||
877 | #define K800_PLL_135_000M 0x001A4081 | ||
878 | #define K800_PLL_136_700M 0x00BD8883 | ||
879 | #define K800_PLL_138_400M 0x00728881 | ||
880 | #define K800_PLL_146_760M 0x00CC8883 | ||
881 | #define K800_PLL_148_500M 0x00ce0803 | ||
882 | #define K800_PLL_153_920M 0x00548482 | ||
883 | #define K800_PLL_156_000M 0x006B8483 | ||
884 | #define K800_PLL_157_500M 0x00142080 | ||
885 | #define K800_PLL_162_000M 0x006F8483 | ||
886 | #define K800_PLL_187_000M 0x00818483 | ||
887 | #define K800_PLL_193_295M 0x004F8481 | ||
888 | #define K800_PLL_202_500M 0x00538481 | ||
889 | #define K800_PLL_204_000M 0x008D8483 | ||
890 | #define K800_PLL_218_500M 0x00978483 | ||
891 | #define K800_PLL_234_000M 0x00608401 | ||
892 | #define K800_PLL_267_250M 0x006E8481 | ||
893 | #define K800_PLL_297_500M 0x00A48402 | ||
894 | #define K800_PLL_74_481M 0x007B8C81 | ||
895 | #define K800_PLL_172_798M 0x00778483 | ||
896 | #define K800_PLL_122_614M 0x00878882 | ||
897 | |||
898 | /* PLL for VT3324 */ | ||
899 | #define CX700_25_175M 0x008B1003 | ||
900 | #define CX700_26_719M 0x00931003 | ||
901 | #define CX700_26_880M 0x00941003 | ||
902 | #define CX700_29_581M 0x00A49003 | ||
903 | #define CX700_31_490M 0x00AE1003 | ||
904 | #define CX700_31_500M 0x00AE1003 | ||
905 | #define CX700_31_728M 0x00AF1003 | ||
906 | #define CX700_32_668M 0x00B51003 | ||
907 | #define CX700_36_000M 0x00C81003 | ||
908 | #define CX700_40_000M 0x006E0C03 | ||
909 | #define CX700_41_291M 0x00710C03 | ||
910 | #define CX700_43_163M 0x00770C03 | ||
911 | #define CX700_45_250M 0x007D0C03 /* 45.46MHz */ | ||
912 | #define CX700_46_000M 0x007F0C03 | ||
913 | #define CX700_46_996M 0x00818C83 | ||
914 | #define CX700_48_000M 0x00840C03 | ||
915 | #define CX700_48_875M 0x00508C81 | ||
916 | #define CX700_49_500M 0x00880C03 | ||
917 | #define CX700_52_406M 0x00730C02 | ||
918 | #define CX700_52_977M 0x00920C03 | ||
919 | #define CX700_56_250M 0x009B0C03 | ||
920 | #define CX700_60_466M 0x00460C00 | ||
921 | #define CX700_61_500M 0x00AA0C03 | ||
922 | #define CX700_65_000M 0x006B0C01 | ||
923 | #define CX700_65_178M 0x006B0C01 | ||
924 | #define CX700_66_750M 0x00940C02 /*67.116MHz */ | ||
925 | #define CX700_68_179M 0x00BC0C03 | ||
926 | #define CX700_69_924M 0x00C10C03 | ||
927 | #define CX700_70_159M 0x00C20C03 | ||
928 | #define CX700_72_000M 0x009F0C02 | ||
929 | #define CX700_74_270M 0x00CE0C03 | ||
930 | #define CX700_74_481M 0x00CE0C03 | ||
931 | #define CX700_78_750M 0x006C0803 | ||
932 | #define CX700_80_136M 0x006E0803 | ||
933 | #define CX700_83_375M 0x005B0882 | ||
934 | #define CX700_83_950M 0x00730803 | ||
935 | #define CX700_84_750M 0x00740803 /* 84.537Mhz */ | ||
936 | #define CX700_85_860M 0x00760803 | ||
937 | #define CX700_88_750M 0x00AC8885 | ||
938 | #define CX700_94_500M 0x00820803 | ||
939 | #define CX700_97_750M 0x00870803 | ||
940 | #define CX700_101_000M 0x008B0803 | ||
941 | #define CX700_106_500M 0x00750802 | ||
942 | #define CX700_108_000M 0x00950803 | ||
943 | #define CX700_113_309M 0x005D0801 | ||
944 | #define CX700_118_840M 0x00A40803 | ||
945 | #define CX700_119_000M 0x00830802 | ||
946 | #define CX700_121_750M 0x00420800 /* 121.704MHz */ | ||
947 | #define CX700_125_104M 0x00AD0803 | ||
948 | #define CX700_133_308M 0x00930802 | ||
949 | #define CX700_135_000M 0x00950802 | ||
950 | #define CX700_136_700M 0x00BD0803 | ||
951 | #define CX700_138_400M 0x00720801 | ||
952 | #define CX700_146_760M 0x00CC0803 | ||
953 | #define CX700_148_500M 0x00a40802 | ||
954 | #define CX700_153_920M 0x00540402 | ||
955 | #define CX700_156_000M 0x006B0403 | ||
956 | #define CX700_157_500M 0x006C0403 | ||
957 | #define CX700_162_000M 0x006F0403 | ||
958 | #define CX700_172_798M 0x00770403 | ||
959 | #define CX700_187_000M 0x00810403 | ||
960 | #define CX700_193_295M 0x00850403 | ||
961 | #define CX700_202_500M 0x008C0403 | ||
962 | #define CX700_204_000M 0x008D0403 | ||
963 | #define CX700_218_500M 0x00970403 | ||
964 | #define CX700_234_000M 0x00600401 | ||
965 | #define CX700_267_250M 0x00B90403 | ||
966 | #define CX700_297_500M 0x00CE0403 | ||
967 | #define CX700_122_614M 0x00870802 | ||
968 | |||
969 | /* Definition CRTC Timing Index */ | ||
970 | #define H_TOTAL_INDEX 0 | ||
971 | #define H_ADDR_INDEX 1 | ||
972 | #define H_BLANK_START_INDEX 2 | ||
973 | #define H_BLANK_END_INDEX 3 | ||
974 | #define H_SYNC_START_INDEX 4 | ||
975 | #define H_SYNC_END_INDEX 5 | ||
976 | #define V_TOTAL_INDEX 6 | ||
977 | #define V_ADDR_INDEX 7 | ||
978 | #define V_BLANK_START_INDEX 8 | ||
979 | #define V_BLANK_END_INDEX 9 | ||
980 | #define V_SYNC_START_INDEX 10 | ||
981 | #define V_SYNC_END_INDEX 11 | ||
982 | #define H_TOTAL_SHADOW_INDEX 12 | ||
983 | #define H_BLANK_END_SHADOW_INDEX 13 | ||
984 | #define V_TOTAL_SHADOW_INDEX 14 | ||
985 | #define V_ADDR_SHADOW_INDEX 15 | ||
986 | #define V_BLANK_SATRT_SHADOW_INDEX 16 | ||
987 | #define V_BLANK_END_SHADOW_INDEX 17 | ||
988 | #define V_SYNC_SATRT_SHADOW_INDEX 18 | ||
989 | #define V_SYNC_END_SHADOW_INDEX 19 | ||
990 | |||
991 | /* Definition Video Mode Pixel Clock (picoseconds) | ||
992 | */ | ||
993 | #define RES_480X640_60HZ_PIXCLOCK 39722 | ||
994 | #define RES_640X480_60HZ_PIXCLOCK 39722 | ||
995 | #define RES_640X480_75HZ_PIXCLOCK 31747 | ||
996 | #define RES_640X480_85HZ_PIXCLOCK 27777 | ||
997 | #define RES_640X480_100HZ_PIXCLOCK 23168 | ||
998 | #define RES_640X480_120HZ_PIXCLOCK 19081 | ||
999 | #define RES_720X480_60HZ_PIXCLOCK 37020 | ||
1000 | #define RES_720X576_60HZ_PIXCLOCK 30611 | ||
1001 | #define RES_800X600_60HZ_PIXCLOCK 25000 | ||
1002 | #define RES_800X600_75HZ_PIXCLOCK 20203 | ||
1003 | #define RES_800X600_85HZ_PIXCLOCK 17777 | ||
1004 | #define RES_800X600_100HZ_PIXCLOCK 14667 | ||
1005 | #define RES_800X600_120HZ_PIXCLOCK 11912 | ||
1006 | #define RES_800X480_60HZ_PIXCLOCK 33805 | ||
1007 | #define RES_848X480_60HZ_PIXCLOCK 31756 | ||
1008 | #define RES_856X480_60HZ_PIXCLOCK 31518 | ||
1009 | #define RES_1024X512_60HZ_PIXCLOCK 24218 | ||
1010 | #define RES_1024X600_60HZ_PIXCLOCK 20460 | ||
1011 | #define RES_1024X768_60HZ_PIXCLOCK 15385 | ||
1012 | #define RES_1024X768_75HZ_PIXCLOCK 12699 | ||
1013 | #define RES_1024X768_85HZ_PIXCLOCK 10582 | ||
1014 | #define RES_1024X768_100HZ_PIXCLOCK 8825 | ||
1015 | #define RES_1152X864_75HZ_PIXCLOCK 9259 | ||
1016 | #define RES_1280X768_60HZ_PIXCLOCK 12480 | ||
1017 | #define RES_1280X800_60HZ_PIXCLOCK 11994 | ||
1018 | #define RES_1280X960_60HZ_PIXCLOCK 9259 | ||
1019 | #define RES_1280X1024_60HZ_PIXCLOCK 9260 | ||
1020 | #define RES_1280X1024_75HZ_PIXCLOCK 7408 | ||
1021 | #define RES_1280X768_85HZ_PIXCLOCK 6349 | ||
1022 | #define RES_1440X1050_60HZ_PIXCLOCK 7993 | ||
1023 | #define RES_1600X1200_60HZ_PIXCLOCK 6172 | ||
1024 | #define RES_1600X1200_75HZ_PIXCLOCK 4938 | ||
1025 | #define RES_1280X720_60HZ_PIXCLOCK 13426 | ||
1026 | #define RES_1920X1080_60HZ_PIXCLOCK 5787 | ||
1027 | #define RES_1400X1050_60HZ_PIXCLOCK 8214 | ||
1028 | #define RES_1400X1050_75HZ_PIXCLOCK 6410 | ||
1029 | #define RES_1368X768_60HZ_PIXCLOCK 11647 | ||
1030 | #define RES_960X600_60HZ_PIXCLOCK 22099 | ||
1031 | #define RES_1000X600_60HZ_PIXCLOCK 20834 | ||
1032 | #define RES_1024X576_60HZ_PIXCLOCK 21278 | ||
1033 | #define RES_1088X612_60HZ_PIXCLOCK 18877 | ||
1034 | #define RES_1152X720_60HZ_PIXCLOCK 14981 | ||
1035 | #define RES_1200X720_60HZ_PIXCLOCK 14253 | ||
1036 | #define RES_1280X600_60HZ_PIXCLOCK 16260 | ||
1037 | #define RES_1280X720_50HZ_PIXCLOCK 16538 | ||
1038 | #define RES_1280X768_50HZ_PIXCLOCK 15342 | ||
1039 | #define RES_1366X768_50HZ_PIXCLOCK 14301 | ||
1040 | #define RES_1366X768_60HZ_PIXCLOCK 11646 | ||
1041 | #define RES_1360X768_60HZ_PIXCLOCK 11799 | ||
1042 | #define RES_1440X900_60HZ_PIXCLOCK 9390 | ||
1043 | #define RES_1440X900_75HZ_PIXCLOCK 7315 | ||
1044 | #define RES_1600X900_60HZ_PIXCLOCK 8415 | ||
1045 | #define RES_1600X1024_60HZ_PIXCLOCK 7315 | ||
1046 | #define RES_1680X1050_60HZ_PIXCLOCK 6814 | ||
1047 | #define RES_1680X1050_75HZ_PIXCLOCK 5348 | ||
1048 | #define RES_1792X1344_60HZ_PIXCLOCK 4902 | ||
1049 | #define RES_1856X1392_60HZ_PIXCLOCK 4577 | ||
1050 | #define RES_1920X1200_60HZ_PIXCLOCK 5173 | ||
1051 | #define RES_1920X1440_60HZ_PIXCLOCK 4274 | ||
1052 | #define RES_1920X1440_75HZ_PIXCLOCK 3367 | ||
1053 | #define RES_2048X1536_60HZ_PIXCLOCK 3742 | ||
1054 | |||
1055 | #define RES_1360X768_RB_60HZ_PIXCLOCK 13889 | ||
1056 | #define RES_1400X1050_RB_60HZ_PIXCLOCK 9901 | ||
1057 | #define RES_1440X900_RB_60HZ_PIXCLOCK 11268 | ||
1058 | #define RES_1600X900_RB_60HZ_PIXCLOCK 10230 | ||
1059 | #define RES_1680X1050_RB_60HZ_PIXCLOCK 8403 | ||
1060 | #define RES_1920X1080_RB_60HZ_PIXCLOCK 7225 | ||
1061 | #define RES_1920X1200_RB_60HZ_PIXCLOCK 6497 | ||
1062 | |||
1063 | /* LCD display method | ||
1064 | */ | ||
1065 | #define LCD_EXPANDSION 0x00 | ||
1066 | #define LCD_CENTERING 0x01 | ||
1067 | |||
1068 | /* LCD mode | ||
1069 | */ | ||
1070 | #define LCD_OPENLDI 0x00 | ||
1071 | #define LCD_SPWG 0x01 | ||
1072 | |||
1073 | /* Define display timing | ||
1074 | */ | ||
1075 | struct display_timing { | ||
1076 | u16 hor_total; | ||
1077 | u16 hor_addr; | ||
1078 | u16 hor_blank_start; | ||
1079 | u16 hor_blank_end; | ||
1080 | u16 hor_sync_start; | ||
1081 | u16 hor_sync_end; | ||
1082 | u16 ver_total; | ||
1083 | u16 ver_addr; | ||
1084 | u16 ver_blank_start; | ||
1085 | u16 ver_blank_end; | ||
1086 | u16 ver_sync_start; | ||
1087 | u16 ver_sync_end; | ||
1088 | }; | ||
1089 | |||
1090 | struct crt_mode_table { | ||
1091 | int refresh_rate; | ||
1092 | unsigned long clk; | ||
1093 | int h_sync_polarity; | ||
1094 | int v_sync_polarity; | ||
1095 | struct display_timing crtc; | ||
1096 | }; | ||
1097 | |||
1098 | struct io_reg { | ||
1099 | int port; | ||
1100 | u8 index; | ||
1101 | u8 mask; | ||
1102 | u8 value; | ||
1103 | }; | ||
1104 | |||
1105 | #endif /* __SHARE_H__ */ | ||
diff --git a/drivers/video/via/tbl1636.c b/drivers/video/via/tbl1636.c new file mode 100644 index 000000000000..2d8453429d4a --- /dev/null +++ b/drivers/video/via/tbl1636.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | struct IODATA COMMON_INIT_TBL_VT1636[] = { | ||
24 | /* Index, Mask, Value */ | ||
25 | /* Set panel power sequence timing */ | ||
26 | {0x10, 0xC0, 0x00}, | ||
27 | /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */ | ||
28 | {0x0B, 0xFF, 0x40}, | ||
29 | /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */ | ||
30 | {0x0C, 0xFF, 0x31}, | ||
31 | /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/ | ||
32 | {0x0D, 0xFF, 0x31}, | ||
33 | /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */ | ||
34 | {0x0E, 0xFF, 0x68}, | ||
35 | /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */ | ||
36 | {0x0F, 0xFF, 0x68}, | ||
37 | /* LVDS output power up */ | ||
38 | {0x09, 0xA0, 0xA0}, | ||
39 | /* turn on back light */ | ||
40 | {0x10, 0x33, 0x13} | ||
41 | }; | ||
42 | |||
43 | struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[] = { | ||
44 | /* Index, Mask, Value */ | ||
45 | {0x08, 0xF0, 0xE0} /* Input Data Mode Select */ | ||
46 | }; | ||
47 | |||
48 | struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[] = { | ||
49 | /* Index, Mask, Value */ | ||
50 | {0x08, 0xF0, 0x00} /* Input Data Mode Select */ | ||
51 | }; | ||
52 | |||
53 | struct IODATA DITHERING_ENABLE_TBL_VT1636[] = { | ||
54 | /* Index, Mask, Value */ | ||
55 | {0x0A, 0x70, 0x50} | ||
56 | }; | ||
57 | |||
58 | struct IODATA DITHERING_DISABLE_TBL_VT1636[] = { | ||
59 | /* Index, Mask, Value */ | ||
60 | {0x0A, 0x70, 0x00} | ||
61 | }; | ||
62 | |||
63 | struct IODATA VDD_ON_TBL_VT1636[] = { | ||
64 | /* Index, Mask, Value */ | ||
65 | {0x10, 0x20, 0x20} | ||
66 | }; | ||
67 | |||
68 | struct IODATA VDD_OFF_TBL_VT1636[] = { | ||
69 | /* Index, Mask, Value */ | ||
70 | {0x10, 0x20, 0x00} | ||
71 | }; | ||
diff --git a/drivers/video/via/tbl1636.h b/drivers/video/via/tbl1636.h new file mode 100644 index 000000000000..d906055f1511 --- /dev/null +++ b/drivers/video/via/tbl1636.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef _TBL1636_H_ | ||
23 | #define _TBL1636_H_ | ||
24 | #include "hw.h" | ||
25 | |||
26 | extern struct IODATA COMMON_INIT_TBL_VT1636[8]; | ||
27 | extern struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[1]; | ||
28 | extern struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[1]; | ||
29 | extern struct IODATA DITHERING_ENABLE_TBL_VT1636[1]; | ||
30 | extern struct IODATA DITHERING_DISABLE_TBL_VT1636[1]; | ||
31 | extern struct IODATA VDD_ON_TBL_VT1636[1]; | ||
32 | extern struct IODATA VDD_OFF_TBL_VT1636[1]; | ||
33 | |||
34 | #endif /* _VIA_TBL1636_H_ */ | ||
diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/via/tblDPASetting.c new file mode 100644 index 000000000000..0c4c8cc712f4 --- /dev/null +++ b/drivers/video/via/tblDPASetting.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | /* For VT3324: */ | ||
24 | struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[] = { | ||
25 | /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */ | ||
26 | {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */ | ||
27 | {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */ | ||
28 | {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */ | ||
29 | {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */ | ||
30 | {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */ | ||
31 | {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */ | ||
32 | {LCD_PANEL_ID6_1600X1200, 0x0B, 0x03} /* For 1600x1200 */ | ||
33 | }; | ||
34 | |||
35 | struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = { | ||
36 | /* ClkRange, DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, | ||
37 | DVP1Driving, DFPHigh, DFPLow */ | ||
38 | /* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B, | ||
39 | SR65, CR97, CR99 */ | ||
40 | /* LCK/VCK < 30000000 will use this value */ | ||
41 | {DPA_CLK_RANGE_30M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, | ||
42 | 0x00}, | ||
43 | /* 30000000 < LCK/VCK < 50000000 will use this value */ | ||
44 | {DPA_CLK_RANGE_30_50M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, | ||
45 | 0x00}, | ||
46 | /* 50000000 < LCK/VCK < 70000000 will use this value */ | ||
47 | {DPA_CLK_RANGE_50_70M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, | ||
48 | 0x00}, | ||
49 | /* 70000000 < LCK/VCK < 100000000 will use this value */ | ||
50 | {DPA_CLK_RANGE_70_100M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, | ||
51 | 0x00}, | ||
52 | /* 100000000 < LCK/VCK < 15000000 will use this value */ | ||
53 | {DPA_CLK_RANGE_100_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, | ||
54 | 0x00}, | ||
55 | /* 15000000 < LCK/VCK will use this value */ | ||
56 | {DPA_CLK_RANGE_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x00, | ||
57 | 0x00}, | ||
58 | }; | ||
59 | |||
60 | /* For VT3327: */ | ||
61 | struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[] = { | ||
62 | /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */ | ||
63 | {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */ | ||
64 | {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */ | ||
65 | {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */ | ||
66 | {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */ | ||
67 | {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */ | ||
68 | {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */ | ||
69 | {LCD_PANEL_ID6_1600X1200, 0x00, 0x00} /* For 1600x1200 */ | ||
70 | }; | ||
71 | |||
72 | struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = { | ||
73 | /* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, | ||
74 | DVP1Driving, DFPHigh, DFPLow */ | ||
75 | /* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B, | ||
76 | SR65, CR97, CR99 */ | ||
77 | /* LCK/VCK < 30000000 will use this value */ | ||
78 | {DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01}, | ||
79 | /* 30000000 < LCK/VCK < 50000000 will use this value */ | ||
80 | {DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01}, | ||
81 | /* 50000000 < LCK/VCK < 70000000 will use this value */ | ||
82 | {DPA_CLK_RANGE_50_70M, 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01}, | ||
83 | /* 70000000 < LCK/VCK < 100000000 will use this value */ | ||
84 | {DPA_CLK_RANGE_70_100M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x03}, | ||
85 | /* 100000000 < LCK/VCK < 15000000 will use this value */ | ||
86 | {DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02}, | ||
87 | /* 15000000 < LCK/VCK will use this value */ | ||
88 | {DPA_CLK_RANGE_150M, 0x00, 0x20, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0D, 0x03}, | ||
89 | }; | ||
90 | |||
91 | /* For VT3364: */ | ||
92 | struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[] = { | ||
93 | /* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, | ||
94 | DVP1Driving, DFPHigh, DFPLow */ | ||
95 | /* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B, | ||
96 | SR65, CR97, CR99 */ | ||
97 | /* LCK/VCK < 30000000 will use this value */ | ||
98 | {DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08}, | ||
99 | /* 30000000 < LCK/VCK < 50000000 will use this value */ | ||
100 | {DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08}, | ||
101 | /* 50000000 < LCK/VCK < 70000000 will use this value */ | ||
102 | {DPA_CLK_RANGE_50_70M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08}, | ||
103 | /* 70000000 < LCK/VCK < 100000000 will use this value */ | ||
104 | {DPA_CLK_RANGE_70_100M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08}, | ||
105 | /* 100000000 < LCK/VCK < 15000000 will use this value */ | ||
106 | {DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08}, | ||
107 | /* 15000000 < LCK/VCK will use this value */ | ||
108 | {DPA_CLK_RANGE_150M, 0x01, 0x00, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x08}, | ||
109 | }; | ||
diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/via/tblDPASetting.h new file mode 100644 index 000000000000..b065a83481d3 --- /dev/null +++ b/drivers/video/via/tblDPASetting.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef _TBLDPASETTING_H_ | ||
23 | #define _TBLDPASETTING_H_ | ||
24 | #include "global.h" | ||
25 | |||
26 | #define DPA_CLK_30M 30000000 | ||
27 | #define DPA_CLK_50M 50000000 | ||
28 | #define DPA_CLK_70M 70000000 | ||
29 | #define DPA_CLK_100M 100000000 | ||
30 | #define DPA_CLK_150M 150000000 | ||
31 | |||
32 | enum DPA_RANGE { | ||
33 | DPA_CLK_RANGE_30M, | ||
34 | DPA_CLK_RANGE_30_50M, | ||
35 | DPA_CLK_RANGE_50_70M, | ||
36 | DPA_CLK_RANGE_70_100M, | ||
37 | DPA_CLK_RANGE_100_150M, | ||
38 | DPA_CLK_RANGE_150M | ||
39 | }; | ||
40 | |||
41 | extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[7]; | ||
42 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6]; | ||
43 | extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[7]; | ||
44 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[]; | ||
45 | extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6]; | ||
46 | |||
47 | #endif | ||
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c new file mode 100644 index 000000000000..0f3ed4eb236d --- /dev/null +++ b/drivers/video/via/via_i2c.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | |||
24 | static void via_i2c_setscl(void *data, int state) | ||
25 | { | ||
26 | u8 val; | ||
27 | struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; | ||
28 | |||
29 | val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; | ||
30 | if (state) | ||
31 | val |= 0x20; | ||
32 | else | ||
33 | val &= ~0x20; | ||
34 | switch (via_i2c_chan->i2c_port) { | ||
35 | case I2CPORTINDEX: | ||
36 | val |= 0x01; | ||
37 | break; | ||
38 | case GPIOPORTINDEX: | ||
39 | val |= 0x80; | ||
40 | break; | ||
41 | default: | ||
42 | DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); | ||
43 | } | ||
44 | viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); | ||
45 | } | ||
46 | |||
47 | static int via_i2c_getscl(void *data) | ||
48 | { | ||
49 | struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; | ||
50 | |||
51 | if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08) | ||
52 | return 1; | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static int via_i2c_getsda(void *data) | ||
57 | { | ||
58 | struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; | ||
59 | |||
60 | if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04) | ||
61 | return 1; | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static void via_i2c_setsda(void *data, int state) | ||
66 | { | ||
67 | u8 val; | ||
68 | struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; | ||
69 | |||
70 | val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; | ||
71 | if (state) | ||
72 | val |= 0x10; | ||
73 | else | ||
74 | val &= ~0x10; | ||
75 | switch (via_i2c_chan->i2c_port) { | ||
76 | case I2CPORTINDEX: | ||
77 | val |= 0x01; | ||
78 | break; | ||
79 | case GPIOPORTINDEX: | ||
80 | val |= 0x40; | ||
81 | break; | ||
82 | default: | ||
83 | DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); | ||
84 | } | ||
85 | viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); | ||
86 | } | ||
87 | |||
88 | int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata) | ||
89 | { | ||
90 | u8 mm1[] = {0x00}; | ||
91 | struct i2c_msg msgs[2]; | ||
92 | |||
93 | *pdata = 0; | ||
94 | msgs[0].flags = 0; | ||
95 | msgs[1].flags = I2C_M_RD; | ||
96 | msgs[0].addr = msgs[1].addr = slave_addr / 2; | ||
97 | mm1[0] = index; | ||
98 | msgs[0].len = 1; msgs[1].len = 1; | ||
99 | msgs[0].buf = mm1; msgs[1].buf = pdata; | ||
100 | i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2); | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data) | ||
106 | { | ||
107 | u8 msg[2] = { index, data }; | ||
108 | struct i2c_msg msgs; | ||
109 | |||
110 | msgs.flags = 0; | ||
111 | msgs.addr = slave_addr / 2; | ||
112 | msgs.len = 2; | ||
113 | msgs.buf = msg; | ||
114 | return i2c_transfer(&viaparinfo->i2c_stuff.adapter, &msgs, 1); | ||
115 | } | ||
116 | |||
117 | int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) | ||
118 | { | ||
119 | u8 mm1[] = {0x00}; | ||
120 | struct i2c_msg msgs[2]; | ||
121 | |||
122 | msgs[0].flags = 0; | ||
123 | msgs[1].flags = I2C_M_RD; | ||
124 | msgs[0].addr = msgs[1].addr = slave_addr / 2; | ||
125 | mm1[0] = index; | ||
126 | msgs[0].len = 1; msgs[1].len = buff_len; | ||
127 | msgs[0].buf = mm1; msgs[1].buf = buff; | ||
128 | i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | int viafb_create_i2c_bus(void *viapar) | ||
133 | { | ||
134 | int ret; | ||
135 | struct viafb_par *par = (struct viafb_par *)viapar; | ||
136 | |||
137 | strcpy(par->i2c_stuff.adapter.name, "via_i2c"); | ||
138 | par->i2c_stuff.i2c_port = 0x0; | ||
139 | par->i2c_stuff.adapter.owner = THIS_MODULE; | ||
140 | par->i2c_stuff.adapter.id = 0x01FFFF; | ||
141 | par->i2c_stuff.adapter.class = 0; | ||
142 | par->i2c_stuff.adapter.algo_data = &par->i2c_stuff.algo; | ||
143 | par->i2c_stuff.adapter.dev.parent = NULL; | ||
144 | par->i2c_stuff.algo.setsda = via_i2c_setsda; | ||
145 | par->i2c_stuff.algo.setscl = via_i2c_setscl; | ||
146 | par->i2c_stuff.algo.getsda = via_i2c_getsda; | ||
147 | par->i2c_stuff.algo.getscl = via_i2c_getscl; | ||
148 | par->i2c_stuff.algo.udelay = 40; | ||
149 | par->i2c_stuff.algo.timeout = 20; | ||
150 | par->i2c_stuff.algo.data = &par->i2c_stuff; | ||
151 | |||
152 | i2c_set_adapdata(&par->i2c_stuff.adapter, &par->i2c_stuff); | ||
153 | |||
154 | /* Raise SCL and SDA */ | ||
155 | par->i2c_stuff.i2c_port = I2CPORTINDEX; | ||
156 | via_i2c_setsda(&par->i2c_stuff, 1); | ||
157 | via_i2c_setscl(&par->i2c_stuff, 1); | ||
158 | |||
159 | par->i2c_stuff.i2c_port = GPIOPORTINDEX; | ||
160 | via_i2c_setsda(&par->i2c_stuff, 1); | ||
161 | via_i2c_setscl(&par->i2c_stuff, 1); | ||
162 | udelay(20); | ||
163 | |||
164 | ret = i2c_bit_add_bus(&par->i2c_stuff.adapter); | ||
165 | if (ret == 0) | ||
166 | DEBUG_MSG("I2C bus %s registered.\n", | ||
167 | par->i2c_stuff.adapter.name); | ||
168 | else | ||
169 | DEBUG_MSG("Failed to register I2C bus %s.\n", | ||
170 | par->i2c_stuff.adapter.name); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | void viafb_delete_i2c_buss(void *par) | ||
175 | { | ||
176 | i2c_del_adapter(&((struct viafb_par *)par)->i2c_stuff.adapter); | ||
177 | } | ||
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h new file mode 100644 index 000000000000..3a13242a3152 --- /dev/null +++ b/drivers/video/via/via_i2c.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #ifndef __VIA_I2C_H__ | ||
22 | #define __VIA_I2C_H__ | ||
23 | |||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/i2c-algo-bit.h> | ||
26 | |||
27 | struct via_i2c_stuff { | ||
28 | u16 i2c_port; /* GPIO or I2C port */ | ||
29 | struct i2c_adapter adapter; | ||
30 | struct i2c_algo_bit_data algo; | ||
31 | }; | ||
32 | |||
33 | #define I2CPORT 0x3c4 | ||
34 | #define I2CPORTINDEX 0x31 | ||
35 | #define GPIOPORT 0x3C4 | ||
36 | #define GPIOPORTINDEX 0x2C | ||
37 | #define I2C_BUS 1 | ||
38 | #define GPIO_BUS 2 | ||
39 | #define DELAYPORT 0x3C3 | ||
40 | |||
41 | int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata); | ||
42 | int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data); | ||
43 | int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len); | ||
44 | int viafb_create_i2c_bus(void *par); | ||
45 | void viafb_delete_i2c_buss(void *par); | ||
46 | #endif /* __VIA_I2C_H__ */ | ||
diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c new file mode 100644 index 000000000000..d53c3d54ed8e --- /dev/null +++ b/drivers/video/via/via_utility.c | |||
@@ -0,0 +1,253 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | |||
24 | void viafb_get_device_support_state(u32 *support_state) | ||
25 | { | ||
26 | *support_state = CRT_Device; | ||
27 | |||
28 | if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name == VT1632_TMDS) | ||
29 | *support_state |= DVI_Device; | ||
30 | |||
31 | if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name == VT1631_LVDS) | ||
32 | *support_state |= LCD_Device; | ||
33 | } | ||
34 | |||
35 | void viafb_get_device_connect_state(u32 *connect_state) | ||
36 | { | ||
37 | bool mobile = false; | ||
38 | |||
39 | *connect_state = CRT_Device; | ||
40 | |||
41 | if (viafb_dvi_sense()) | ||
42 | *connect_state |= DVI_Device; | ||
43 | |||
44 | viafb_lcd_get_mobile_state(&mobile); | ||
45 | if (mobile) | ||
46 | *connect_state |= LCD_Device; | ||
47 | } | ||
48 | |||
49 | bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres) | ||
50 | { | ||
51 | unsigned int support_state = 0; | ||
52 | |||
53 | switch (viafb_lcd_panel_id) { | ||
54 | case LCD_PANEL_ID0_640X480: | ||
55 | if ((xres < 640) && (yres < 480)) | ||
56 | support_state = true; | ||
57 | break; | ||
58 | |||
59 | case LCD_PANEL_ID1_800X600: | ||
60 | if ((xres < 800) && (yres < 600)) | ||
61 | support_state = true; | ||
62 | break; | ||
63 | |||
64 | case LCD_PANEL_ID2_1024X768: | ||
65 | if ((xres < 1024) && (yres < 768)) | ||
66 | support_state = true; | ||
67 | break; | ||
68 | |||
69 | case LCD_PANEL_ID3_1280X768: | ||
70 | if ((xres < 1280) && (yres < 768)) | ||
71 | support_state = true; | ||
72 | break; | ||
73 | |||
74 | case LCD_PANEL_ID4_1280X1024: | ||
75 | if ((xres < 1280) && (yres < 1024)) | ||
76 | support_state = true; | ||
77 | break; | ||
78 | |||
79 | case LCD_PANEL_ID5_1400X1050: | ||
80 | if ((xres < 1400) && (yres < 1050)) | ||
81 | support_state = true; | ||
82 | break; | ||
83 | |||
84 | case LCD_PANEL_ID6_1600X1200: | ||
85 | if ((xres < 1600) && (yres < 1200)) | ||
86 | support_state = true; | ||
87 | break; | ||
88 | |||
89 | case LCD_PANEL_ID7_1366X768: | ||
90 | if ((xres < 1366) && (yres < 768)) | ||
91 | support_state = true; | ||
92 | break; | ||
93 | |||
94 | case LCD_PANEL_ID8_1024X600: | ||
95 | if ((xres < 1024) && (yres < 600)) | ||
96 | support_state = true; | ||
97 | break; | ||
98 | |||
99 | case LCD_PANEL_ID9_1280X800: | ||
100 | if ((xres < 1280) && (yres < 800)) | ||
101 | support_state = true; | ||
102 | break; | ||
103 | |||
104 | case LCD_PANEL_IDA_800X480: | ||
105 | if ((xres < 800) && (yres < 480)) | ||
106 | support_state = true; | ||
107 | break; | ||
108 | |||
109 | case LCD_PANEL_IDB_1360X768: | ||
110 | if ((xres < 1360) && (yres < 768)) | ||
111 | support_state = true; | ||
112 | break; | ||
113 | |||
114 | case LCD_PANEL_IDC_480X640: | ||
115 | if ((xres < 480) && (yres < 640)) | ||
116 | support_state = true; | ||
117 | break; | ||
118 | |||
119 | default: | ||
120 | support_state = false; | ||
121 | break; | ||
122 | } | ||
123 | |||
124 | return support_state; | ||
125 | } | ||
126 | |||
127 | /*====================================================================*/ | ||
128 | /* Gamma Function Implementation*/ | ||
129 | /*====================================================================*/ | ||
130 | |||
131 | void viafb_set_gamma_table(int bpp, unsigned int *gamma_table) | ||
132 | { | ||
133 | int i, sr1a; | ||
134 | int active_device_amount = 0; | ||
135 | int device_status = viafb_DeviceStatus; | ||
136 | |||
137 | for (i = 0; i < sizeof(viafb_DeviceStatus) * 8; i++) { | ||
138 | if (device_status & 1) | ||
139 | active_device_amount++; | ||
140 | device_status >>= 1; | ||
141 | } | ||
142 | |||
143 | /* 8 bpp mode can't adjust gamma */ | ||
144 | if (bpp == 8) | ||
145 | return ; | ||
146 | |||
147 | /* Enable Gamma */ | ||
148 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
149 | case UNICHROME_CLE266: | ||
150 | case UNICHROME_K400: | ||
151 | viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7); | ||
152 | break; | ||
153 | |||
154 | case UNICHROME_K800: | ||
155 | case UNICHROME_PM800: | ||
156 | case UNICHROME_CN700: | ||
157 | case UNICHROME_CX700: | ||
158 | case UNICHROME_K8M890: | ||
159 | case UNICHROME_P4M890: | ||
160 | case UNICHROME_P4M900: | ||
161 | viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7); | ||
162 | break; | ||
163 | } | ||
164 | sr1a = (unsigned int)viafb_read_reg(VIASR, SR1A); | ||
165 | viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0); | ||
166 | |||
167 | /* Fill IGA1 Gamma Table */ | ||
168 | outb(0, LUT_INDEX_WRITE); | ||
169 | for (i = 0; i < 256; i++) { | ||
170 | outb(gamma_table[i] >> 16, LUT_DATA); | ||
171 | outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA); | ||
172 | outb(gamma_table[i] & 0xFF, LUT_DATA); | ||
173 | } | ||
174 | |||
175 | /* If adjust Gamma value in SAMM, fill IGA1, | ||
176 | IGA2 Gamma table simultanous. */ | ||
177 | /* Switch to IGA2 Gamma Table */ | ||
178 | if ((active_device_amount > 1) && | ||
179 | !((viaparinfo->chip_info->gfx_chip_name == | ||
180 | UNICHROME_CLE266) && | ||
181 | (viaparinfo->chip_info->gfx_chip_revision < 15))) { | ||
182 | viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0); | ||
183 | viafb_write_reg_mask(CR6A, VIACR, 0x02, BIT1); | ||
184 | |||
185 | /* Fill IGA2 Gamma Table */ | ||
186 | outb(0, LUT_INDEX_WRITE); | ||
187 | for (i = 0; i < 256; i++) { | ||
188 | outb(gamma_table[i] >> 16, LUT_DATA); | ||
189 | outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA); | ||
190 | outb(gamma_table[i] & 0xFF, LUT_DATA); | ||
191 | } | ||
192 | } | ||
193 | viafb_write_reg(SR1A, VIASR, sr1a); | ||
194 | } | ||
195 | |||
196 | void viafb_get_gamma_table(unsigned int *gamma_table) | ||
197 | { | ||
198 | unsigned char color_r, color_g, color_b; | ||
199 | unsigned char sr1a = 0; | ||
200 | int i; | ||
201 | |||
202 | /* Enable Gamma */ | ||
203 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
204 | case UNICHROME_CLE266: | ||
205 | case UNICHROME_K400: | ||
206 | viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7); | ||
207 | break; | ||
208 | |||
209 | case UNICHROME_K800: | ||
210 | case UNICHROME_PM800: | ||
211 | case UNICHROME_CN700: | ||
212 | case UNICHROME_CX700: | ||
213 | case UNICHROME_K8M890: | ||
214 | case UNICHROME_P4M890: | ||
215 | case UNICHROME_P4M900: | ||
216 | viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7); | ||
217 | break; | ||
218 | } | ||
219 | sr1a = viafb_read_reg(VIASR, SR1A); | ||
220 | viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0); | ||
221 | |||
222 | /* Reading gamma table to get color value */ | ||
223 | outb(0, LUT_INDEX_READ); | ||
224 | for (i = 0; i < 256; i++) { | ||
225 | color_r = inb(LUT_DATA); | ||
226 | color_g = inb(LUT_DATA); | ||
227 | color_b = inb(LUT_DATA); | ||
228 | gamma_table[i] = | ||
229 | ((((u32) color_r) << 16) | | ||
230 | (((u16) color_g) << 8)) | color_b; | ||
231 | } | ||
232 | viafb_write_reg(SR1A, VIASR, sr1a); | ||
233 | } | ||
234 | |||
235 | void viafb_get_gamma_support_state(int bpp, unsigned int *support_state) | ||
236 | { | ||
237 | if (bpp == 8) | ||
238 | *support_state = None_Device; | ||
239 | else | ||
240 | *support_state = CRT_Device | DVI_Device | LCD_Device; | ||
241 | } | ||
242 | |||
243 | int viafb_input_parameter_converter(int parameter_value) | ||
244 | { | ||
245 | int result; | ||
246 | |||
247 | if (parameter_value >= 1 && parameter_value <= 9) | ||
248 | result = 1 << (parameter_value - 1); | ||
249 | else | ||
250 | result = 1; | ||
251 | |||
252 | return result; | ||
253 | } | ||
diff --git a/drivers/video/via/via_utility.h b/drivers/video/via/via_utility.h new file mode 100644 index 000000000000..2fd455202ebd --- /dev/null +++ b/drivers/video/via/via_utility.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | #ifndef __VIAUTILITY_H__ | ||
22 | #define __VIAUTILITY_H__ | ||
23 | |||
24 | /* These functions are used to get infomation about device's state */ | ||
25 | void viafb_get_device_support_state(u32 *support_state); | ||
26 | void viafb_get_device_connect_state(u32 *connect_state); | ||
27 | bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres); | ||
28 | |||
29 | /* These function are used to access gamma table */ | ||
30 | void viafb_set_gamma_table(int bpp, unsigned int *gamma_table); | ||
31 | void viafb_get_gamma_table(unsigned int *gamma_table); | ||
32 | void viafb_get_gamma_support_state(int bpp, unsigned int *support_state); | ||
33 | int viafb_input_parameter_converter(int parameter_value); | ||
34 | |||
35 | #endif /* __VIAUTILITY_H__ */ | ||
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c new file mode 100644 index 000000000000..0132eae06f55 --- /dev/null +++ b/drivers/video/via/viafbdev.c | |||
@@ -0,0 +1,2571 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #define _MASTER_FILE | ||
24 | |||
25 | #include "global.h" | ||
26 | |||
27 | static int MAX_CURS = 32; | ||
28 | static struct fb_var_screeninfo default_var; | ||
29 | static char *viafb_name = "Via"; | ||
30 | static u32 pseudo_pal[17]; | ||
31 | |||
32 | /* video mode */ | ||
33 | static char *viafb_mode = "640x480"; | ||
34 | static char *viafb_mode1 = "640x480"; | ||
35 | static int viafb_resMode = VIA_RES_640X480; | ||
36 | |||
37 | /* Added for specifying active devices.*/ | ||
38 | char *viafb_active_dev = ""; | ||
39 | |||
40 | /* Added for specifying video on devices.*/ | ||
41 | char *viafb_video_dev = ""; | ||
42 | |||
43 | /*Added for specify lcd output port*/ | ||
44 | char *viafb_lcd_port = ""; | ||
45 | char *viafb_dvi_port = ""; | ||
46 | |||
47 | static void viafb_set_device(struct device_t active_dev); | ||
48 | static int apply_device_setting(struct viafb_ioctl_setting setting_info, | ||
49 | struct fb_info *info); | ||
50 | static void apply_second_mode_setting(struct fb_var_screeninfo | ||
51 | *sec_var); | ||
52 | static void retrieve_device_setting(struct viafb_ioctl_setting | ||
53 | *setting_info); | ||
54 | static void viafb_set_video_device(u32 video_dev_info); | ||
55 | static void viafb_get_video_device(u32 *video_dev_info); | ||
56 | |||
57 | /* Mode information */ | ||
58 | static const struct viafb_modeinfo viafb_modentry[] = { | ||
59 | {480, 640, VIA_RES_480X640, "480x640"}, | ||
60 | {640, 480, VIA_RES_640X480, "640x480"}, | ||
61 | {800, 480, VIA_RES_800X480, "800x480"}, | ||
62 | {800, 600, VIA_RES_800X600, "800x600"}, | ||
63 | {1024, 768, VIA_RES_1024X768, "1024x768"}, | ||
64 | {1152, 864, VIA_RES_1152X864, "1152x864"}, | ||
65 | {1280, 1024, VIA_RES_1280X1024, "1280x1024"}, | ||
66 | {1600, 1200, VIA_RES_1600X1200, "1600x1200"}, | ||
67 | {1440, 1050, VIA_RES_1440X1050, "1440x1050"}, | ||
68 | {1280, 768, VIA_RES_1280X768, "1280x768"}, | ||
69 | {1280, 800, VIA_RES_1280X800, "1280x800"}, | ||
70 | {1280, 960, VIA_RES_1280X960, "1280x960"}, | ||
71 | {1920, 1440, VIA_RES_1920X1440, "1920x1440"}, | ||
72 | {848, 480, VIA_RES_848X480, "848x480"}, | ||
73 | {1400, 1050, VIA_RES_1400X1050, "1400x1050"}, | ||
74 | {720, 480, VIA_RES_720X480, "720x480"}, | ||
75 | {720, 576, VIA_RES_720X576, "720x576"}, | ||
76 | {1024, 512, VIA_RES_1024X512, "1024x512"}, | ||
77 | {1024, 576, VIA_RES_1024X576, "1024x576"}, | ||
78 | {1024, 600, VIA_RES_1024X600, "1024x600"}, | ||
79 | {1280, 720, VIA_RES_1280X720, "1280x720"}, | ||
80 | {1920, 1080, VIA_RES_1920X1080, "1920x1080"}, | ||
81 | {1366, 768, VIA_RES_1368X768, "1368x768"}, | ||
82 | {1680, 1050, VIA_RES_1680X1050, "1680x1050"}, | ||
83 | {960, 600, VIA_RES_960X600, "960x600"}, | ||
84 | {1000, 600, VIA_RES_1000X600, "1000x600"}, | ||
85 | {1024, 576, VIA_RES_1024X576, "1024x576"}, | ||
86 | {1024, 600, VIA_RES_1024X600, "1024x600"}, | ||
87 | {1088, 612, VIA_RES_1088X612, "1088x612"}, | ||
88 | {1152, 720, VIA_RES_1152X720, "1152x720"}, | ||
89 | {1200, 720, VIA_RES_1200X720, "1200x720"}, | ||
90 | {1280, 600, VIA_RES_1280X600, "1280x600"}, | ||
91 | {1360, 768, VIA_RES_1360X768, "1360x768"}, | ||
92 | {1440, 900, VIA_RES_1440X900, "1440x900"}, | ||
93 | {1600, 900, VIA_RES_1600X900, "1600x900"}, | ||
94 | {1600, 1024, VIA_RES_1600X1024, "1600x1024"}, | ||
95 | {1792, 1344, VIA_RES_1792X1344, "1792x1344"}, | ||
96 | {1856, 1392, VIA_RES_1856X1392, "1856x1392"}, | ||
97 | {1920, 1200, VIA_RES_1920X1200, "1920x1200"}, | ||
98 | {2048, 1536, VIA_RES_2048X1536, "2048x1536"}, | ||
99 | {0, 0, VIA_RES_INVALID, "640x480"} | ||
100 | }; | ||
101 | |||
102 | static struct fb_ops viafb_ops; | ||
103 | |||
104 | static int viafb_update_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | ||
105 | { | ||
106 | struct viafb_par *ppar; | ||
107 | ppar = info->par; | ||
108 | |||
109 | DEBUG_MSG(KERN_INFO "viafb_update_fix!\n"); | ||
110 | |||
111 | fix->visual = | ||
112 | ppar->bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | ||
113 | fix->line_length = ppar->linelength; | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | |||
119 | static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, | ||
120 | struct viafb_par *viaparinfo) | ||
121 | { | ||
122 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | ||
123 | strcpy(fix->id, viafb_name); | ||
124 | |||
125 | fix->smem_start = viaparinfo->fbmem; | ||
126 | fix->smem_len = viaparinfo->fbmem_free; | ||
127 | fix->mmio_start = viaparinfo->mmio_base; | ||
128 | fix->mmio_len = viaparinfo->mmio_len; | ||
129 | |||
130 | fix->type = FB_TYPE_PACKED_PIXELS; | ||
131 | fix->type_aux = 0; | ||
132 | |||
133 | fix->xpanstep = fix->ywrapstep = 0; | ||
134 | fix->ypanstep = 1; | ||
135 | |||
136 | /* Just tell the accel name */ | ||
137 | viafbinfo->fix.accel = FB_ACCEL_VIA_UNICHROME; | ||
138 | } | ||
139 | static int viafb_open(struct fb_info *info, int user) | ||
140 | { | ||
141 | DEBUG_MSG(KERN_INFO "viafb_open!\n"); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int viafb_release(struct fb_info *info, int user) | ||
146 | { | ||
147 | DEBUG_MSG(KERN_INFO "viafb_release!\n"); | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static void viafb_update_viafb_par(struct fb_info *info) | ||
152 | { | ||
153 | struct viafb_par *ppar; | ||
154 | |||
155 | ppar = info->par; | ||
156 | ppar->bpp = info->var.bits_per_pixel; | ||
157 | ppar->linelength = ((info->var.xres_virtual + 7) & ~7) * ppar->bpp / 8; | ||
158 | ppar->hres = info->var.xres; | ||
159 | ppar->vres = info->var.yres; | ||
160 | ppar->xoffset = info->var.xoffset; | ||
161 | ppar->yoffset = info->var.yoffset; | ||
162 | } | ||
163 | |||
164 | static int viafb_check_var(struct fb_var_screeninfo *var, | ||
165 | struct fb_info *info) | ||
166 | { | ||
167 | int vmode_index, htotal, vtotal; | ||
168 | struct viafb_par *ppar; | ||
169 | u32 long_refresh; | ||
170 | struct viafb_par *p_viafb_par; | ||
171 | ppar = info->par; | ||
172 | |||
173 | |||
174 | DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); | ||
175 | /* Sanity check */ | ||
176 | /* HW neither support interlacte nor double-scaned mode */ | ||
177 | if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) | ||
178 | return -EINVAL; | ||
179 | |||
180 | vmode_index = viafb_get_mode_index(var->xres, var->yres, 0); | ||
181 | if (vmode_index == VIA_RES_INVALID) { | ||
182 | DEBUG_MSG(KERN_INFO | ||
183 | "viafb: Mode %dx%dx%d not supported!!\n", | ||
184 | var->xres, var->yres, var->bits_per_pixel); | ||
185 | return -EINVAL; | ||
186 | } | ||
187 | |||
188 | if (24 == var->bits_per_pixel) | ||
189 | var->bits_per_pixel = 32; | ||
190 | |||
191 | if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 && | ||
192 | var->bits_per_pixel != 32) | ||
193 | return -EINVAL; | ||
194 | |||
195 | if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F) | ||
196 | /*32 pixel alignment */ | ||
197 | var->xres_virtual = (var->xres_virtual + 31) & ~31; | ||
198 | if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 > | ||
199 | ppar->memsize) | ||
200 | return -EINVAL; | ||
201 | |||
202 | /* Based on var passed in to calculate the refresh, | ||
203 | * because our driver use some modes special. | ||
204 | */ | ||
205 | htotal = var->xres + var->left_margin + | ||
206 | var->right_margin + var->hsync_len; | ||
207 | vtotal = var->yres + var->upper_margin + | ||
208 | var->lower_margin + var->vsync_len; | ||
209 | long_refresh = 1000000000UL / var->pixclock * 1000; | ||
210 | long_refresh /= (htotal * vtotal); | ||
211 | |||
212 | viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh); | ||
213 | |||
214 | /* Adjust var according to our driver's own table */ | ||
215 | viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); | ||
216 | |||
217 | /* This is indeed a patch for VT3353 */ | ||
218 | if (!info->par) | ||
219 | return -1; | ||
220 | p_viafb_par = (struct viafb_par *)info->par; | ||
221 | if (p_viafb_par->chip_info->gfx_chip_name == UNICHROME_VX800) | ||
222 | var->accel_flags = 0; | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int viafb_set_par(struct fb_info *info) | ||
228 | { | ||
229 | int vmode_index; | ||
230 | int vmode_index1 = 0; | ||
231 | DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); | ||
232 | |||
233 | viafb_update_device_setting(info->var.xres, info->var.yres, | ||
234 | info->var.bits_per_pixel, viafb_refresh, 0); | ||
235 | |||
236 | vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres, 0); | ||
237 | |||
238 | if (viafb_SAMM_ON == 1) { | ||
239 | DEBUG_MSG(KERN_INFO | ||
240 | "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", | ||
241 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | ||
242 | vmode_index1 = viafb_get_mode_index(viafb_second_xres, | ||
243 | viafb_second_yres, 1); | ||
244 | DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n", | ||
245 | vmode_index1); | ||
246 | |||
247 | viafb_update_device_setting(viafb_second_xres, | ||
248 | viafb_second_yres, viafb_bpp1, viafb_refresh1, 1); | ||
249 | } | ||
250 | |||
251 | if (vmode_index != VIA_RES_INVALID) { | ||
252 | viafb_setmode(vmode_index, info->var.xres, info->var.yres, | ||
253 | info->var.bits_per_pixel, vmode_index1, | ||
254 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | ||
255 | |||
256 | /*We should set memory offset according virtual_x */ | ||
257 | /*Fix me:put this function into viafb_setmode */ | ||
258 | viafb_memory_pitch_patch(info); | ||
259 | |||
260 | /* Update ***fb_par information */ | ||
261 | viafb_update_viafb_par(info); | ||
262 | |||
263 | /* Update other fixed information */ | ||
264 | viafb_update_fix(&info->fix, info); | ||
265 | viafb_bpp = info->var.bits_per_pixel; | ||
266 | /* Update viafb_accel, it is necessary to our 2D accelerate */ | ||
267 | viafb_accel = info->var.accel_flags; | ||
268 | |||
269 | if (viafb_accel) | ||
270 | viafb_set_2d_color_depth(info->var.bits_per_pixel); | ||
271 | } | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | /* Set one color register */ | ||
277 | static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
278 | unsigned blue, unsigned transp, struct fb_info *info) | ||
279 | { | ||
280 | u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10; | ||
281 | unsigned cmap_entries = (info->var.bits_per_pixel == 8) ? 256 : 16; | ||
282 | DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n"); | ||
283 | if (regno >= cmap_entries) | ||
284 | return 1; | ||
285 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) { | ||
286 | /* | ||
287 | * Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev. | ||
288 | */ | ||
289 | outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8); | ||
290 | rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff; | ||
291 | } | ||
292 | switch (info->var.bits_per_pixel) { | ||
293 | case 8: | ||
294 | outb(0x1A, 0x3C4); | ||
295 | sr1a = inb(0x3C5); | ||
296 | outb(0x1B, 0x3C4); | ||
297 | sr1b = inb(0x3C5); | ||
298 | outb(0x67, 0x3D4); | ||
299 | cr67 = inb(0x3D5); | ||
300 | outb(0x6A, 0x3D4); | ||
301 | cr6a = inb(0x3D5); | ||
302 | |||
303 | /* Map the 3C6/7/8/9 to the IGA2 */ | ||
304 | outb(0x1A, 0x3C4); | ||
305 | outb(sr1a | 0x01, 0x3C5); | ||
306 | /* Second Display Engine colck always on */ | ||
307 | outb(0x1B, 0x3C4); | ||
308 | outb(sr1b | 0x80, 0x3C5); | ||
309 | /* Second Display Color Depth 8 */ | ||
310 | outb(0x67, 0x3D4); | ||
311 | outb(cr67 & 0x3F, 0x3D5); | ||
312 | outb(0x6A, 0x3D4); | ||
313 | /* Second Display Channel Reset CR6A[6]) */ | ||
314 | outb(cr6a & 0xBF, 0x3D5); | ||
315 | /* Second Display Channel Enable CR6A[7] */ | ||
316 | outb(cr6a | 0x80, 0x3D5); | ||
317 | /* Second Display Channel stop reset) */ | ||
318 | outb(cr6a | 0x40, 0x3D5); | ||
319 | |||
320 | /* Bit mask of palette */ | ||
321 | outb(0xFF, 0x3c6); | ||
322 | /* Write one register of IGA2 */ | ||
323 | outb(regno, 0x3C8); | ||
324 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name && | ||
325 | rev >= 15) { | ||
326 | shift = 8; | ||
327 | viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5); | ||
328 | viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7); | ||
329 | } else { | ||
330 | shift = 10; | ||
331 | viafb_write_reg_mask(CR6A, VIACR, 0, BIT5); | ||
332 | viafb_write_reg_mask(SR15, VIASR, 0, BIT7); | ||
333 | } | ||
334 | outb(red >> shift, 0x3C9); | ||
335 | outb(green >> shift, 0x3C9); | ||
336 | outb(blue >> shift, 0x3C9); | ||
337 | |||
338 | /* Map the 3C6/7/8/9 to the IGA1 */ | ||
339 | outb(0x1A, 0x3C4); | ||
340 | outb(sr1a & 0xFE, 0x3C5); | ||
341 | /* Bit mask of palette */ | ||
342 | outb(0xFF, 0x3c6); | ||
343 | /* Write one register of IGA1 */ | ||
344 | outb(regno, 0x3C8); | ||
345 | outb(red >> shift, 0x3C9); | ||
346 | outb(green >> shift, 0x3C9); | ||
347 | outb(blue >> shift, 0x3C9); | ||
348 | |||
349 | outb(0x1A, 0x3C4); | ||
350 | outb(sr1a, 0x3C5); | ||
351 | outb(0x1B, 0x3C4); | ||
352 | outb(sr1b, 0x3C5); | ||
353 | outb(0x67, 0x3D4); | ||
354 | outb(cr67, 0x3D5); | ||
355 | outb(0x6A, 0x3D4); | ||
356 | outb(cr6a, 0x3D5); | ||
357 | break; | ||
358 | case 16: | ||
359 | ((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) | | ||
360 | ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11); | ||
361 | break; | ||
362 | case 32: | ||
363 | ((u32 *) info->pseudo_palette)[regno] = | ||
364 | ((transp & 0xFF00) << 16) | | ||
365 | ((red & 0xFF00) << 8) | | ||
366 | ((green & 0xFF00)) | ((blue & 0xFF00) >> 8); | ||
367 | break; | ||
368 | } | ||
369 | |||
370 | return 0; | ||
371 | |||
372 | } | ||
373 | |||
374 | /*CALLED BY: fb_set_cmap */ | ||
375 | /* fb_set_var, pass 256 colors */ | ||
376 | /*CALLED BY: fb_set_cmap */ | ||
377 | /* fbcon_set_palette, pass 16 colors */ | ||
378 | static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info) | ||
379 | { | ||
380 | u32 len = cmap->len; | ||
381 | u32 i; | ||
382 | u16 *pred = cmap->red; | ||
383 | u16 *pgreen = cmap->green; | ||
384 | u16 *pblue = cmap->blue; | ||
385 | u16 *ptransp = cmap->transp; | ||
386 | u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10; | ||
387 | if (len > 256) | ||
388 | return 1; | ||
389 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) { | ||
390 | /* | ||
391 | * Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip | ||
392 | * rev. | ||
393 | */ | ||
394 | outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8); | ||
395 | rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff; | ||
396 | } | ||
397 | switch (info->var.bits_per_pixel) { | ||
398 | case 8: | ||
399 | outb(0x1A, 0x3C4); | ||
400 | sr1a = inb(0x3C5); | ||
401 | outb(0x1B, 0x3C4); | ||
402 | sr1b = inb(0x3C5); | ||
403 | outb(0x67, 0x3D4); | ||
404 | cr67 = inb(0x3D5); | ||
405 | outb(0x6A, 0x3D4); | ||
406 | cr6a = inb(0x3D5); | ||
407 | /* Map the 3C6/7/8/9 to the IGA2 */ | ||
408 | outb(0x1A, 0x3C4); | ||
409 | outb(sr1a | 0x01, 0x3C5); | ||
410 | outb(0x1B, 0x3C4); | ||
411 | /* Second Display Engine colck always on */ | ||
412 | outb(sr1b | 0x80, 0x3C5); | ||
413 | outb(0x67, 0x3D4); | ||
414 | /* Second Display Color Depth 8 */ | ||
415 | outb(cr67 & 0x3F, 0x3D5); | ||
416 | outb(0x6A, 0x3D4); | ||
417 | /* Second Display Channel Reset CR6A[6]) */ | ||
418 | outb(cr6a & 0xBF, 0x3D5); | ||
419 | /* Second Display Channel Enable CR6A[7] */ | ||
420 | outb(cr6a | 0x80, 0x3D5); | ||
421 | /* Second Display Channel stop reset) */ | ||
422 | outb(cr6a | 0xC0, 0x3D5); | ||
423 | |||
424 | /* Bit mask of palette */ | ||
425 | outb(0xFF, 0x3c6); | ||
426 | outb(0x00, 0x3C8); | ||
427 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name && | ||
428 | rev >= 15) { | ||
429 | shift = 8; | ||
430 | viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5); | ||
431 | viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7); | ||
432 | } else { | ||
433 | shift = 10; | ||
434 | viafb_write_reg_mask(CR6A, VIACR, 0, BIT5); | ||
435 | viafb_write_reg_mask(SR15, VIASR, 0, BIT7); | ||
436 | } | ||
437 | for (i = 0; i < len; i++) { | ||
438 | outb((*(pred + i)) >> shift, 0x3C9); | ||
439 | outb((*(pgreen + i)) >> shift, 0x3C9); | ||
440 | outb((*(pblue + i)) >> shift, 0x3C9); | ||
441 | } | ||
442 | |||
443 | outb(0x1A, 0x3C4); | ||
444 | /* Map the 3C6/7/8/9 to the IGA1 */ | ||
445 | outb(sr1a & 0xFE, 0x3C5); | ||
446 | /* Bit mask of palette */ | ||
447 | outb(0xFF, 0x3c6); | ||
448 | outb(0x00, 0x3C8); | ||
449 | for (i = 0; i < len; i++) { | ||
450 | outb((*(pred + i)) >> shift, 0x3C9); | ||
451 | outb((*(pgreen + i)) >> shift, 0x3C9); | ||
452 | outb((*(pblue + i)) >> shift, 0x3C9); | ||
453 | } | ||
454 | |||
455 | outb(0x1A, 0x3C4); | ||
456 | outb(sr1a, 0x3C5); | ||
457 | outb(0x1B, 0x3C4); | ||
458 | outb(sr1b, 0x3C5); | ||
459 | outb(0x67, 0x3D4); | ||
460 | outb(cr67, 0x3D5); | ||
461 | outb(0x6A, 0x3D4); | ||
462 | outb(cr6a, 0x3D5); | ||
463 | break; | ||
464 | case 16: | ||
465 | if (len > 17) | ||
466 | return 0; /* Because static u32 pseudo_pal[17]; */ | ||
467 | for (i = 0; i < len; i++) | ||
468 | ((u32 *) info->pseudo_palette)[i] = | ||
469 | (*(pred + i) & 0xF800) | | ||
470 | ((*(pgreen + i) & 0xFC00) >> 5) | | ||
471 | ((*(pblue + i) & 0xF800) >> 11); | ||
472 | break; | ||
473 | case 32: | ||
474 | if (len > 17) | ||
475 | return 0; | ||
476 | if (ptransp) { | ||
477 | for (i = 0; i < len; i++) | ||
478 | ((u32 *) info->pseudo_palette)[i] = | ||
479 | ((*(ptransp + i) & 0xFF00) << 16) | | ||
480 | ((*(pred + i) & 0xFF00) << 8) | | ||
481 | ((*(pgreen + i) & 0xFF00)) | | ||
482 | ((*(pblue + i) & 0xFF00) >> 8); | ||
483 | } else { | ||
484 | for (i = 0; i < len; i++) | ||
485 | ((u32 *) info->pseudo_palette)[i] = | ||
486 | 0x00000000 | | ||
487 | ((*(pred + i) & 0xFF00) << 8) | | ||
488 | ((*(pgreen + i) & 0xFF00)) | | ||
489 | ((*(pblue + i) & 0xFF00) >> 8); | ||
490 | } | ||
491 | break; | ||
492 | } | ||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | static int viafb_pan_display(struct fb_var_screeninfo *var, | ||
497 | struct fb_info *info) | ||
498 | { | ||
499 | unsigned int offset; | ||
500 | |||
501 | DEBUG_MSG(KERN_INFO "viafb_pan_display!\n"); | ||
502 | |||
503 | offset = (var->xoffset + (var->yoffset * var->xres_virtual)) * | ||
504 | var->bits_per_pixel / 16; | ||
505 | |||
506 | DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset); | ||
507 | |||
508 | viafb_write_reg_mask(0x48, 0x3d4, ((offset >> 24) & 0x3), 0x3); | ||
509 | viafb_write_reg_mask(0x34, 0x3d4, ((offset >> 16) & 0xff), 0xff); | ||
510 | viafb_write_reg_mask(0x0c, 0x3d4, ((offset >> 8) & 0xff), 0xff); | ||
511 | viafb_write_reg_mask(0x0d, 0x3d4, (offset & 0xff), 0xff); | ||
512 | |||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | static int viafb_blank(int blank_mode, struct fb_info *info) | ||
517 | { | ||
518 | DEBUG_MSG(KERN_INFO "viafb_blank!\n"); | ||
519 | /* clear DPMS setting */ | ||
520 | |||
521 | switch (blank_mode) { | ||
522 | case FB_BLANK_UNBLANK: | ||
523 | /* Screen: On, HSync: On, VSync: On */ | ||
524 | /* control CRT monitor power management */ | ||
525 | viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); | ||
526 | break; | ||
527 | case FB_BLANK_HSYNC_SUSPEND: | ||
528 | /* Screen: Off, HSync: Off, VSync: On */ | ||
529 | /* control CRT monitor power management */ | ||
530 | viafb_write_reg_mask(CR36, VIACR, 0x10, BIT4 + BIT5); | ||
531 | break; | ||
532 | case FB_BLANK_VSYNC_SUSPEND: | ||
533 | /* Screen: Off, HSync: On, VSync: Off */ | ||
534 | /* control CRT monitor power management */ | ||
535 | viafb_write_reg_mask(CR36, VIACR, 0x20, BIT4 + BIT5); | ||
536 | break; | ||
537 | case FB_BLANK_POWERDOWN: | ||
538 | /* Screen: Off, HSync: Off, VSync: Off */ | ||
539 | /* control CRT monitor power management */ | ||
540 | viafb_write_reg_mask(CR36, VIACR, 0x30, BIT4 + BIT5); | ||
541 | break; | ||
542 | } | ||
543 | |||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | ||
548 | { | ||
549 | struct viafb_ioctl_mode viamode; | ||
550 | struct viafb_ioctl_samm viasamm; | ||
551 | struct viafb_driver_version driver_version; | ||
552 | struct fb_var_screeninfo sec_var; | ||
553 | struct _panel_size_pos_info panel_pos_size_para; | ||
554 | u32 state_info = 0; | ||
555 | u32 viainfo_size = sizeof(struct viafb_ioctl_info); | ||
556 | u32 *viafb_gamma_table; | ||
557 | char driver_name[] = "viafb"; | ||
558 | |||
559 | u32 __user *argp = (u32 __user *) arg; | ||
560 | u32 gpu32; | ||
561 | u32 video_dev_info = 0; | ||
562 | struct viafb_ioctl_setting viafb_setting = {}; | ||
563 | struct device_t active_dev = {}; | ||
564 | |||
565 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); | ||
566 | |||
567 | switch (cmd) { | ||
568 | case VIAFB_GET_CHIP_INFO: | ||
569 | if (copy_to_user(argp, viaparinfo->chip_info, | ||
570 | sizeof(struct chip_information))) | ||
571 | return -EFAULT; | ||
572 | break; | ||
573 | case VIAFB_GET_INFO_SIZE: | ||
574 | return put_user(viainfo_size, argp); | ||
575 | case VIAFB_GET_INFO: | ||
576 | return viafb_ioctl_get_viafb_info(arg); | ||
577 | case VIAFB_HOTPLUG: | ||
578 | return put_user(viafb_ioctl_hotplug(info->var.xres, | ||
579 | info->var.yres, | ||
580 | info->var.bits_per_pixel), argp); | ||
581 | case VIAFB_SET_HOTPLUG_FLAG: | ||
582 | if (copy_from_user(&gpu32, argp, sizeof(gpu32))) | ||
583 | return -EFAULT; | ||
584 | viafb_hotplug = (gpu32) ? 1 : 0; | ||
585 | break; | ||
586 | case VIAFB_GET_RESOLUTION: | ||
587 | viamode.xres = (u32) viafb_hotplug_Xres; | ||
588 | viamode.yres = (u32) viafb_hotplug_Yres; | ||
589 | viamode.refresh = (u32) viafb_hotplug_refresh; | ||
590 | viamode.bpp = (u32) viafb_hotplug_bpp; | ||
591 | if (viafb_SAMM_ON == 1) { | ||
592 | viamode.xres_sec = viafb_second_xres; | ||
593 | viamode.yres_sec = viafb_second_yres; | ||
594 | viamode.virtual_xres_sec = viafb_second_virtual_xres; | ||
595 | viamode.virtual_yres_sec = viafb_second_virtual_yres; | ||
596 | viamode.refresh_sec = viafb_refresh1; | ||
597 | viamode.bpp_sec = viafb_bpp1; | ||
598 | } else { | ||
599 | viamode.xres_sec = 0; | ||
600 | viamode.yres_sec = 0; | ||
601 | viamode.virtual_xres_sec = 0; | ||
602 | viamode.virtual_yres_sec = 0; | ||
603 | viamode.refresh_sec = 0; | ||
604 | viamode.bpp_sec = 0; | ||
605 | } | ||
606 | if (copy_to_user(argp, &viamode, sizeof(viamode))) | ||
607 | return -EFAULT; | ||
608 | break; | ||
609 | case VIAFB_GET_SAMM_INFO: | ||
610 | viasamm.samm_status = viafb_SAMM_ON; | ||
611 | |||
612 | if (viafb_SAMM_ON == 1) { | ||
613 | if (viafb_dual_fb) { | ||
614 | viasamm.size_prim = viaparinfo->fbmem_free; | ||
615 | viasamm.size_sec = viaparinfo1->fbmem_free; | ||
616 | } else { | ||
617 | if (viafb_second_size) { | ||
618 | viasamm.size_prim = | ||
619 | viaparinfo->fbmem_free - | ||
620 | viafb_second_size * 1024 * 1024; | ||
621 | viasamm.size_sec = | ||
622 | viafb_second_size * 1024 * 1024; | ||
623 | } else { | ||
624 | viasamm.size_prim = | ||
625 | viaparinfo->fbmem_free >> 1; | ||
626 | viasamm.size_sec = | ||
627 | (viaparinfo->fbmem_free >> 1); | ||
628 | } | ||
629 | } | ||
630 | viasamm.mem_base = viaparinfo->fbmem; | ||
631 | viasamm.offset_sec = viafb_second_offset; | ||
632 | } else { | ||
633 | viasamm.size_prim = | ||
634 | viaparinfo->memsize - viaparinfo->fbmem_used; | ||
635 | viasamm.size_sec = 0; | ||
636 | viasamm.mem_base = viaparinfo->fbmem; | ||
637 | viasamm.offset_sec = 0; | ||
638 | } | ||
639 | |||
640 | if (copy_to_user(argp, &viasamm, sizeof(viasamm))) | ||
641 | return -EFAULT; | ||
642 | |||
643 | break; | ||
644 | case VIAFB_TURN_ON_OUTPUT_DEVICE: | ||
645 | if (copy_from_user(&gpu32, argp, sizeof(gpu32))) | ||
646 | return -EFAULT; | ||
647 | if (gpu32 & CRT_Device) | ||
648 | viafb_crt_enable(); | ||
649 | if (gpu32 & DVI_Device) | ||
650 | viafb_dvi_enable(); | ||
651 | if (gpu32 & LCD_Device) | ||
652 | viafb_lcd_enable(); | ||
653 | break; | ||
654 | case VIAFB_TURN_OFF_OUTPUT_DEVICE: | ||
655 | if (copy_from_user(&gpu32, argp, sizeof(gpu32))) | ||
656 | return -EFAULT; | ||
657 | if (gpu32 & CRT_Device) | ||
658 | viafb_crt_disable(); | ||
659 | if (gpu32 & DVI_Device) | ||
660 | viafb_dvi_disable(); | ||
661 | if (gpu32 & LCD_Device) | ||
662 | viafb_lcd_disable(); | ||
663 | break; | ||
664 | case VIAFB_SET_DEVICE: | ||
665 | if (copy_from_user(&active_dev, (void *)argp, | ||
666 | sizeof(active_dev))) | ||
667 | return -EFAULT; | ||
668 | viafb_set_device(active_dev); | ||
669 | viafb_set_par(info); | ||
670 | break; | ||
671 | case VIAFB_GET_DEVICE: | ||
672 | active_dev.crt = viafb_CRT_ON; | ||
673 | active_dev.dvi = viafb_DVI_ON; | ||
674 | active_dev.lcd = viafb_LCD_ON; | ||
675 | active_dev.samm = viafb_SAMM_ON; | ||
676 | active_dev.primary_dev = viafb_primary_dev; | ||
677 | |||
678 | active_dev.lcd_dsp_cent = viafb_lcd_dsp_method; | ||
679 | active_dev.lcd_panel_id = viafb_lcd_panel_id; | ||
680 | active_dev.lcd_mode = viafb_lcd_mode; | ||
681 | |||
682 | active_dev.xres = viafb_hotplug_Xres; | ||
683 | active_dev.yres = viafb_hotplug_Yres; | ||
684 | |||
685 | active_dev.xres1 = viafb_second_xres; | ||
686 | active_dev.yres1 = viafb_second_yres; | ||
687 | |||
688 | active_dev.bpp = viafb_bpp; | ||
689 | active_dev.bpp1 = viafb_bpp1; | ||
690 | active_dev.refresh = viafb_refresh; | ||
691 | active_dev.refresh1 = viafb_refresh1; | ||
692 | |||
693 | active_dev.epia_dvi = viafb_platform_epia_dvi; | ||
694 | active_dev.lcd_dual_edge = viafb_device_lcd_dualedge; | ||
695 | active_dev.bus_width = viafb_bus_width; | ||
696 | |||
697 | if (copy_to_user(argp, &active_dev, sizeof(active_dev))) | ||
698 | return -EFAULT; | ||
699 | break; | ||
700 | |||
701 | case VIAFB_GET_DRIVER_VERSION: | ||
702 | driver_version.iMajorNum = VERSION_MAJOR; | ||
703 | driver_version.iKernelNum = VERSION_KERNEL; | ||
704 | driver_version.iOSNum = VERSION_OS; | ||
705 | driver_version.iMinorNum = VERSION_MINOR; | ||
706 | |||
707 | if (copy_to_user(argp, &driver_version, | ||
708 | sizeof(driver_version))) | ||
709 | return -EFAULT; | ||
710 | |||
711 | break; | ||
712 | |||
713 | case VIAFB_SET_DEVICE_INFO: | ||
714 | if (copy_from_user(&viafb_setting, | ||
715 | argp, sizeof(viafb_setting))) | ||
716 | return -EFAULT; | ||
717 | if (apply_device_setting(viafb_setting, info) < 0) | ||
718 | return -EINVAL; | ||
719 | |||
720 | break; | ||
721 | |||
722 | case VIAFB_SET_SECOND_MODE: | ||
723 | if (copy_from_user(&sec_var, argp, sizeof(sec_var))) | ||
724 | return -EFAULT; | ||
725 | apply_second_mode_setting(&sec_var); | ||
726 | break; | ||
727 | |||
728 | case VIAFB_GET_DEVICE_INFO: | ||
729 | |||
730 | retrieve_device_setting(&viafb_setting); | ||
731 | |||
732 | if (copy_to_user(argp, &viafb_setting, sizeof(viafb_setting))) | ||
733 | return -EFAULT; | ||
734 | |||
735 | break; | ||
736 | |||
737 | case VIAFB_GET_DEVICE_SUPPORT: | ||
738 | viafb_get_device_support_state(&state_info); | ||
739 | if (put_user(state_info, argp)) | ||
740 | return -EFAULT; | ||
741 | break; | ||
742 | |||
743 | case VIAFB_GET_DEVICE_CONNECT: | ||
744 | viafb_get_device_connect_state(&state_info); | ||
745 | if (put_user(state_info, argp)) | ||
746 | return -EFAULT; | ||
747 | break; | ||
748 | |||
749 | case VIAFB_GET_PANEL_SUPPORT_EXPAND: | ||
750 | state_info = | ||
751 | viafb_lcd_get_support_expand_state(info->var.xres, | ||
752 | info->var.yres); | ||
753 | if (put_user(state_info, argp)) | ||
754 | return -EFAULT; | ||
755 | break; | ||
756 | |||
757 | case VIAFB_GET_DRIVER_NAME: | ||
758 | if (copy_to_user(argp, driver_name, sizeof(driver_name))) | ||
759 | return -EFAULT; | ||
760 | break; | ||
761 | |||
762 | case VIAFB_SET_GAMMA_LUT: | ||
763 | viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL); | ||
764 | if (!viafb_gamma_table) | ||
765 | return -ENOMEM; | ||
766 | if (copy_from_user(viafb_gamma_table, argp, | ||
767 | sizeof(viafb_gamma_table))) { | ||
768 | kfree(viafb_gamma_table); | ||
769 | return -EFAULT; | ||
770 | } | ||
771 | viafb_set_gamma_table(viafb_bpp, viafb_gamma_table); | ||
772 | kfree(viafb_gamma_table); | ||
773 | break; | ||
774 | |||
775 | case VIAFB_GET_GAMMA_LUT: | ||
776 | viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL); | ||
777 | if (!viafb_gamma_table) | ||
778 | return -ENOMEM; | ||
779 | viafb_get_gamma_table(viafb_gamma_table); | ||
780 | if (copy_to_user(argp, viafb_gamma_table, | ||
781 | sizeof(viafb_gamma_table))) { | ||
782 | kfree(viafb_gamma_table); | ||
783 | return -EFAULT; | ||
784 | } | ||
785 | kfree(viafb_gamma_table); | ||
786 | break; | ||
787 | |||
788 | case VIAFB_GET_GAMMA_SUPPORT_STATE: | ||
789 | viafb_get_gamma_support_state(viafb_bpp, &state_info); | ||
790 | if (put_user(state_info, argp)) | ||
791 | return -EFAULT; | ||
792 | break; | ||
793 | case VIAFB_SET_VIDEO_DEVICE: | ||
794 | get_user(video_dev_info, argp); | ||
795 | viafb_set_video_device(video_dev_info); | ||
796 | break; | ||
797 | case VIAFB_GET_VIDEO_DEVICE: | ||
798 | viafb_get_video_device(&video_dev_info); | ||
799 | if (put_user(video_dev_info, argp)) | ||
800 | return -EFAULT; | ||
801 | break; | ||
802 | case VIAFB_SYNC_SURFACE: | ||
803 | DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n"); | ||
804 | break; | ||
805 | case VIAFB_GET_DRIVER_CAPS: | ||
806 | break; | ||
807 | |||
808 | case VIAFB_GET_PANEL_MAX_SIZE: | ||
809 | if (copy_from_user | ||
810 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | ||
811 | return -EFAULT; | ||
812 | panel_pos_size_para.x = panel_pos_size_para.y = 0; | ||
813 | if (copy_to_user(argp, &panel_pos_size_para, | ||
814 | sizeof(panel_pos_size_para))) | ||
815 | return -EFAULT; | ||
816 | break; | ||
817 | case VIAFB_GET_PANEL_MAX_POSITION: | ||
818 | if (copy_from_user | ||
819 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | ||
820 | return -EFAULT; | ||
821 | panel_pos_size_para.x = panel_pos_size_para.y = 0; | ||
822 | if (copy_to_user(argp, &panel_pos_size_para, | ||
823 | sizeof(panel_pos_size_para))) | ||
824 | return -EFAULT; | ||
825 | break; | ||
826 | |||
827 | case VIAFB_GET_PANEL_POSITION: | ||
828 | if (copy_from_user | ||
829 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | ||
830 | return -EFAULT; | ||
831 | panel_pos_size_para.x = panel_pos_size_para.y = 0; | ||
832 | if (copy_to_user(argp, &panel_pos_size_para, | ||
833 | sizeof(panel_pos_size_para))) | ||
834 | return -EFAULT; | ||
835 | break; | ||
836 | case VIAFB_GET_PANEL_SIZE: | ||
837 | if (copy_from_user | ||
838 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | ||
839 | return -EFAULT; | ||
840 | panel_pos_size_para.x = panel_pos_size_para.y = 0; | ||
841 | if (copy_to_user(argp, &panel_pos_size_para, | ||
842 | sizeof(panel_pos_size_para))) | ||
843 | return -EFAULT; | ||
844 | break; | ||
845 | |||
846 | case VIAFB_SET_PANEL_POSITION: | ||
847 | if (copy_from_user | ||
848 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | ||
849 | return -EFAULT; | ||
850 | break; | ||
851 | case VIAFB_SET_PANEL_SIZE: | ||
852 | if (copy_from_user | ||
853 | (&panel_pos_size_para, argp, sizeof(panel_pos_size_para))) | ||
854 | return -EFAULT; | ||
855 | break; | ||
856 | |||
857 | default: | ||
858 | return -EINVAL; | ||
859 | } | ||
860 | |||
861 | return 0; | ||
862 | } | ||
863 | |||
864 | static void viafb_fillrect(struct fb_info *info, | ||
865 | const struct fb_fillrect *rect) | ||
866 | { | ||
867 | u32 col = 0, rop = 0; | ||
868 | int pitch; | ||
869 | |||
870 | if (!viafb_accel) | ||
871 | return cfb_fillrect(info, rect); | ||
872 | |||
873 | if (!rect->width || !rect->height) | ||
874 | return; | ||
875 | |||
876 | switch (rect->rop) { | ||
877 | case ROP_XOR: | ||
878 | rop = 0x5A; | ||
879 | break; | ||
880 | case ROP_COPY: | ||
881 | default: | ||
882 | rop = 0xF0; | ||
883 | break; | ||
884 | } | ||
885 | |||
886 | switch (info->var.bits_per_pixel) { | ||
887 | case 8: | ||
888 | col = rect->color; | ||
889 | break; | ||
890 | case 16: | ||
891 | col = ((u32 *) (info->pseudo_palette))[rect->color]; | ||
892 | break; | ||
893 | case 32: | ||
894 | col = ((u32 *) (info->pseudo_palette))[rect->color]; | ||
895 | break; | ||
896 | } | ||
897 | |||
898 | /* BitBlt Source Address */ | ||
899 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); | ||
900 | /* Source Base Address */ | ||
901 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
902 | /* Destination Base Address */ | ||
903 | writel(((unsigned long) (info->screen_base) - | ||
904 | (unsigned long) viafb_FB_MM) >> 3, | ||
905 | viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
906 | /* Pitch */ | ||
907 | pitch = (info->var.xres_virtual + 7) & ~7; | ||
908 | writel(VIA_PITCH_ENABLE | | ||
909 | (((pitch * | ||
910 | info->var.bits_per_pixel >> 3) >> 3) | | ||
911 | (((pitch * info-> | ||
912 | var.bits_per_pixel >> 3) >> 3) << 16)), | ||
913 | viaparinfo->io_virt + VIA_REG_PITCH); | ||
914 | /* BitBlt Destination Address */ | ||
915 | writel(((rect->dy << 16) | rect->dx), | ||
916 | viaparinfo->io_virt + VIA_REG_DSTPOS); | ||
917 | /* Dimension: width & height */ | ||
918 | writel((((rect->height - 1) << 16) | (rect->width - 1)), | ||
919 | viaparinfo->io_virt + VIA_REG_DIMENSION); | ||
920 | /* Forground color or Destination color */ | ||
921 | writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR); | ||
922 | /* GE Command */ | ||
923 | writel((0x01 | 0x2000 | (rop << 24)), | ||
924 | viaparinfo->io_virt + VIA_REG_GECMD); | ||
925 | |||
926 | } | ||
927 | |||
928 | static void viafb_copyarea(struct fb_info *info, | ||
929 | const struct fb_copyarea *area) | ||
930 | { | ||
931 | u32 dy = area->dy, sy = area->sy, direction = 0x0; | ||
932 | u32 sx = area->sx, dx = area->dx, width = area->width; | ||
933 | int pitch; | ||
934 | |||
935 | DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n"); | ||
936 | |||
937 | if (!viafb_accel) | ||
938 | return cfb_copyarea(info, area); | ||
939 | |||
940 | if (!area->width || !area->height) | ||
941 | return; | ||
942 | |||
943 | if (sy < dy) { | ||
944 | dy += area->height - 1; | ||
945 | sy += area->height - 1; | ||
946 | direction |= 0x4000; | ||
947 | } | ||
948 | |||
949 | if (sx < dx) { | ||
950 | dx += width - 1; | ||
951 | sx += width - 1; | ||
952 | direction |= 0x8000; | ||
953 | } | ||
954 | |||
955 | /* Source Base Address */ | ||
956 | writel(((unsigned long) (info->screen_base) - | ||
957 | (unsigned long) viafb_FB_MM) >> 3, | ||
958 | viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
959 | /* Destination Base Address */ | ||
960 | writel(((unsigned long) (info->screen_base) - | ||
961 | (unsigned long) viafb_FB_MM) >> 3, | ||
962 | viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
963 | /* Pitch */ | ||
964 | pitch = (info->var.xres_virtual + 7) & ~7; | ||
965 | /* VIA_PITCH_ENABLE can be omitted now. */ | ||
966 | writel(VIA_PITCH_ENABLE | | ||
967 | (((pitch * | ||
968 | info->var.bits_per_pixel >> 3) >> 3) | (((pitch * | ||
969 | info->var. | ||
970 | bits_per_pixel | ||
971 | >> 3) >> 3) | ||
972 | << 16)), | ||
973 | viaparinfo->io_virt + VIA_REG_PITCH); | ||
974 | /* BitBlt Source Address */ | ||
975 | writel(((sy << 16) | sx), viaparinfo->io_virt + VIA_REG_SRCPOS); | ||
976 | /* BitBlt Destination Address */ | ||
977 | writel(((dy << 16) | dx), viaparinfo->io_virt + VIA_REG_DSTPOS); | ||
978 | /* Dimension: width & height */ | ||
979 | writel((((area->height - 1) << 16) | (area->width - 1)), | ||
980 | viaparinfo->io_virt + VIA_REG_DIMENSION); | ||
981 | /* GE Command */ | ||
982 | writel((0x01 | direction | (0xCC << 24)), | ||
983 | viaparinfo->io_virt + VIA_REG_GECMD); | ||
984 | |||
985 | } | ||
986 | |||
987 | static void viafb_imageblit(struct fb_info *info, | ||
988 | const struct fb_image *image) | ||
989 | { | ||
990 | u32 size, bg_col = 0, fg_col = 0, *udata; | ||
991 | int i; | ||
992 | int pitch; | ||
993 | |||
994 | if (!viafb_accel) | ||
995 | return cfb_imageblit(info, image); | ||
996 | |||
997 | udata = (u32 *) image->data; | ||
998 | |||
999 | switch (info->var.bits_per_pixel) { | ||
1000 | case 8: | ||
1001 | bg_col = image->bg_color; | ||
1002 | fg_col = image->fg_color; | ||
1003 | break; | ||
1004 | case 16: | ||
1005 | bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; | ||
1006 | fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; | ||
1007 | break; | ||
1008 | case 32: | ||
1009 | bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; | ||
1010 | fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; | ||
1011 | break; | ||
1012 | } | ||
1013 | size = image->width * image->height; | ||
1014 | |||
1015 | /* Source Base Address */ | ||
1016 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); | ||
1017 | /* Destination Base Address */ | ||
1018 | writel(((unsigned long) (info->screen_base) - | ||
1019 | (unsigned long) viafb_FB_MM) >> 3, | ||
1020 | viaparinfo->io_virt + VIA_REG_DSTBASE); | ||
1021 | /* Pitch */ | ||
1022 | pitch = (info->var.xres_virtual + 7) & ~7; | ||
1023 | writel(VIA_PITCH_ENABLE | | ||
1024 | (((pitch * | ||
1025 | info->var.bits_per_pixel >> 3) >> 3) | (((pitch * | ||
1026 | info->var. | ||
1027 | bits_per_pixel | ||
1028 | >> 3) >> 3) | ||
1029 | << 16)), | ||
1030 | viaparinfo->io_virt + VIA_REG_PITCH); | ||
1031 | /* BitBlt Source Address */ | ||
1032 | writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); | ||
1033 | /* BitBlt Destination Address */ | ||
1034 | writel(((image->dy << 16) | image->dx), | ||
1035 | viaparinfo->io_virt + VIA_REG_DSTPOS); | ||
1036 | /* Dimension: width & height */ | ||
1037 | writel((((image->height - 1) << 16) | (image->width - 1)), | ||
1038 | viaparinfo->io_virt + VIA_REG_DIMENSION); | ||
1039 | /* fb color */ | ||
1040 | writel(fg_col, viaparinfo->io_virt + VIA_REG_FGCOLOR); | ||
1041 | /* bg color */ | ||
1042 | writel(bg_col, viaparinfo->io_virt + VIA_REG_BGCOLOR); | ||
1043 | /* GE Command */ | ||
1044 | writel(0xCC020142, viaparinfo->io_virt + VIA_REG_GECMD); | ||
1045 | |||
1046 | for (i = 0; i < size / 4; i++) { | ||
1047 | writel(*udata, viaparinfo->io_virt + VIA_MMIO_BLTBASE); | ||
1048 | udata++; | ||
1049 | } | ||
1050 | |||
1051 | } | ||
1052 | |||
1053 | static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
1054 | { | ||
1055 | u8 data[CURSOR_SIZE / 8]; | ||
1056 | u32 data_bak[CURSOR_SIZE / 32]; | ||
1057 | u32 temp, xx, yy, bg_col = 0, fg_col = 0; | ||
1058 | int size, i, j = 0; | ||
1059 | static int hw_cursor; | ||
1060 | struct viafb_par *p_viafb_par; | ||
1061 | |||
1062 | if (viafb_accel) | ||
1063 | hw_cursor = 1; | ||
1064 | |||
1065 | if (!viafb_accel) { | ||
1066 | if (hw_cursor) { | ||
1067 | viafb_show_hw_cursor(info, HW_Cursor_OFF); | ||
1068 | hw_cursor = 0; | ||
1069 | } | ||
1070 | return -ENODEV; | ||
1071 | } | ||
1072 | |||
1073 | if ((((struct viafb_par *)(info->par))->iga_path == IGA2) | ||
1074 | && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) | ||
1075 | return -ENODEV; | ||
1076 | |||
1077 | /* When duoview and using lcd , use soft cursor */ | ||
1078 | if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview) | ||
1079 | return -ENODEV; | ||
1080 | |||
1081 | viafb_show_hw_cursor(info, HW_Cursor_OFF); | ||
1082 | viacursor = *cursor; | ||
1083 | |||
1084 | if (cursor->set & FB_CUR_SETHOT) { | ||
1085 | viacursor.hot = cursor->hot; | ||
1086 | temp = ((viacursor.hot.x) << 16) + viacursor.hot.y; | ||
1087 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); | ||
1088 | } | ||
1089 | |||
1090 | if (cursor->set & FB_CUR_SETPOS) { | ||
1091 | viacursor.image.dx = cursor->image.dx; | ||
1092 | viacursor.image.dy = cursor->image.dy; | ||
1093 | yy = cursor->image.dy - info->var.yoffset; | ||
1094 | xx = cursor->image.dx - info->var.xoffset; | ||
1095 | temp = yy & 0xFFFF; | ||
1096 | temp |= (xx << 16); | ||
1097 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS); | ||
1098 | } | ||
1099 | |||
1100 | if (cursor->set & FB_CUR_SETSIZE) { | ||
1101 | temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | ||
1102 | |||
1103 | if ((cursor->image.width <= 32) | ||
1104 | && (cursor->image.height <= 32)) { | ||
1105 | MAX_CURS = 32; | ||
1106 | temp |= 0x2; | ||
1107 | } else if ((cursor->image.width <= 64) | ||
1108 | && (cursor->image.height <= 64)) { | ||
1109 | MAX_CURS = 64; | ||
1110 | temp &= 0xFFFFFFFD; | ||
1111 | } else { | ||
1112 | DEBUG_MSG(KERN_INFO | ||
1113 | "The cursor image is biger than 64x64 bits...\n"); | ||
1114 | return -ENXIO; | ||
1115 | } | ||
1116 | writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); | ||
1117 | |||
1118 | viacursor.image.height = cursor->image.height; | ||
1119 | viacursor.image.width = cursor->image.width; | ||
1120 | } | ||
1121 | |||
1122 | if (cursor->set & FB_CUR_SETCMAP) { | ||
1123 | viacursor.image.fg_color = cursor->image.fg_color; | ||
1124 | viacursor.image.bg_color = cursor->image.bg_color; | ||
1125 | |||
1126 | switch (info->var.bits_per_pixel) { | ||
1127 | case 8: | ||
1128 | case 16: | ||
1129 | case 32: | ||
1130 | bg_col = | ||
1131 | (0xFF << 24) | | ||
1132 | (((info->cmap.red)[viacursor.image.bg_color] & | ||
1133 | 0xFF00) << 8) | | ||
1134 | ((info->cmap.green)[viacursor.image.bg_color] & | ||
1135 | 0xFF00) | | ||
1136 | (((info->cmap.blue)[viacursor.image.bg_color] & | ||
1137 | 0xFF00) >> 8); | ||
1138 | fg_col = | ||
1139 | (0xFF << 24) | | ||
1140 | (((info->cmap.red)[viacursor.image.fg_color] & | ||
1141 | 0xFF00) << 8) | | ||
1142 | ((info->cmap.green)[viacursor.image.fg_color] & | ||
1143 | 0xFF00) | | ||
1144 | (((info->cmap.blue)[viacursor.image.fg_color] & | ||
1145 | 0xFF00) >> 8); | ||
1146 | break; | ||
1147 | default: | ||
1148 | return 0; | ||
1149 | } | ||
1150 | |||
1151 | /* This is indeed a patch for VT3324/VT3353 */ | ||
1152 | if (!info->par) | ||
1153 | return 0; | ||
1154 | p_viafb_par = (struct viafb_par *)info->par; | ||
1155 | |||
1156 | if ((p_viafb_par->chip_info->gfx_chip_name == | ||
1157 | UNICHROME_CX700) || | ||
1158 | ((p_viafb_par->chip_info->gfx_chip_name == | ||
1159 | UNICHROME_VX800))) { | ||
1160 | bg_col = | ||
1161 | (((info->cmap.red)[viacursor.image.bg_color] & | ||
1162 | 0xFFC0) << 14) | | ||
1163 | (((info->cmap.green)[viacursor.image.bg_color] & | ||
1164 | 0xFFC0) << 4) | | ||
1165 | (((info->cmap.blue)[viacursor.image.bg_color] & | ||
1166 | 0xFFC0) >> 6); | ||
1167 | fg_col = | ||
1168 | (((info->cmap.red)[viacursor.image.fg_color] & | ||
1169 | 0xFFC0) << 14) | | ||
1170 | (((info->cmap.green)[viacursor.image.fg_color] & | ||
1171 | 0xFFC0) << 4) | | ||
1172 | (((info->cmap.blue)[viacursor.image.fg_color] & | ||
1173 | 0xFFC0) >> 6); | ||
1174 | } | ||
1175 | |||
1176 | writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG); | ||
1177 | writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG); | ||
1178 | } | ||
1179 | |||
1180 | if (cursor->set & FB_CUR_SETSHAPE) { | ||
1181 | size = | ||
1182 | ((viacursor.image.width + 7) >> 3) * | ||
1183 | viacursor.image.height; | ||
1184 | |||
1185 | if (MAX_CURS == 32) { | ||
1186 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { | ||
1187 | data_bak[i] = 0x0; | ||
1188 | data_bak[i + 1] = 0xFFFFFFFF; | ||
1189 | i += 1; | ||
1190 | } | ||
1191 | } else if (MAX_CURS == 64) { | ||
1192 | for (i = 0; i < (CURSOR_SIZE / 32); i++) { | ||
1193 | data_bak[i] = 0x0; | ||
1194 | data_bak[i + 1] = 0x0; | ||
1195 | data_bak[i + 2] = 0xFFFFFFFF; | ||
1196 | data_bak[i + 3] = 0xFFFFFFFF; | ||
1197 | i += 3; | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | switch (viacursor.rop) { | ||
1202 | case ROP_XOR: | ||
1203 | for (i = 0; i < size; i++) | ||
1204 | data[i] = viacursor.mask[i]; | ||
1205 | break; | ||
1206 | case ROP_COPY: | ||
1207 | |||
1208 | for (i = 0; i < size; i++) | ||
1209 | data[i] = viacursor.mask[i]; | ||
1210 | break; | ||
1211 | default: | ||
1212 | break; | ||
1213 | } | ||
1214 | |||
1215 | if (MAX_CURS == 32) { | ||
1216 | for (i = 0; i < size; i++) { | ||
1217 | data_bak[j] = (u32) data[i]; | ||
1218 | data_bak[j + 1] = ~data_bak[j]; | ||
1219 | j += 2; | ||
1220 | } | ||
1221 | } else if (MAX_CURS == 64) { | ||
1222 | for (i = 0; i < size; i++) { | ||
1223 | data_bak[j] = (u32) data[i]; | ||
1224 | data_bak[j + 1] = 0x0; | ||
1225 | data_bak[j + 2] = ~data_bak[j]; | ||
1226 | data_bak[j + 3] = ~data_bak[j + 1]; | ||
1227 | j += 4; | ||
1228 | } | ||
1229 | } | ||
1230 | |||
1231 | memcpy(((struct viafb_par *)(info->par))->fbmem_virt + | ||
1232 | ((struct viafb_par *)(info->par))->cursor_start, | ||
1233 | data_bak, CURSOR_SIZE); | ||
1234 | } | ||
1235 | |||
1236 | if (viacursor.enable) | ||
1237 | viafb_show_hw_cursor(info, HW_Cursor_ON); | ||
1238 | |||
1239 | return 0; | ||
1240 | } | ||
1241 | |||
1242 | static int viafb_sync(struct fb_info *info) | ||
1243 | { | ||
1244 | if (viafb_accel) | ||
1245 | viafb_wait_engine_idle(); | ||
1246 | return 0; | ||
1247 | } | ||
1248 | |||
1249 | int viafb_get_mode_index(int hres, int vres, int flag) | ||
1250 | { | ||
1251 | u32 i; | ||
1252 | DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n"); | ||
1253 | |||
1254 | for (i = 0; viafb_modentry[i].mode_index != VIA_RES_INVALID; i++) | ||
1255 | if (viafb_modentry[i].xres == hres && | ||
1256 | viafb_modentry[i].yres == vres) | ||
1257 | break; | ||
1258 | |||
1259 | viafb_resMode = viafb_modentry[i].mode_index; | ||
1260 | if (flag) | ||
1261 | viafb_mode1 = viafb_modentry[i].mode_res; | ||
1262 | else | ||
1263 | viafb_mode = viafb_modentry[i].mode_res; | ||
1264 | |||
1265 | return viafb_resMode; | ||
1266 | } | ||
1267 | |||
1268 | static void check_available_device_to_enable(int device_id) | ||
1269 | { | ||
1270 | int device_num = 0; | ||
1271 | |||
1272 | /* Initialize: */ | ||
1273 | viafb_CRT_ON = STATE_OFF; | ||
1274 | viafb_DVI_ON = STATE_OFF; | ||
1275 | viafb_LCD_ON = STATE_OFF; | ||
1276 | viafb_LCD2_ON = STATE_OFF; | ||
1277 | viafb_DeviceStatus = None_Device; | ||
1278 | |||
1279 | if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) { | ||
1280 | viafb_CRT_ON = STATE_ON; | ||
1281 | device_num++; | ||
1282 | viafb_DeviceStatus |= CRT_Device; | ||
1283 | } | ||
1284 | |||
1285 | if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) { | ||
1286 | viafb_DVI_ON = STATE_ON; | ||
1287 | device_num++; | ||
1288 | viafb_DeviceStatus |= DVI_Device; | ||
1289 | } | ||
1290 | |||
1291 | if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) { | ||
1292 | viafb_LCD_ON = STATE_ON; | ||
1293 | device_num++; | ||
1294 | viafb_DeviceStatus |= LCD_Device; | ||
1295 | } | ||
1296 | |||
1297 | if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) { | ||
1298 | viafb_LCD2_ON = STATE_ON; | ||
1299 | device_num++; | ||
1300 | viafb_DeviceStatus |= LCD2_Device; | ||
1301 | } | ||
1302 | |||
1303 | if (viafb_DeviceStatus == None_Device) { | ||
1304 | /* Use CRT as default active device: */ | ||
1305 | viafb_CRT_ON = STATE_ON; | ||
1306 | viafb_DeviceStatus = CRT_Device; | ||
1307 | } | ||
1308 | DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus); | ||
1309 | } | ||
1310 | |||
1311 | static void viafb_set_device(struct device_t active_dev) | ||
1312 | { | ||
1313 | /* Check available device to enable: */ | ||
1314 | int device_id = None_Device; | ||
1315 | if (active_dev.crt) | ||
1316 | device_id |= CRT_Device; | ||
1317 | if (active_dev.dvi) | ||
1318 | device_id |= DVI_Device; | ||
1319 | if (active_dev.lcd) | ||
1320 | device_id |= LCD_Device; | ||
1321 | |||
1322 | check_available_device_to_enable(device_id); | ||
1323 | |||
1324 | /* Check property of LCD: */ | ||
1325 | if (viafb_LCD_ON) { | ||
1326 | if (active_dev.lcd_dsp_cent) { | ||
1327 | viaparinfo->lvds_setting_info->display_method = | ||
1328 | viafb_lcd_dsp_method = LCD_CENTERING; | ||
1329 | } else { | ||
1330 | viaparinfo->lvds_setting_info->display_method = | ||
1331 | viafb_lcd_dsp_method = LCD_EXPANDSION; | ||
1332 | } | ||
1333 | |||
1334 | if (active_dev.lcd_mode == LCD_SPWG) { | ||
1335 | viaparinfo->lvds_setting_info->lcd_mode = | ||
1336 | viafb_lcd_mode = LCD_SPWG; | ||
1337 | } else { | ||
1338 | viaparinfo->lvds_setting_info->lcd_mode = | ||
1339 | viafb_lcd_mode = LCD_OPENLDI; | ||
1340 | } | ||
1341 | |||
1342 | if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) { | ||
1343 | viafb_lcd_panel_id = active_dev.lcd_panel_id; | ||
1344 | viafb_init_lcd_size(); | ||
1345 | } | ||
1346 | } | ||
1347 | |||
1348 | /* Check property of mode: */ | ||
1349 | if (!active_dev.xres1) | ||
1350 | viafb_second_xres = 640; | ||
1351 | else | ||
1352 | viafb_second_xres = active_dev.xres1; | ||
1353 | if (!active_dev.yres1) | ||
1354 | viafb_second_yres = 480; | ||
1355 | else | ||
1356 | viafb_second_yres = active_dev.yres1; | ||
1357 | if (active_dev.bpp != 0) | ||
1358 | viafb_bpp = active_dev.bpp; | ||
1359 | if (active_dev.bpp1 != 0) | ||
1360 | viafb_bpp1 = active_dev.bpp1; | ||
1361 | if (active_dev.refresh != 0) | ||
1362 | viafb_refresh = active_dev.refresh; | ||
1363 | if (active_dev.refresh1 != 0) | ||
1364 | viafb_refresh1 = active_dev.refresh1; | ||
1365 | if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON)) | ||
1366 | viafb_SAMM_ON = active_dev.samm; | ||
1367 | viafb_primary_dev = active_dev.primary_dev; | ||
1368 | |||
1369 | viafb_set_start_addr(); | ||
1370 | viafb_set_iga_path(); | ||
1371 | } | ||
1372 | |||
1373 | static void viafb_set_video_device(u32 video_dev_info) | ||
1374 | { | ||
1375 | viaparinfo->video_on_crt = STATE_OFF; | ||
1376 | viaparinfo->video_on_dvi = STATE_OFF; | ||
1377 | viaparinfo->video_on_lcd = STATE_OFF; | ||
1378 | |||
1379 | /* Check available device to enable: */ | ||
1380 | if ((video_dev_info & CRT_Device) == CRT_Device) | ||
1381 | viaparinfo->video_on_crt = STATE_ON; | ||
1382 | else if ((video_dev_info & DVI_Device) == DVI_Device) | ||
1383 | viaparinfo->video_on_dvi = STATE_ON; | ||
1384 | else if ((video_dev_info & LCD_Device) == LCD_Device) | ||
1385 | viaparinfo->video_on_lcd = STATE_ON; | ||
1386 | } | ||
1387 | |||
1388 | static void viafb_get_video_device(u32 *video_dev_info) | ||
1389 | { | ||
1390 | *video_dev_info = None_Device; | ||
1391 | if (viaparinfo->video_on_crt == STATE_ON) | ||
1392 | *video_dev_info |= CRT_Device; | ||
1393 | else if (viaparinfo->video_on_dvi == STATE_ON) | ||
1394 | *video_dev_info |= DVI_Device; | ||
1395 | else if (viaparinfo->video_on_lcd == STATE_ON) | ||
1396 | *video_dev_info |= LCD_Device; | ||
1397 | } | ||
1398 | |||
1399 | static int get_primary_device(void) | ||
1400 | { | ||
1401 | int primary_device = 0; | ||
1402 | /* Rule: device on iga1 path are the primary device. */ | ||
1403 | if (viafb_SAMM_ON) { | ||
1404 | if (viafb_CRT_ON) { | ||
1405 | if (viaparinfo->crt_setting_info->iga_path == IGA1) { | ||
1406 | DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", | ||
1407 | viaparinfo-> | ||
1408 | crt_setting_info->iga_path); | ||
1409 | primary_device = CRT_Device; | ||
1410 | } | ||
1411 | } | ||
1412 | if (viafb_DVI_ON) { | ||
1413 | if (viaparinfo->tmds_setting_info->iga_path == IGA1) { | ||
1414 | DEBUG_MSG(KERN_INFO "DVI IGA Path:%d\n", | ||
1415 | viaparinfo-> | ||
1416 | tmds_setting_info->iga_path); | ||
1417 | primary_device = DVI_Device; | ||
1418 | } | ||
1419 | } | ||
1420 | if (viafb_LCD_ON) { | ||
1421 | if (viaparinfo->lvds_setting_info->iga_path == IGA1) { | ||
1422 | DEBUG_MSG(KERN_INFO "LCD IGA Path:%d\n", | ||
1423 | viaparinfo-> | ||
1424 | lvds_setting_info->iga_path); | ||
1425 | primary_device = LCD_Device; | ||
1426 | } | ||
1427 | } | ||
1428 | if (viafb_LCD2_ON) { | ||
1429 | if (viaparinfo->lvds_setting_info2->iga_path == IGA1) { | ||
1430 | DEBUG_MSG(KERN_INFO "LCD2 IGA Path:%d\n", | ||
1431 | viaparinfo-> | ||
1432 | lvds_setting_info2->iga_path); | ||
1433 | primary_device = LCD2_Device; | ||
1434 | } | ||
1435 | } | ||
1436 | } | ||
1437 | return primary_device; | ||
1438 | } | ||
1439 | |||
1440 | static u8 is_duoview(void) | ||
1441 | { | ||
1442 | if (0 == viafb_SAMM_ON) { | ||
1443 | if (viafb_LCD_ON + viafb_LCD2_ON + | ||
1444 | viafb_DVI_ON + viafb_CRT_ON == 2) | ||
1445 | return true; | ||
1446 | return false; | ||
1447 | } else { | ||
1448 | return false; | ||
1449 | } | ||
1450 | } | ||
1451 | |||
1452 | static void apply_second_mode_setting(struct fb_var_screeninfo | ||
1453 | *sec_var) | ||
1454 | { | ||
1455 | u32 htotal, vtotal, long_refresh; | ||
1456 | |||
1457 | htotal = sec_var->xres + sec_var->left_margin + | ||
1458 | sec_var->right_margin + sec_var->hsync_len; | ||
1459 | vtotal = sec_var->yres + sec_var->upper_margin + | ||
1460 | sec_var->lower_margin + sec_var->vsync_len; | ||
1461 | if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) { | ||
1462 | /*Is 32 bytes alignment? */ | ||
1463 | /*32 pixel alignment */ | ||
1464 | sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31; | ||
1465 | } | ||
1466 | |||
1467 | htotal = sec_var->xres + sec_var->left_margin + | ||
1468 | sec_var->right_margin + sec_var->hsync_len; | ||
1469 | vtotal = sec_var->yres + sec_var->upper_margin + | ||
1470 | sec_var->lower_margin + sec_var->vsync_len; | ||
1471 | long_refresh = 1000000000UL / sec_var->pixclock * 1000; | ||
1472 | long_refresh /= (htotal * vtotal); | ||
1473 | |||
1474 | viafb_second_xres = sec_var->xres; | ||
1475 | viafb_second_yres = sec_var->yres; | ||
1476 | viafb_second_virtual_xres = sec_var->xres_virtual; | ||
1477 | viafb_second_virtual_yres = sec_var->yres_virtual; | ||
1478 | viafb_bpp1 = sec_var->bits_per_pixel; | ||
1479 | viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres, | ||
1480 | long_refresh); | ||
1481 | } | ||
1482 | |||
1483 | static int apply_device_setting(struct viafb_ioctl_setting setting_info, | ||
1484 | struct fb_info *info) | ||
1485 | { | ||
1486 | int need_set_mode = 0; | ||
1487 | DEBUG_MSG(KERN_INFO "apply_device_setting\n"); | ||
1488 | |||
1489 | if (setting_info.device_flag) { | ||
1490 | need_set_mode = 1; | ||
1491 | check_available_device_to_enable(setting_info.device_status); | ||
1492 | } | ||
1493 | |||
1494 | /* Unlock LCD's operation according to LCD flag | ||
1495 | and check if the setting value is valid. */ | ||
1496 | /* If the value is valid, apply the new setting value to the device. */ | ||
1497 | if (viafb_LCD_ON) { | ||
1498 | if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) { | ||
1499 | need_set_mode = 1; | ||
1500 | if (setting_info.lcd_attributes.display_center) { | ||
1501 | /* Centering */ | ||
1502 | viaparinfo->lvds_setting_info->display_method = | ||
1503 | LCD_CENTERING; | ||
1504 | viafb_lcd_dsp_method = LCD_CENTERING; | ||
1505 | viaparinfo->lvds_setting_info2->display_method = | ||
1506 | viafb_lcd_dsp_method = LCD_CENTERING; | ||
1507 | } else { | ||
1508 | /* expandsion */ | ||
1509 | viaparinfo->lvds_setting_info->display_method = | ||
1510 | LCD_EXPANDSION; | ||
1511 | viafb_lcd_dsp_method = LCD_EXPANDSION; | ||
1512 | viaparinfo->lvds_setting_info2->display_method = | ||
1513 | LCD_EXPANDSION; | ||
1514 | viafb_lcd_dsp_method = LCD_EXPANDSION; | ||
1515 | } | ||
1516 | } | ||
1517 | |||
1518 | if (setting_info.lcd_operation_flag & OP_LCD_MODE) { | ||
1519 | need_set_mode = 1; | ||
1520 | if (setting_info.lcd_attributes.lcd_mode == | ||
1521 | LCD_SPWG) { | ||
1522 | viaparinfo->lvds_setting_info->lcd_mode = | ||
1523 | viafb_lcd_mode = LCD_SPWG; | ||
1524 | } else { | ||
1525 | viaparinfo->lvds_setting_info->lcd_mode = | ||
1526 | viafb_lcd_mode = LCD_OPENLDI; | ||
1527 | } | ||
1528 | viaparinfo->lvds_setting_info2->lcd_mode = | ||
1529 | viaparinfo->lvds_setting_info->lcd_mode; | ||
1530 | } | ||
1531 | |||
1532 | if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) { | ||
1533 | need_set_mode = 1; | ||
1534 | if (setting_info.lcd_attributes.panel_id <= | ||
1535 | LCD_PANEL_ID_MAXIMUM) { | ||
1536 | viafb_lcd_panel_id = | ||
1537 | setting_info.lcd_attributes.panel_id; | ||
1538 | viafb_init_lcd_size(); | ||
1539 | } | ||
1540 | } | ||
1541 | } | ||
1542 | |||
1543 | if (0 != (setting_info.samm_status & OP_SAMM)) { | ||
1544 | setting_info.samm_status = | ||
1545 | setting_info.samm_status & (~OP_SAMM); | ||
1546 | if (setting_info.samm_status == 0 | ||
1547 | || setting_info.samm_status == 1) { | ||
1548 | viafb_SAMM_ON = setting_info.samm_status; | ||
1549 | |||
1550 | if (viafb_SAMM_ON) | ||
1551 | viafb_primary_dev = setting_info.primary_device; | ||
1552 | |||
1553 | viafb_set_start_addr(); | ||
1554 | viafb_set_iga_path(); | ||
1555 | } | ||
1556 | need_set_mode = 1; | ||
1557 | } | ||
1558 | |||
1559 | viaparinfo->duoview = is_duoview(); | ||
1560 | |||
1561 | if (!need_set_mode) { | ||
1562 | ; | ||
1563 | } else { | ||
1564 | viafb_set_iga_path(); | ||
1565 | viafb_set_par(info); | ||
1566 | } | ||
1567 | return true; | ||
1568 | } | ||
1569 | |||
1570 | static void retrieve_device_setting(struct viafb_ioctl_setting | ||
1571 | *setting_info) | ||
1572 | { | ||
1573 | |||
1574 | /* get device status */ | ||
1575 | if (viafb_CRT_ON == 1) | ||
1576 | setting_info->device_status = CRT_Device; | ||
1577 | if (viafb_DVI_ON == 1) | ||
1578 | setting_info->device_status |= DVI_Device; | ||
1579 | if (viafb_LCD_ON == 1) | ||
1580 | setting_info->device_status |= LCD_Device; | ||
1581 | if (viafb_LCD2_ON == 1) | ||
1582 | setting_info->device_status |= LCD2_Device; | ||
1583 | if ((viaparinfo->video_on_crt == 1) && (viafb_CRT_ON == 1)) { | ||
1584 | setting_info->video_device_status = | ||
1585 | viaparinfo->crt_setting_info->iga_path; | ||
1586 | } else if ((viaparinfo->video_on_dvi == 1) && (viafb_DVI_ON == 1)) { | ||
1587 | setting_info->video_device_status = | ||
1588 | viaparinfo->tmds_setting_info->iga_path; | ||
1589 | } else if ((viaparinfo->video_on_lcd == 1) && (viafb_LCD_ON == 1)) { | ||
1590 | setting_info->video_device_status = | ||
1591 | viaparinfo->lvds_setting_info->iga_path; | ||
1592 | } else { | ||
1593 | setting_info->video_device_status = 0; | ||
1594 | } | ||
1595 | |||
1596 | setting_info->samm_status = viafb_SAMM_ON; | ||
1597 | setting_info->primary_device = get_primary_device(); | ||
1598 | |||
1599 | setting_info->first_dev_bpp = viafb_bpp; | ||
1600 | setting_info->second_dev_bpp = viafb_bpp1; | ||
1601 | |||
1602 | setting_info->first_dev_refresh = viafb_refresh; | ||
1603 | setting_info->second_dev_refresh = viafb_refresh1; | ||
1604 | |||
1605 | setting_info->first_dev_hor_res = viafb_hotplug_Xres; | ||
1606 | setting_info->first_dev_ver_res = viafb_hotplug_Yres; | ||
1607 | setting_info->second_dev_hor_res = viafb_second_xres; | ||
1608 | setting_info->second_dev_ver_res = viafb_second_yres; | ||
1609 | |||
1610 | /* Get lcd attributes */ | ||
1611 | setting_info->lcd_attributes.display_center = viafb_lcd_dsp_method; | ||
1612 | setting_info->lcd_attributes.panel_id = viafb_lcd_panel_id; | ||
1613 | setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode; | ||
1614 | } | ||
1615 | |||
1616 | static void parse_active_dev(void) | ||
1617 | { | ||
1618 | viafb_CRT_ON = STATE_OFF; | ||
1619 | viafb_DVI_ON = STATE_OFF; | ||
1620 | viafb_LCD_ON = STATE_OFF; | ||
1621 | viafb_LCD2_ON = STATE_OFF; | ||
1622 | /* 1. Modify the active status of devices. */ | ||
1623 | /* 2. Keep the order of devices, so we can set corresponding | ||
1624 | IGA path to devices in SAMM case. */ | ||
1625 | /* Note: The previous of active_dev is primary device, | ||
1626 | and the following is secondary device. */ | ||
1627 | if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) { | ||
1628 | /* CRT+DVI */ | ||
1629 | viafb_CRT_ON = STATE_ON; | ||
1630 | viafb_DVI_ON = STATE_ON; | ||
1631 | viafb_primary_dev = CRT_Device; | ||
1632 | } else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) { | ||
1633 | /* DVI+CRT */ | ||
1634 | viafb_CRT_ON = STATE_ON; | ||
1635 | viafb_DVI_ON = STATE_ON; | ||
1636 | viafb_primary_dev = DVI_Device; | ||
1637 | } else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) { | ||
1638 | /* CRT+LCD */ | ||
1639 | viafb_CRT_ON = STATE_ON; | ||
1640 | viafb_LCD_ON = STATE_ON; | ||
1641 | viafb_primary_dev = CRT_Device; | ||
1642 | } else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) { | ||
1643 | /* LCD+CRT */ | ||
1644 | viafb_CRT_ON = STATE_ON; | ||
1645 | viafb_LCD_ON = STATE_ON; | ||
1646 | viafb_primary_dev = LCD_Device; | ||
1647 | } else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) { | ||
1648 | /* DVI+LCD */ | ||
1649 | viafb_DVI_ON = STATE_ON; | ||
1650 | viafb_LCD_ON = STATE_ON; | ||
1651 | viafb_primary_dev = DVI_Device; | ||
1652 | } else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) { | ||
1653 | /* LCD+DVI */ | ||
1654 | viafb_DVI_ON = STATE_ON; | ||
1655 | viafb_LCD_ON = STATE_ON; | ||
1656 | viafb_primary_dev = LCD_Device; | ||
1657 | } else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) { | ||
1658 | viafb_LCD_ON = STATE_ON; | ||
1659 | viafb_LCD2_ON = STATE_ON; | ||
1660 | viafb_primary_dev = LCD_Device; | ||
1661 | } else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) { | ||
1662 | viafb_LCD_ON = STATE_ON; | ||
1663 | viafb_LCD2_ON = STATE_ON; | ||
1664 | viafb_primary_dev = LCD2_Device; | ||
1665 | } else if (!strncmp(viafb_active_dev, "CRT", 3)) { | ||
1666 | /* CRT only */ | ||
1667 | viafb_CRT_ON = STATE_ON; | ||
1668 | viafb_SAMM_ON = STATE_OFF; | ||
1669 | } else if (!strncmp(viafb_active_dev, "DVI", 3)) { | ||
1670 | /* DVI only */ | ||
1671 | viafb_DVI_ON = STATE_ON; | ||
1672 | viafb_SAMM_ON = STATE_OFF; | ||
1673 | } else if (!strncmp(viafb_active_dev, "LCD", 3)) { | ||
1674 | /* LCD only */ | ||
1675 | viafb_LCD_ON = STATE_ON; | ||
1676 | viafb_SAMM_ON = STATE_OFF; | ||
1677 | } else { | ||
1678 | viafb_CRT_ON = STATE_ON; | ||
1679 | viafb_SAMM_ON = STATE_OFF; | ||
1680 | } | ||
1681 | viaparinfo->duoview = is_duoview(); | ||
1682 | } | ||
1683 | |||
1684 | static void parse_video_dev(void) | ||
1685 | { | ||
1686 | viaparinfo->video_on_crt = STATE_OFF; | ||
1687 | viaparinfo->video_on_dvi = STATE_OFF; | ||
1688 | viaparinfo->video_on_lcd = STATE_OFF; | ||
1689 | |||
1690 | if (!strncmp(viafb_video_dev, "CRT", 3)) { | ||
1691 | /* Video on CRT */ | ||
1692 | viaparinfo->video_on_crt = STATE_ON; | ||
1693 | } else if (!strncmp(viafb_video_dev, "DVI", 3)) { | ||
1694 | /* Video on DVI */ | ||
1695 | viaparinfo->video_on_dvi = STATE_ON; | ||
1696 | } else if (!strncmp(viafb_video_dev, "LCD", 3)) { | ||
1697 | /* Video on LCD */ | ||
1698 | viaparinfo->video_on_lcd = STATE_ON; | ||
1699 | } | ||
1700 | } | ||
1701 | |||
1702 | static int parse_port(char *opt_str, int *output_interface) | ||
1703 | { | ||
1704 | if (!strncmp(opt_str, "DVP0", 4)) | ||
1705 | *output_interface = INTERFACE_DVP0; | ||
1706 | else if (!strncmp(opt_str, "DVP1", 4)) | ||
1707 | *output_interface = INTERFACE_DVP1; | ||
1708 | else if (!strncmp(opt_str, "DFP_HIGHLOW", 11)) | ||
1709 | *output_interface = INTERFACE_DFP; | ||
1710 | else if (!strncmp(opt_str, "DFP_HIGH", 8)) | ||
1711 | *output_interface = INTERFACE_DFP_HIGH; | ||
1712 | else if (!strncmp(opt_str, "DFP_LOW", 7)) | ||
1713 | *output_interface = INTERFACE_DFP_LOW; | ||
1714 | else | ||
1715 | *output_interface = INTERFACE_NONE; | ||
1716 | return 0; | ||
1717 | } | ||
1718 | |||
1719 | static void parse_lcd_port(void) | ||
1720 | { | ||
1721 | parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info. | ||
1722 | output_interface); | ||
1723 | /*Initialize to avoid unexpected behavior */ | ||
1724 | viaparinfo->chip_info->lvds_chip_info2.output_interface = | ||
1725 | INTERFACE_NONE; | ||
1726 | |||
1727 | DEBUG_MSG(KERN_INFO "parse_lcd_port: viafb_lcd_port:%s,interface:%d\n", | ||
1728 | viafb_lcd_port, viaparinfo->chip_info->lvds_chip_info. | ||
1729 | output_interface); | ||
1730 | } | ||
1731 | |||
1732 | static void parse_dvi_port(void) | ||
1733 | { | ||
1734 | parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info. | ||
1735 | output_interface); | ||
1736 | |||
1737 | DEBUG_MSG(KERN_INFO "parse_dvi_port: viafb_dvi_port:%s,interface:%d\n", | ||
1738 | viafb_dvi_port, viaparinfo->chip_info->tmds_chip_info. | ||
1739 | output_interface); | ||
1740 | } | ||
1741 | |||
1742 | /* | ||
1743 | * The proc filesystem read/write function, a simple proc implement to | ||
1744 | * get/set the value of DPA DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, | ||
1745 | * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], | ||
1746 | * CR9B, SR65, CR97, CR99 | ||
1747 | */ | ||
1748 | static int viafb_dvp0_proc_read(char *buf, char **start, off_t offset, | ||
1749 | int count, int *eof, void *data) | ||
1750 | { | ||
1751 | int len = 0; | ||
1752 | u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0; | ||
1753 | dvp0_data_dri = | ||
1754 | (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 | | ||
1755 | (viafb_read_reg(VIASR, SR1B) & BIT1) >> 1; | ||
1756 | dvp0_clk_dri = | ||
1757 | (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 | | ||
1758 | (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2; | ||
1759 | dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f; | ||
1760 | len += | ||
1761 | sprintf(buf + len, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri); | ||
1762 | *eof = 1; /*Inform kernel end of data */ | ||
1763 | return len; | ||
1764 | } | ||
1765 | static int viafb_dvp0_proc_write(struct file *file, | ||
1766 | const char __user *buffer, unsigned long count, void *data) | ||
1767 | { | ||
1768 | char buf[20], *value, *pbuf; | ||
1769 | u8 reg_val = 0; | ||
1770 | unsigned long length, i; | ||
1771 | if (count < 1) | ||
1772 | return -EINVAL; | ||
1773 | length = count > 20 ? 20 : count; | ||
1774 | if (copy_from_user(&buf[0], buffer, length)) | ||
1775 | return -EFAULT; | ||
1776 | buf[length - 1] = '\0'; /*Ensure end string */ | ||
1777 | pbuf = &buf[0]; | ||
1778 | for (i = 0; i < 3; i++) { | ||
1779 | value = strsep(&pbuf, " "); | ||
1780 | if (value != NULL) { | ||
1781 | strict_strtoul(value, 0, (unsigned long *)®_val); | ||
1782 | DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i, | ||
1783 | reg_val); | ||
1784 | switch (i) { | ||
1785 | case 0: | ||
1786 | viafb_write_reg_mask(CR96, VIACR, | ||
1787 | reg_val, 0x0f); | ||
1788 | break; | ||
1789 | case 1: | ||
1790 | viafb_write_reg_mask(SR2A, VIASR, | ||
1791 | reg_val << 4, BIT5); | ||
1792 | viafb_write_reg_mask(SR1B, VIASR, | ||
1793 | reg_val << 1, BIT1); | ||
1794 | break; | ||
1795 | case 2: | ||
1796 | viafb_write_reg_mask(SR2A, VIASR, | ||
1797 | reg_val << 3, BIT4); | ||
1798 | viafb_write_reg_mask(SR1E, VIASR, | ||
1799 | reg_val << 2, BIT2); | ||
1800 | break; | ||
1801 | default: | ||
1802 | break; | ||
1803 | } | ||
1804 | } else { | ||
1805 | break; | ||
1806 | } | ||
1807 | } | ||
1808 | return count; | ||
1809 | } | ||
1810 | static int viafb_dvp1_proc_read(char *buf, char **start, off_t offset, | ||
1811 | int count, int *eof, void *data) | ||
1812 | { | ||
1813 | int len = 0; | ||
1814 | u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0; | ||
1815 | dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f; | ||
1816 | dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2; | ||
1817 | dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03; | ||
1818 | len += | ||
1819 | sprintf(buf + len, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri); | ||
1820 | *eof = 1; /*Inform kernel end of data */ | ||
1821 | return len; | ||
1822 | } | ||
1823 | static int viafb_dvp1_proc_write(struct file *file, | ||
1824 | const char __user *buffer, unsigned long count, void *data) | ||
1825 | { | ||
1826 | char buf[20], *value, *pbuf; | ||
1827 | u8 reg_val = 0; | ||
1828 | unsigned long length, i; | ||
1829 | if (count < 1) | ||
1830 | return -EINVAL; | ||
1831 | length = count > 20 ? 20 : count; | ||
1832 | if (copy_from_user(&buf[0], buffer, length)) | ||
1833 | return -EFAULT; | ||
1834 | buf[length - 1] = '\0'; /*Ensure end string */ | ||
1835 | pbuf = &buf[0]; | ||
1836 | for (i = 0; i < 3; i++) { | ||
1837 | value = strsep(&pbuf, " "); | ||
1838 | if (value != NULL) { | ||
1839 | strict_strtoul(value, 0, (unsigned long *)®_val); | ||
1840 | switch (i) { | ||
1841 | case 0: | ||
1842 | viafb_write_reg_mask(CR9B, VIACR, | ||
1843 | reg_val, 0x0f); | ||
1844 | break; | ||
1845 | case 1: | ||
1846 | viafb_write_reg_mask(SR65, VIASR, | ||
1847 | reg_val << 2, 0x0c); | ||
1848 | break; | ||
1849 | case 2: | ||
1850 | viafb_write_reg_mask(SR65, VIASR, | ||
1851 | reg_val, 0x03); | ||
1852 | break; | ||
1853 | default: | ||
1854 | break; | ||
1855 | } | ||
1856 | } else { | ||
1857 | break; | ||
1858 | } | ||
1859 | } | ||
1860 | return count; | ||
1861 | } | ||
1862 | |||
1863 | static int viafb_dfph_proc_read(char *buf, char **start, off_t offset, | ||
1864 | int count, int *eof, void *data) | ||
1865 | { | ||
1866 | int len = 0; | ||
1867 | u8 dfp_high = 0; | ||
1868 | dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f; | ||
1869 | len += sprintf(buf + len, "%x\n", dfp_high); | ||
1870 | *eof = 1; /*Inform kernel end of data */ | ||
1871 | return len; | ||
1872 | } | ||
1873 | static int viafb_dfph_proc_write(struct file *file, | ||
1874 | const char __user *buffer, unsigned long count, void *data) | ||
1875 | { | ||
1876 | char buf[20]; | ||
1877 | u8 reg_val = 0; | ||
1878 | unsigned long length; | ||
1879 | if (count < 1) | ||
1880 | return -EINVAL; | ||
1881 | length = count > 20 ? 20 : count; | ||
1882 | if (copy_from_user(&buf[0], buffer, length)) | ||
1883 | return -EFAULT; | ||
1884 | buf[length - 1] = '\0'; /*Ensure end string */ | ||
1885 | strict_strtoul(&buf[0], 0, (unsigned long *)®_val); | ||
1886 | viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); | ||
1887 | return count; | ||
1888 | } | ||
1889 | static int viafb_dfpl_proc_read(char *buf, char **start, off_t offset, | ||
1890 | int count, int *eof, void *data) | ||
1891 | { | ||
1892 | int len = 0; | ||
1893 | u8 dfp_low = 0; | ||
1894 | dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f; | ||
1895 | len += sprintf(buf + len, "%x\n", dfp_low); | ||
1896 | *eof = 1; /*Inform kernel end of data */ | ||
1897 | return len; | ||
1898 | } | ||
1899 | static int viafb_dfpl_proc_write(struct file *file, | ||
1900 | const char __user *buffer, unsigned long count, void *data) | ||
1901 | { | ||
1902 | char buf[20]; | ||
1903 | u8 reg_val = 0; | ||
1904 | unsigned long length; | ||
1905 | if (count < 1) | ||
1906 | return -EINVAL; | ||
1907 | length = count > 20 ? 20 : count; | ||
1908 | if (copy_from_user(&buf[0], buffer, length)) | ||
1909 | return -EFAULT; | ||
1910 | buf[length - 1] = '\0'; /*Ensure end string */ | ||
1911 | strict_strtoul(&buf[0], 0, (unsigned long *)®_val); | ||
1912 | viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); | ||
1913 | return count; | ||
1914 | } | ||
1915 | static int viafb_vt1636_proc_read(char *buf, char **start, | ||
1916 | off_t offset, int count, int *eof, void *data) | ||
1917 | { | ||
1918 | int len = 0; | ||
1919 | u8 vt1636_08 = 0, vt1636_09 = 0; | ||
1920 | switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { | ||
1921 | case VT1636_LVDS: | ||
1922 | vt1636_08 = | ||
1923 | viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, | ||
1924 | &viaparinfo->chip_info->lvds_chip_info, 0x08) & 0x0f; | ||
1925 | vt1636_09 = | ||
1926 | viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, | ||
1927 | &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f; | ||
1928 | len += sprintf(buf + len, "%x %x\n", vt1636_08, vt1636_09); | ||
1929 | break; | ||
1930 | default: | ||
1931 | break; | ||
1932 | } | ||
1933 | switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { | ||
1934 | case VT1636_LVDS: | ||
1935 | vt1636_08 = | ||
1936 | viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, | ||
1937 | &viaparinfo->chip_info->lvds_chip_info2, 0x08) & 0x0f; | ||
1938 | vt1636_09 = | ||
1939 | viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, | ||
1940 | &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f; | ||
1941 | len += sprintf(buf + len, " %x %x\n", vt1636_08, vt1636_09); | ||
1942 | break; | ||
1943 | default: | ||
1944 | break; | ||
1945 | } | ||
1946 | *eof = 1; /*Inform kernel end of data */ | ||
1947 | return len; | ||
1948 | } | ||
1949 | static int viafb_vt1636_proc_write(struct file *file, | ||
1950 | const char __user *buffer, unsigned long count, void *data) | ||
1951 | { | ||
1952 | char buf[30], *value, *pbuf; | ||
1953 | struct IODATA reg_val; | ||
1954 | unsigned long length, i; | ||
1955 | if (count < 1) | ||
1956 | return -EINVAL; | ||
1957 | length = count > 30 ? 30 : count; | ||
1958 | if (copy_from_user(&buf[0], buffer, length)) | ||
1959 | return -EFAULT; | ||
1960 | buf[length - 1] = '\0'; /*Ensure end string */ | ||
1961 | pbuf = &buf[0]; | ||
1962 | switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { | ||
1963 | case VT1636_LVDS: | ||
1964 | for (i = 0; i < 2; i++) { | ||
1965 | value = strsep(&pbuf, " "); | ||
1966 | if (value != NULL) { | ||
1967 | strict_strtoul(value, 0, | ||
1968 | (unsigned long *)®_val.Data); | ||
1969 | switch (i) { | ||
1970 | case 0: | ||
1971 | reg_val.Index = 0x08; | ||
1972 | reg_val.Mask = 0x0f; | ||
1973 | viafb_gpio_i2c_write_mask_lvds | ||
1974 | (viaparinfo->lvds_setting_info, | ||
1975 | &viaparinfo-> | ||
1976 | chip_info->lvds_chip_info, | ||
1977 | reg_val); | ||
1978 | break; | ||
1979 | case 1: | ||
1980 | reg_val.Index = 0x09; | ||
1981 | reg_val.Mask = 0x1f; | ||
1982 | viafb_gpio_i2c_write_mask_lvds | ||
1983 | (viaparinfo->lvds_setting_info, | ||
1984 | &viaparinfo-> | ||
1985 | chip_info->lvds_chip_info, | ||
1986 | reg_val); | ||
1987 | break; | ||
1988 | default: | ||
1989 | break; | ||
1990 | } | ||
1991 | } else { | ||
1992 | break; | ||
1993 | } | ||
1994 | } | ||
1995 | break; | ||
1996 | default: | ||
1997 | break; | ||
1998 | } | ||
1999 | switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { | ||
2000 | case VT1636_LVDS: | ||
2001 | for (i = 0; i < 2; i++) { | ||
2002 | value = strsep(&pbuf, " "); | ||
2003 | if (value != NULL) { | ||
2004 | strict_strtoul(value, 0, | ||
2005 | (unsigned long *)®_val.Data); | ||
2006 | switch (i) { | ||
2007 | case 0: | ||
2008 | reg_val.Index = 0x08; | ||
2009 | reg_val.Mask = 0x0f; | ||
2010 | viafb_gpio_i2c_write_mask_lvds | ||
2011 | (viaparinfo->lvds_setting_info2, | ||
2012 | &viaparinfo-> | ||
2013 | chip_info->lvds_chip_info2, | ||
2014 | reg_val); | ||
2015 | break; | ||
2016 | case 1: | ||
2017 | reg_val.Index = 0x09; | ||
2018 | reg_val.Mask = 0x1f; | ||
2019 | viafb_gpio_i2c_write_mask_lvds | ||
2020 | (viaparinfo->lvds_setting_info2, | ||
2021 | &viaparinfo-> | ||
2022 | chip_info->lvds_chip_info2, | ||
2023 | reg_val); | ||
2024 | break; | ||
2025 | default: | ||
2026 | break; | ||
2027 | } | ||
2028 | } else { | ||
2029 | break; | ||
2030 | } | ||
2031 | } | ||
2032 | break; | ||
2033 | default: | ||
2034 | break; | ||
2035 | } | ||
2036 | return count; | ||
2037 | } | ||
2038 | |||
2039 | static void viafb_init_proc(struct proc_dir_entry *viafb_entry) | ||
2040 | { | ||
2041 | struct proc_dir_entry *entry; | ||
2042 | viafb_entry = proc_mkdir("viafb", NULL); | ||
2043 | if (viafb_entry) { | ||
2044 | entry = create_proc_entry("dvp0", 0, viafb_entry); | ||
2045 | if (entry) { | ||
2046 | entry->owner = THIS_MODULE; | ||
2047 | entry->read_proc = viafb_dvp0_proc_read; | ||
2048 | entry->write_proc = viafb_dvp0_proc_write; | ||
2049 | } | ||
2050 | entry = create_proc_entry("dvp1", 0, viafb_entry); | ||
2051 | if (entry) { | ||
2052 | entry->owner = THIS_MODULE; | ||
2053 | entry->read_proc = viafb_dvp1_proc_read; | ||
2054 | entry->write_proc = viafb_dvp1_proc_write; | ||
2055 | } | ||
2056 | entry = create_proc_entry("dfph", 0, viafb_entry); | ||
2057 | if (entry) { | ||
2058 | entry->owner = THIS_MODULE; | ||
2059 | entry->read_proc = viafb_dfph_proc_read; | ||
2060 | entry->write_proc = viafb_dfph_proc_write; | ||
2061 | } | ||
2062 | entry = create_proc_entry("dfpl", 0, viafb_entry); | ||
2063 | if (entry) { | ||
2064 | entry->owner = THIS_MODULE; | ||
2065 | entry->read_proc = viafb_dfpl_proc_read; | ||
2066 | entry->write_proc = viafb_dfpl_proc_write; | ||
2067 | } | ||
2068 | if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. | ||
2069 | lvds_chip_name || VT1636_LVDS == | ||
2070 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { | ||
2071 | entry = create_proc_entry("vt1636", 0, viafb_entry); | ||
2072 | if (entry) { | ||
2073 | entry->owner = THIS_MODULE; | ||
2074 | entry->read_proc = viafb_vt1636_proc_read; | ||
2075 | entry->write_proc = viafb_vt1636_proc_write; | ||
2076 | } | ||
2077 | } | ||
2078 | |||
2079 | } | ||
2080 | } | ||
2081 | static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) | ||
2082 | { | ||
2083 | /* no problem if it was not registered */ | ||
2084 | remove_proc_entry("dvp0", viafb_entry);/* parent dir */ | ||
2085 | remove_proc_entry("dvp1", viafb_entry); | ||
2086 | remove_proc_entry("dfph", viafb_entry); | ||
2087 | remove_proc_entry("dfpl", viafb_entry); | ||
2088 | remove_proc_entry("vt1636", viafb_entry); | ||
2089 | remove_proc_entry("vt1625", viafb_entry); | ||
2090 | } | ||
2091 | |||
2092 | static int __devinit via_pci_probe(void) | ||
2093 | { | ||
2094 | unsigned int default_xres, default_yres; | ||
2095 | char *tmpc, *tmpm; | ||
2096 | char *tmpc_sec, *tmpm_sec; | ||
2097 | int vmode_index; | ||
2098 | u32 tmds_length, lvds_length, crt_length, chip_length, viafb_par_length; | ||
2099 | |||
2100 | DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); | ||
2101 | |||
2102 | viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); | ||
2103 | tmds_length = ALIGN(sizeof(struct tmds_setting_information), | ||
2104 | BITS_PER_LONG/8); | ||
2105 | lvds_length = ALIGN(sizeof(struct lvds_setting_information), | ||
2106 | BITS_PER_LONG/8); | ||
2107 | crt_length = ALIGN(sizeof(struct lvds_setting_information), | ||
2108 | BITS_PER_LONG/8); | ||
2109 | chip_length = ALIGN(sizeof(struct chip_information), BITS_PER_LONG/8); | ||
2110 | |||
2111 | /* Allocate fb_info and ***_par here, also including some other needed | ||
2112 | * variables | ||
2113 | */ | ||
2114 | viafbinfo = framebuffer_alloc(viafb_par_length + 2 * lvds_length + | ||
2115 | tmds_length + crt_length + chip_length, NULL); | ||
2116 | if (!viafbinfo) { | ||
2117 | printk(KERN_ERR"Could not allocate memory for viafb_info.\n"); | ||
2118 | return -ENODEV; | ||
2119 | } | ||
2120 | |||
2121 | viaparinfo = (struct viafb_par *)viafbinfo->par; | ||
2122 | viaparinfo->tmds_setting_info = (struct tmds_setting_information *) | ||
2123 | ((unsigned long)viaparinfo + viafb_par_length); | ||
2124 | viaparinfo->lvds_setting_info = (struct lvds_setting_information *) | ||
2125 | ((unsigned long)viaparinfo->tmds_setting_info + tmds_length); | ||
2126 | viaparinfo->lvds_setting_info2 = (struct lvds_setting_information *) | ||
2127 | ((unsigned long)viaparinfo->lvds_setting_info + lvds_length); | ||
2128 | viaparinfo->crt_setting_info = (struct crt_setting_information *) | ||
2129 | ((unsigned long)viaparinfo->lvds_setting_info2 + lvds_length); | ||
2130 | viaparinfo->chip_info = (struct chip_information *) | ||
2131 | ((unsigned long)viaparinfo->crt_setting_info + crt_length); | ||
2132 | |||
2133 | if (viafb_dual_fb) | ||
2134 | viafb_SAMM_ON = 1; | ||
2135 | parse_active_dev(); | ||
2136 | parse_video_dev(); | ||
2137 | parse_lcd_port(); | ||
2138 | parse_dvi_port(); | ||
2139 | |||
2140 | /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */ | ||
2141 | if (!viafb_SAMM_ON) | ||
2142 | viafb_dual_fb = 0; | ||
2143 | |||
2144 | /* Set up I2C bus stuff */ | ||
2145 | viafb_create_i2c_bus(viaparinfo); | ||
2146 | |||
2147 | viafb_init_chip_info(); | ||
2148 | viafb_get_fb_info(&viaparinfo->fbmem, &viaparinfo->memsize); | ||
2149 | viaparinfo->fbmem_free = viaparinfo->memsize; | ||
2150 | viaparinfo->fbmem_used = 0; | ||
2151 | viaparinfo->fbmem_virt = ioremap_nocache(viaparinfo->fbmem, | ||
2152 | viaparinfo->memsize); | ||
2153 | viafbinfo->screen_base = (char *)viaparinfo->fbmem_virt; | ||
2154 | |||
2155 | if (!viaparinfo->fbmem_virt) { | ||
2156 | printk(KERN_INFO "ioremap failed\n"); | ||
2157 | return -1; | ||
2158 | } | ||
2159 | |||
2160 | viafb_get_mmio_info(&viaparinfo->mmio_base, &viaparinfo->mmio_len); | ||
2161 | viaparinfo->io_virt = ioremap_nocache(viaparinfo->mmio_base, | ||
2162 | viaparinfo->mmio_len); | ||
2163 | |||
2164 | viafbinfo->node = 0; | ||
2165 | viafbinfo->fbops = &viafb_ops; | ||
2166 | viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | ||
2167 | |||
2168 | viafbinfo->pseudo_palette = pseudo_pal; | ||
2169 | if (viafb_accel) { | ||
2170 | viafb_init_accel(); | ||
2171 | viafb_init_2d_engine(); | ||
2172 | viafb_hw_cursor_init(); | ||
2173 | } | ||
2174 | |||
2175 | if (viafb_second_size && (viafb_second_size < 8)) { | ||
2176 | viafb_second_offset = viaparinfo->fbmem_free - | ||
2177 | viafb_second_size * 1024 * 1024; | ||
2178 | } else { | ||
2179 | viafb_second_size = 8; | ||
2180 | viafb_second_offset = viaparinfo->fbmem_free - | ||
2181 | viafb_second_size * 1024 * 1024; | ||
2182 | } | ||
2183 | |||
2184 | viafb_FB_MM = viaparinfo->fbmem_virt; | ||
2185 | tmpm = viafb_mode; | ||
2186 | tmpc = strsep(&tmpm, "x"); | ||
2187 | strict_strtoul(tmpc, 0, (unsigned long *)&default_xres); | ||
2188 | strict_strtoul(tmpm, 0, (unsigned long *)&default_yres); | ||
2189 | |||
2190 | vmode_index = viafb_get_mode_index(default_xres, default_yres, 0); | ||
2191 | DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index); | ||
2192 | |||
2193 | if (viafb_SAMM_ON == 1) { | ||
2194 | if (strcmp(viafb_mode, viafb_mode1)) { | ||
2195 | tmpm_sec = viafb_mode1; | ||
2196 | tmpc_sec = strsep(&tmpm_sec, "x"); | ||
2197 | strict_strtoul(tmpc_sec, 0, | ||
2198 | (unsigned long *)&viafb_second_xres); | ||
2199 | strict_strtoul(tmpm_sec, 0, | ||
2200 | (unsigned long *)&viafb_second_yres); | ||
2201 | } else { | ||
2202 | viafb_second_xres = default_xres; | ||
2203 | viafb_second_yres = default_yres; | ||
2204 | } | ||
2205 | if (0 == viafb_second_virtual_xres) { | ||
2206 | switch (viafb_second_xres) { | ||
2207 | case 1400: | ||
2208 | viafb_second_virtual_xres = 1408; | ||
2209 | break; | ||
2210 | default: | ||
2211 | viafb_second_virtual_xres = viafb_second_xres; | ||
2212 | break; | ||
2213 | } | ||
2214 | } | ||
2215 | if (0 == viafb_second_virtual_yres) | ||
2216 | viafb_second_virtual_yres = viafb_second_yres; | ||
2217 | } | ||
2218 | |||
2219 | switch (viafb_bpp) { | ||
2220 | case 0 ... 8: | ||
2221 | viafb_bpp = 8; | ||
2222 | break; | ||
2223 | case 9 ... 16: | ||
2224 | viafb_bpp = 16; | ||
2225 | break; | ||
2226 | case 17 ... 32: | ||
2227 | viafb_bpp = 32; | ||
2228 | break; | ||
2229 | default: | ||
2230 | viafb_bpp = 8; | ||
2231 | } | ||
2232 | default_var.xres = default_xres; | ||
2233 | default_var.yres = default_yres; | ||
2234 | switch (default_xres) { | ||
2235 | case 1400: | ||
2236 | default_var.xres_virtual = 1408; | ||
2237 | break; | ||
2238 | default: | ||
2239 | default_var.xres_virtual = default_xres; | ||
2240 | break; | ||
2241 | } | ||
2242 | default_var.yres_virtual = default_yres; | ||
2243 | default_var.bits_per_pixel = viafb_bpp; | ||
2244 | if (default_var.bits_per_pixel == 15) | ||
2245 | default_var.bits_per_pixel = 16; | ||
2246 | default_var.pixclock = | ||
2247 | viafb_get_pixclock(default_xres, default_yres, viafb_refresh); | ||
2248 | default_var.left_margin = (default_xres >> 3) & 0xf8; | ||
2249 | default_var.right_margin = 32; | ||
2250 | default_var.upper_margin = 16; | ||
2251 | default_var.lower_margin = 4; | ||
2252 | default_var.hsync_len = default_var.left_margin; | ||
2253 | default_var.vsync_len = 4; | ||
2254 | default_var.accel_flags = 0; | ||
2255 | |||
2256 | if (viafb_accel) { | ||
2257 | viafbinfo->flags |= | ||
2258 | (FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | | ||
2259 | FBINFO_HWACCEL_IMAGEBLIT); | ||
2260 | default_var.accel_flags |= FB_ACCELF_TEXT; | ||
2261 | } else | ||
2262 | viafbinfo->flags |= FBINFO_HWACCEL_DISABLED; | ||
2263 | |||
2264 | if (viafb_dual_fb) { | ||
2265 | viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL); | ||
2266 | if (!viafbinfo1) { | ||
2267 | printk(KERN_ERR | ||
2268 | "allocate the second framebuffer struct error\n"); | ||
2269 | framebuffer_release(viafbinfo); | ||
2270 | return -ENOMEM; | ||
2271 | } | ||
2272 | viaparinfo1 = viafbinfo1->par; | ||
2273 | memcpy(viaparinfo1, viaparinfo, viafb_par_length); | ||
2274 | viaparinfo1->memsize = viaparinfo->memsize - | ||
2275 | viafb_second_offset; | ||
2276 | viaparinfo->memsize = viafb_second_offset; | ||
2277 | viaparinfo1->fbmem_virt = viaparinfo->fbmem_virt + | ||
2278 | viafb_second_offset; | ||
2279 | viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset; | ||
2280 | |||
2281 | viaparinfo1->fbmem_used = viaparinfo->fbmem_used; | ||
2282 | viaparinfo1->fbmem_free = viaparinfo1->memsize - | ||
2283 | viaparinfo1->fbmem_used; | ||
2284 | viaparinfo->fbmem_free = viaparinfo->memsize; | ||
2285 | viaparinfo->fbmem_used = 0; | ||
2286 | if (viafb_accel) { | ||
2287 | viaparinfo1->cursor_start = | ||
2288 | viaparinfo->cursor_start - viafb_second_offset; | ||
2289 | viaparinfo1->VQ_start = viaparinfo->VQ_start - | ||
2290 | viafb_second_offset; | ||
2291 | viaparinfo1->VQ_end = viaparinfo->VQ_end - | ||
2292 | viafb_second_offset; | ||
2293 | } | ||
2294 | |||
2295 | memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info)); | ||
2296 | viafbinfo1->screen_base = viafbinfo->screen_base + | ||
2297 | viafb_second_offset; | ||
2298 | viafbinfo1->fix.smem_start = viaparinfo1->fbmem; | ||
2299 | viafbinfo1->fix.smem_len = viaparinfo1->fbmem_free; | ||
2300 | |||
2301 | default_var.xres = viafb_second_xres; | ||
2302 | default_var.yres = viafb_second_yres; | ||
2303 | default_var.xres_virtual = viafb_second_virtual_xres; | ||
2304 | default_var.yres_virtual = viafb_second_virtual_yres; | ||
2305 | if (viafb_bpp1 != viafb_bpp) | ||
2306 | viafb_bpp1 = viafb_bpp; | ||
2307 | default_var.bits_per_pixel = viafb_bpp1; | ||
2308 | default_var.pixclock = | ||
2309 | viafb_get_pixclock(viafb_second_xres, viafb_second_yres, | ||
2310 | viafb_refresh); | ||
2311 | default_var.left_margin = (viafb_second_xres >> 3) & 0xf8; | ||
2312 | default_var.right_margin = 32; | ||
2313 | default_var.upper_margin = 16; | ||
2314 | default_var.lower_margin = 4; | ||
2315 | default_var.hsync_len = default_var.left_margin; | ||
2316 | default_var.vsync_len = 4; | ||
2317 | |||
2318 | viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); | ||
2319 | viafb_check_var(&default_var, viafbinfo1); | ||
2320 | viafbinfo1->var = default_var; | ||
2321 | viafb_update_viafb_par(viafbinfo); | ||
2322 | viafb_update_fix(&viafbinfo1->fix, viafbinfo1); | ||
2323 | } | ||
2324 | |||
2325 | viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); | ||
2326 | viafb_check_var(&default_var, viafbinfo); | ||
2327 | viafbinfo->var = default_var; | ||
2328 | viafb_update_viafb_par(viafbinfo); | ||
2329 | viafb_update_fix(&viafbinfo->fix, viafbinfo); | ||
2330 | default_var.activate = FB_ACTIVATE_NOW; | ||
2331 | fb_alloc_cmap(&viafbinfo->cmap, 256, 0); | ||
2332 | |||
2333 | if (viafb_dual_fb && (viafb_primary_dev == LCD_Device) | ||
2334 | && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) { | ||
2335 | if (register_framebuffer(viafbinfo1) < 0) | ||
2336 | return -EINVAL; | ||
2337 | } | ||
2338 | if (register_framebuffer(viafbinfo) < 0) | ||
2339 | return -EINVAL; | ||
2340 | |||
2341 | if (viafb_dual_fb && ((viafb_primary_dev != LCD_Device) | ||
2342 | || (viaparinfo->chip_info->gfx_chip_name != | ||
2343 | UNICHROME_CLE266))) { | ||
2344 | if (register_framebuffer(viafbinfo1) < 0) | ||
2345 | return -EINVAL; | ||
2346 | } | ||
2347 | DEBUG_MSG(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n", | ||
2348 | viafbinfo->node, viafbinfo->fix.id, default_var.xres, | ||
2349 | default_var.yres, default_var.bits_per_pixel); | ||
2350 | |||
2351 | viafb_init_proc(viaparinfo->proc_entry); | ||
2352 | viafb_init_dac(IGA2); | ||
2353 | return 0; | ||
2354 | } | ||
2355 | |||
2356 | static void __devexit via_pci_remove(void) | ||
2357 | { | ||
2358 | DEBUG_MSG(KERN_INFO "via_pci_remove!\n"); | ||
2359 | fb_dealloc_cmap(&viafbinfo->cmap); | ||
2360 | unregister_framebuffer(viafbinfo); | ||
2361 | if (viafb_dual_fb) | ||
2362 | unregister_framebuffer(viafbinfo1); | ||
2363 | iounmap((void *)viaparinfo->fbmem_virt); | ||
2364 | iounmap(viaparinfo->io_virt); | ||
2365 | |||
2366 | viafb_delete_i2c_buss(viaparinfo); | ||
2367 | |||
2368 | framebuffer_release(viafbinfo); | ||
2369 | if (viafb_dual_fb) | ||
2370 | framebuffer_release(viafbinfo1); | ||
2371 | |||
2372 | viafb_remove_proc(viaparinfo->proc_entry); | ||
2373 | } | ||
2374 | |||
2375 | #ifndef MODULE | ||
2376 | static int __init viafb_setup(char *options) | ||
2377 | { | ||
2378 | char *this_opt; | ||
2379 | DEBUG_MSG(KERN_INFO "viafb_setup!\n"); | ||
2380 | |||
2381 | if (!options || !*options) | ||
2382 | return 0; | ||
2383 | |||
2384 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
2385 | if (!*this_opt) | ||
2386 | continue; | ||
2387 | |||
2388 | if (!strncmp(this_opt, "viafb_mode1=", 12)) | ||
2389 | viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL); | ||
2390 | else if (!strncmp(this_opt, "viafb_mode=", 11)) | ||
2391 | viafb_mode = kstrdup(this_opt + 11, GFP_KERNEL); | ||
2392 | else if (!strncmp(this_opt, "viafb_bpp1=", 11)) | ||
2393 | strict_strtoul(this_opt + 11, 0, | ||
2394 | (unsigned long *)&viafb_bpp1); | ||
2395 | else if (!strncmp(this_opt, "viafb_bpp=", 10)) | ||
2396 | strict_strtoul(this_opt + 10, 0, | ||
2397 | (unsigned long *)&viafb_bpp); | ||
2398 | else if (!strncmp(this_opt, "viafb_refresh1=", 15)) | ||
2399 | strict_strtoul(this_opt + 15, 0, | ||
2400 | (unsigned long *)&viafb_refresh1); | ||
2401 | else if (!strncmp(this_opt, "viafb_refresh=", 14)) | ||
2402 | strict_strtoul(this_opt + 14, 0, | ||
2403 | (unsigned long *)&viafb_refresh); | ||
2404 | else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21)) | ||
2405 | strict_strtoul(this_opt + 21, 0, | ||
2406 | (unsigned long *)&viafb_lcd_dsp_method); | ||
2407 | else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19)) | ||
2408 | strict_strtoul(this_opt + 19, 0, | ||
2409 | (unsigned long *)&viafb_lcd_panel_id); | ||
2410 | else if (!strncmp(this_opt, "viafb_accel=", 12)) | ||
2411 | strict_strtoul(this_opt + 12, 0, | ||
2412 | (unsigned long *)&viafb_accel); | ||
2413 | else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14)) | ||
2414 | strict_strtoul(this_opt + 14, 0, | ||
2415 | (unsigned long *)&viafb_SAMM_ON); | ||
2416 | else if (!strncmp(this_opt, "viafb_active_dev=", 17)) | ||
2417 | viafb_active_dev = kstrdup(this_opt + 17, GFP_KERNEL); | ||
2418 | else if (!strncmp(this_opt, | ||
2419 | "viafb_display_hardware_layout=", 30)) | ||
2420 | strict_strtoul(this_opt + 30, 0, | ||
2421 | (unsigned long *)&viafb_display_hardware_layout); | ||
2422 | else if (!strncmp(this_opt, "viafb_second_size=", 18)) | ||
2423 | strict_strtoul(this_opt + 18, 0, | ||
2424 | (unsigned long *)&viafb_second_size); | ||
2425 | else if (!strncmp(this_opt, | ||
2426 | "viafb_platform_epia_dvi=", 24)) | ||
2427 | strict_strtoul(this_opt + 24, 0, | ||
2428 | (unsigned long *)&viafb_platform_epia_dvi); | ||
2429 | else if (!strncmp(this_opt, | ||
2430 | "viafb_device_lcd_dualedge=", 26)) | ||
2431 | strict_strtoul(this_opt + 26, 0, | ||
2432 | (unsigned long *)&viafb_device_lcd_dualedge); | ||
2433 | else if (!strncmp(this_opt, "viafb_bus_width=", 16)) | ||
2434 | strict_strtoul(this_opt + 16, 0, | ||
2435 | (unsigned long *)&viafb_bus_width); | ||
2436 | else if (!strncmp(this_opt, "viafb_lcd_mode=", 15)) | ||
2437 | strict_strtoul(this_opt + 15, 0, | ||
2438 | (unsigned long *)&viafb_lcd_mode); | ||
2439 | else if (!strncmp(this_opt, "viafb_video_dev=", 16)) | ||
2440 | viafb_video_dev = kstrdup(this_opt + 16, GFP_KERNEL); | ||
2441 | else if (!strncmp(this_opt, "viafb_lcd_port=", 15)) | ||
2442 | viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL); | ||
2443 | else if (!strncmp(this_opt, "viafb_dvi_port=", 15)) | ||
2444 | viafb_dvi_port = kstrdup(this_opt + 15, GFP_KERNEL); | ||
2445 | } | ||
2446 | return 0; | ||
2447 | } | ||
2448 | #endif | ||
2449 | |||
2450 | static int __init viafb_init(void) | ||
2451 | { | ||
2452 | #ifndef MODULE | ||
2453 | char *option = NULL; | ||
2454 | if (fb_get_options("viafb", &option)) | ||
2455 | return -ENODEV; | ||
2456 | viafb_setup(option); | ||
2457 | #endif | ||
2458 | printk(KERN_INFO | ||
2459 | "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", | ||
2460 | VERSION_MAJOR, VERSION_MINOR); | ||
2461 | return via_pci_probe(); | ||
2462 | } | ||
2463 | |||
2464 | static void __exit viafb_exit(void) | ||
2465 | { | ||
2466 | DEBUG_MSG(KERN_INFO "viafb_exit!\n"); | ||
2467 | via_pci_remove(); | ||
2468 | } | ||
2469 | |||
2470 | static struct fb_ops viafb_ops = { | ||
2471 | .owner = THIS_MODULE, | ||
2472 | .fb_open = viafb_open, | ||
2473 | .fb_release = viafb_release, | ||
2474 | .fb_check_var = viafb_check_var, | ||
2475 | .fb_set_par = viafb_set_par, | ||
2476 | .fb_setcolreg = viafb_setcolreg, | ||
2477 | .fb_pan_display = viafb_pan_display, | ||
2478 | .fb_blank = viafb_blank, | ||
2479 | .fb_fillrect = viafb_fillrect, | ||
2480 | .fb_copyarea = viafb_copyarea, | ||
2481 | .fb_imageblit = viafb_imageblit, | ||
2482 | .fb_cursor = viafb_cursor, | ||
2483 | .fb_ioctl = viafb_ioctl, | ||
2484 | .fb_sync = viafb_sync, | ||
2485 | .fb_setcmap = viafb_setcmap, | ||
2486 | }; | ||
2487 | |||
2488 | module_init(viafb_init); | ||
2489 | module_exit(viafb_exit); | ||
2490 | |||
2491 | #ifdef MODULE | ||
2492 | module_param(viafb_memsize, int, 0); | ||
2493 | |||
2494 | module_param(viafb_mode, charp, 0); | ||
2495 | MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); | ||
2496 | |||
2497 | module_param(viafb_mode1, charp, 0); | ||
2498 | MODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)"); | ||
2499 | |||
2500 | module_param(viafb_bpp, int, 0); | ||
2501 | MODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)"); | ||
2502 | |||
2503 | module_param(viafb_bpp1, int, 0); | ||
2504 | MODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)"); | ||
2505 | |||
2506 | module_param(viafb_refresh, int, 0); | ||
2507 | MODULE_PARM_DESC(viafb_refresh, | ||
2508 | "Set CRT viafb_refresh rate (default = 60)"); | ||
2509 | |||
2510 | module_param(viafb_refresh1, int, 0); | ||
2511 | MODULE_PARM_DESC(viafb_refresh1, | ||
2512 | "Set CRT refresh rate (default = 60)"); | ||
2513 | |||
2514 | module_param(viafb_lcd_panel_id, int, 0); | ||
2515 | MODULE_PARM_DESC(viafb_lcd_panel_id, | ||
2516 | "Set Flat Panel type(Default=1024x768)"); | ||
2517 | |||
2518 | module_param(viafb_lcd_dsp_method, int, 0); | ||
2519 | MODULE_PARM_DESC(viafb_lcd_dsp_method, | ||
2520 | "Set Flat Panel display scaling method.(Default=Expandsion)"); | ||
2521 | |||
2522 | module_param(viafb_SAMM_ON, int, 0); | ||
2523 | MODULE_PARM_DESC(viafb_SAMM_ON, | ||
2524 | "Turn on/off flag of SAMM(Default=OFF)"); | ||
2525 | |||
2526 | module_param(viafb_accel, int, 0); | ||
2527 | MODULE_PARM_DESC(viafb_accel, | ||
2528 | "Set 2D Hardware Acceleration.(Default = OFF)"); | ||
2529 | |||
2530 | module_param(viafb_active_dev, charp, 0); | ||
2531 | MODULE_PARM_DESC(viafb_active_dev, "Specify active devices."); | ||
2532 | |||
2533 | module_param(viafb_display_hardware_layout, int, 0); | ||
2534 | MODULE_PARM_DESC(viafb_display_hardware_layout, | ||
2535 | "Display Hardware Layout (LCD Only, DVI Only...,etc)"); | ||
2536 | |||
2537 | module_param(viafb_second_size, int, 0); | ||
2538 | MODULE_PARM_DESC(viafb_second_size, | ||
2539 | "Set secondary device memory size"); | ||
2540 | |||
2541 | module_param(viafb_dual_fb, int, 0); | ||
2542 | MODULE_PARM_DESC(viafb_dual_fb, | ||
2543 | "Turn on/off flag of dual framebuffer devices.(Default = OFF)"); | ||
2544 | |||
2545 | module_param(viafb_platform_epia_dvi, int, 0); | ||
2546 | MODULE_PARM_DESC(viafb_platform_epia_dvi, | ||
2547 | "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)"); | ||
2548 | |||
2549 | module_param(viafb_device_lcd_dualedge, int, 0); | ||
2550 | MODULE_PARM_DESC(viafb_device_lcd_dualedge, | ||
2551 | "Turn on/off flag of dual edge panel.(Default = OFF)"); | ||
2552 | |||
2553 | module_param(viafb_bus_width, int, 0); | ||
2554 | MODULE_PARM_DESC(viafb_bus_width, | ||
2555 | "Set bus width of panel.(Default = 12)"); | ||
2556 | |||
2557 | module_param(viafb_lcd_mode, int, 0); | ||
2558 | MODULE_PARM_DESC(viafb_lcd_mode, | ||
2559 | "Set Flat Panel mode(Default=OPENLDI)"); | ||
2560 | |||
2561 | module_param(viafb_video_dev, charp, 0); | ||
2562 | MODULE_PARM_DESC(viafb_video_dev, "Specify video devices."); | ||
2563 | |||
2564 | module_param(viafb_lcd_port, charp, 0); | ||
2565 | MODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port."); | ||
2566 | |||
2567 | module_param(viafb_dvi_port, charp, 0); | ||
2568 | MODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port."); | ||
2569 | |||
2570 | MODULE_LICENSE("GPL"); | ||
2571 | #endif | ||
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h new file mode 100644 index 000000000000..a4158e872878 --- /dev/null +++ b/drivers/video/via/viafbdev.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __VIAFBDEV_H__ | ||
23 | #define __VIAFBDEV_H__ | ||
24 | |||
25 | #include <linux/proc_fs.h> | ||
26 | #include <linux/fb.h> | ||
27 | |||
28 | #include "ioctl.h" | ||
29 | #include "share.h" | ||
30 | #include "chip.h" | ||
31 | #include "hw.h" | ||
32 | #include "via_i2c.h" | ||
33 | |||
34 | #define VERSION_MAJOR 2 | ||
35 | #define VERSION_KERNEL 6 /* For kernel 2.6 */ | ||
36 | |||
37 | #define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ | ||
38 | #define VERSION_MINOR 4 | ||
39 | |||
40 | struct viafb_par { | ||
41 | int bpp; | ||
42 | int hres; | ||
43 | int vres; | ||
44 | int linelength; | ||
45 | u32 xoffset; | ||
46 | u32 yoffset; | ||
47 | |||
48 | void __iomem *fbmem_virt; /*framebuffer virtual memory address */ | ||
49 | void __iomem *io_virt; /*iospace virtual memory address */ | ||
50 | unsigned int fbmem; /*framebuffer physical memory address */ | ||
51 | unsigned int memsize; /*size of fbmem */ | ||
52 | unsigned int io; /*io space address */ | ||
53 | unsigned long mmio_base; /*mmio base address */ | ||
54 | unsigned long mmio_len; /*mmio base length */ | ||
55 | u32 fbmem_free; /* Free FB memory */ | ||
56 | u32 fbmem_used; /* Use FB memory size */ | ||
57 | u32 cursor_start; /* Cursor Start Address */ | ||
58 | u32 VQ_start; /* Virtual Queue Start Address */ | ||
59 | u32 VQ_end; /* Virtual Queue End Address */ | ||
60 | u32 iga_path; | ||
61 | struct proc_dir_entry *proc_entry; /*viafb proc entry */ | ||
62 | u8 duoview; /*Is working in duoview mode? */ | ||
63 | |||
64 | /* I2C stuff */ | ||
65 | struct via_i2c_stuff i2c_stuff; | ||
66 | |||
67 | /* All the information will be needed to set engine */ | ||
68 | struct tmds_setting_information *tmds_setting_info; | ||
69 | struct crt_setting_information *crt_setting_info; | ||
70 | struct lvds_setting_information *lvds_setting_info; | ||
71 | struct lvds_setting_information *lvds_setting_info2; | ||
72 | struct chip_information *chip_info; | ||
73 | |||
74 | /* some information related to video playing */ | ||
75 | int video_on_crt; | ||
76 | int video_on_dvi; | ||
77 | int video_on_lcd; | ||
78 | |||
79 | }; | ||
80 | struct viafb_modeinfo { | ||
81 | u32 xres; | ||
82 | u32 yres; | ||
83 | int mode_index; | ||
84 | char *mode_res; | ||
85 | }; | ||
86 | extern unsigned int viafb_second_virtual_yres; | ||
87 | extern unsigned int viafb_second_virtual_xres; | ||
88 | extern unsigned int viafb_second_offset; | ||
89 | extern int viafb_second_size; | ||
90 | extern int viafb_SAMM_ON; | ||
91 | extern int viafb_dual_fb; | ||
92 | extern int viafb_LCD2_ON; | ||
93 | extern int viafb_LCD_ON; | ||
94 | extern int viafb_DVI_ON; | ||
95 | extern int viafb_accel; | ||
96 | extern int viafb_hotplug; | ||
97 | extern int viafb_memsize; | ||
98 | |||
99 | extern int strict_strtoul(const char *cp, unsigned int base, | ||
100 | unsigned long *res); | ||
101 | |||
102 | void viafb_memory_pitch_patch(struct fb_info *info); | ||
103 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | ||
104 | int mode_index); | ||
105 | int viafb_get_mode_index(int hres, int vres, int flag); | ||
106 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | ||
107 | *plvds_setting_info, struct lvds_chip_information | ||
108 | *plvds_chip_info, u8 index); | ||
109 | void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information | ||
110 | *plvds_setting_info, struct lvds_chip_information | ||
111 | *plvds_chip_info, struct IODATA io_data); | ||
112 | #endif /* __VIAFBDEV_H__ */ | ||
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c new file mode 100644 index 000000000000..6dcf583a837d --- /dev/null +++ b/drivers/video/via/viamode.c | |||
@@ -0,0 +1,1086 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | struct res_map_refresh res_map_refresh_tbl[] = { | ||
24 | /*hres, vres, vclock, vmode_refresh*/ | ||
25 | {480, 640, RES_480X640_60HZ_PIXCLOCK, 60}, | ||
26 | {640, 480, RES_640X480_60HZ_PIXCLOCK, 60}, | ||
27 | {640, 480, RES_640X480_75HZ_PIXCLOCK, 75}, | ||
28 | {640, 480, RES_640X480_85HZ_PIXCLOCK, 85}, | ||
29 | {640, 480, RES_640X480_100HZ_PIXCLOCK, 100}, | ||
30 | {640, 480, RES_640X480_120HZ_PIXCLOCK, 120}, | ||
31 | {720, 480, RES_720X480_60HZ_PIXCLOCK, 60}, | ||
32 | {720, 576, RES_720X576_60HZ_PIXCLOCK, 60}, | ||
33 | {800, 480, RES_800X480_60HZ_PIXCLOCK, 60}, | ||
34 | {800, 600, RES_800X600_60HZ_PIXCLOCK, 60}, | ||
35 | {800, 600, RES_800X600_75HZ_PIXCLOCK, 75}, | ||
36 | {800, 600, RES_800X600_85HZ_PIXCLOCK, 85}, | ||
37 | {800, 600, RES_800X600_100HZ_PIXCLOCK, 100}, | ||
38 | {800, 600, RES_800X600_120HZ_PIXCLOCK, 120}, | ||
39 | {848, 480, RES_848X480_60HZ_PIXCLOCK, 60}, | ||
40 | {856, 480, RES_856X480_60HZ_PIXCLOCK, 60}, | ||
41 | {1024, 512, RES_1024X512_60HZ_PIXCLOCK, 60}, | ||
42 | {1024, 600, RES_1024X600_60HZ_PIXCLOCK, 60}, | ||
43 | {1024, 768, RES_1024X768_60HZ_PIXCLOCK, 60}, | ||
44 | {1024, 768, RES_1024X768_75HZ_PIXCLOCK, 75}, | ||
45 | {1024, 768, RES_1024X768_85HZ_PIXCLOCK, 85}, | ||
46 | {1024, 768, RES_1024X768_100HZ_PIXCLOCK, 100}, | ||
47 | /* {1152,864, RES_1152X864_70HZ_PIXCLOCK, 70},*/ | ||
48 | {1152, 864, RES_1152X864_75HZ_PIXCLOCK, 75}, | ||
49 | {1280, 768, RES_1280X768_60HZ_PIXCLOCK, 60}, | ||
50 | {1280, 800, RES_1280X800_60HZ_PIXCLOCK, 60}, | ||
51 | {1280, 960, RES_1280X960_60HZ_PIXCLOCK, 60}, | ||
52 | {1280, 1024, RES_1280X1024_60HZ_PIXCLOCK, 60}, | ||
53 | {1280, 1024, RES_1280X1024_75HZ_PIXCLOCK, 75}, | ||
54 | {1280, 1024, RES_1280X768_85HZ_PIXCLOCK, 85}, | ||
55 | {1440, 1050, RES_1440X1050_60HZ_PIXCLOCK, 60}, | ||
56 | {1600, 1200, RES_1600X1200_60HZ_PIXCLOCK, 60}, | ||
57 | {1600, 1200, RES_1600X1200_75HZ_PIXCLOCK, 75}, | ||
58 | {1280, 720, RES_1280X720_60HZ_PIXCLOCK, 60}, | ||
59 | {1920, 1080, RES_1920X1080_60HZ_PIXCLOCK, 60}, | ||
60 | {1400, 1050, RES_1400X1050_60HZ_PIXCLOCK, 60}, | ||
61 | {1400, 1050, RES_1400X1050_75HZ_PIXCLOCK, 75}, | ||
62 | {1368, 768, RES_1368X768_60HZ_PIXCLOCK, 60}, | ||
63 | {960, 600, RES_960X600_60HZ_PIXCLOCK, 60}, | ||
64 | {1000, 600, RES_1000X600_60HZ_PIXCLOCK, 60}, | ||
65 | {1024, 576, RES_1024X576_60HZ_PIXCLOCK, 60}, | ||
66 | {1088, 612, RES_1088X612_60HZ_PIXCLOCK, 60}, | ||
67 | {1152, 720, RES_1152X720_60HZ_PIXCLOCK, 60}, | ||
68 | {1200, 720, RES_1200X720_60HZ_PIXCLOCK, 60}, | ||
69 | {1280, 600, RES_1280X600_60HZ_PIXCLOCK, 60}, | ||
70 | {1280, 720, RES_1280X720_50HZ_PIXCLOCK, 50}, | ||
71 | {1280, 768, RES_1280X768_50HZ_PIXCLOCK, 50}, | ||
72 | {1360, 768, RES_1360X768_60HZ_PIXCLOCK, 60}, | ||
73 | {1366, 768, RES_1366X768_50HZ_PIXCLOCK, 50}, | ||
74 | {1366, 768, RES_1366X768_60HZ_PIXCLOCK, 60}, | ||
75 | {1440, 900, RES_1440X900_60HZ_PIXCLOCK, 60}, | ||
76 | {1440, 900, RES_1440X900_75HZ_PIXCLOCK, 75}, | ||
77 | {1600, 900, RES_1600X900_60HZ_PIXCLOCK, 60}, | ||
78 | {1600, 1024, RES_1600X1024_60HZ_PIXCLOCK, 60}, | ||
79 | {1680, 1050, RES_1680X1050_60HZ_PIXCLOCK, 60}, | ||
80 | {1680, 1050, RES_1680X1050_75HZ_PIXCLOCK, 75}, | ||
81 | {1792, 1344, RES_1792X1344_60HZ_PIXCLOCK, 60}, | ||
82 | {1856, 1392, RES_1856X1392_60HZ_PIXCLOCK, 60}, | ||
83 | {1920, 1200, RES_1920X1200_60HZ_PIXCLOCK, 60}, | ||
84 | {1920, 1440, RES_1920X1440_60HZ_PIXCLOCK, 60}, | ||
85 | {1920, 1440, RES_1920X1440_75HZ_PIXCLOCK, 75}, | ||
86 | {2048, 1536, RES_2048X1536_60HZ_PIXCLOCK, 60} | ||
87 | }; | ||
88 | |||
89 | struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | ||
90 | {VIASR, SR15, 0x02, 0x02}, | ||
91 | {VIASR, SR16, 0xBF, 0x08}, | ||
92 | {VIASR, SR17, 0xFF, 0x1F}, | ||
93 | {VIASR, SR18, 0xFF, 0x4E}, | ||
94 | {VIASR, SR1A, 0xFB, 0x08}, | ||
95 | {VIASR, SR1E, 0x0F, 0x01}, | ||
96 | {VIASR, SR2A, 0xFF, 0x00}, | ||
97 | {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ | ||
98 | {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ | ||
99 | {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ | ||
100 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ | ||
101 | {VIACR, CR32, 0xFF, 0x00}, | ||
102 | {VIACR, CR33, 0xFF, 0x00}, | ||
103 | {VIACR, CR34, 0xFF, 0x00}, | ||
104 | {VIACR, CR35, 0xFF, 0x00}, | ||
105 | {VIACR, CR36, 0x08, 0x00}, | ||
106 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
107 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
108 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
109 | {VIACR, CR69, 0xFF, 0x00}, | ||
110 | {VIACR, CR6A, 0xFF, 0x40}, | ||
111 | {VIACR, CR6B, 0xFF, 0x00}, | ||
112 | {VIACR, CR6C, 0xFF, 0x00}, | ||
113 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
114 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
115 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
116 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
117 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
118 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
119 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
120 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
121 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
122 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
123 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
124 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
125 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
126 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
127 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | ||
128 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | ||
129 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | ||
130 | {VIACR, CR8B, 0xFF, 0x69}, /* LCD Power Sequence Control 0 */ | ||
131 | {VIACR, CR8C, 0xFF, 0x57}, /* LCD Power Sequence Control 1 */ | ||
132 | {VIACR, CR8D, 0xFF, 0x00}, /* LCD Power Sequence Control 2 */ | ||
133 | {VIACR, CR8E, 0xFF, 0x7B}, /* LCD Power Sequence Control 3 */ | ||
134 | {VIACR, CR8F, 0xFF, 0x03}, /* LCD Power Sequence Control 4 */ | ||
135 | {VIACR, CR90, 0xFF, 0x30}, /* LCD Power Sequence Control 5 */ | ||
136 | {VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */ | ||
137 | {VIACR, CR96, 0xFF, 0x00}, | ||
138 | {VIACR, CR97, 0xFF, 0x00}, | ||
139 | {VIACR, CR99, 0xFF, 0x00}, | ||
140 | {VIACR, CR9B, 0xFF, 0x00} | ||
141 | }; | ||
142 | |||
143 | /* Video Mode Table for VT3314 chipset*/ | ||
144 | /* Common Setting for Video Mode */ | ||
145 | struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | ||
146 | {VIASR, SR15, 0x02, 0x02}, | ||
147 | {VIASR, SR16, 0xBF, 0x08}, | ||
148 | {VIASR, SR17, 0xFF, 0x1F}, | ||
149 | {VIASR, SR18, 0xFF, 0x4E}, | ||
150 | {VIASR, SR1A, 0xFB, 0x82}, | ||
151 | {VIASR, SR1B, 0xFF, 0xF0}, | ||
152 | {VIASR, SR1F, 0xFF, 0x00}, | ||
153 | {VIASR, SR1E, 0xFF, 0x01}, | ||
154 | {VIASR, SR22, 0xFF, 0x1F}, | ||
155 | {VIASR, SR2A, 0x0F, 0x00}, | ||
156 | {VIASR, SR2E, 0xFF, 0xFF}, | ||
157 | {VIASR, SR3F, 0xFF, 0xFF}, | ||
158 | {VIASR, SR40, 0xF7, 0x00}, | ||
159 | {VIASR, CR30, 0xFF, 0x04}, | ||
160 | {VIACR, CR32, 0xFF, 0x00}, | ||
161 | {VIACR, CR33, 0x7F, 0x00}, | ||
162 | {VIACR, CR34, 0xFF, 0x00}, | ||
163 | {VIACR, CR35, 0xFF, 0x00}, | ||
164 | {VIACR, CR36, 0xFF, 0x31}, | ||
165 | {VIACR, CR41, 0xFF, 0x80}, | ||
166 | {VIACR, CR42, 0xFF, 0x00}, | ||
167 | {VIACR, CR55, 0x80, 0x00}, | ||
168 | {VIACR, CR5D, 0x80, 0x00}, /*Horizontal Retrace Start bit[11] should be 0*/ | ||
169 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
170 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
171 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
172 | {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ | ||
173 | {VIACR, CR69, 0xFF, 0x00}, | ||
174 | {VIACR, CR6A, 0xFD, 0x40}, | ||
175 | {VIACR, CR6B, 0xFF, 0x00}, | ||
176 | {VIACR, CR6C, 0xFF, 0x00}, | ||
177 | {VIACR, CR77, 0xFF, 0x00}, /* LCD scaling Factor */ | ||
178 | {VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */ | ||
179 | {VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */ | ||
180 | {VIACR, CR9F, 0x03, 0x00}, /* LCD scaling Factor */ | ||
181 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
182 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
183 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
184 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
185 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
186 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
187 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
188 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
189 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
190 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
191 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
192 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
193 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
194 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
195 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | ||
196 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | ||
197 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | ||
198 | {VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */ | ||
199 | {VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */ | ||
200 | {VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */ | ||
201 | {VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */ | ||
202 | {VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */ | ||
203 | {VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */ | ||
204 | {VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */ | ||
205 | {VIACR, CR96, 0xFF, 0x00}, | ||
206 | {VIACR, CR97, 0xFF, 0x00}, | ||
207 | {VIACR, CR99, 0xFF, 0x00}, | ||
208 | {VIACR, CR9B, 0xFF, 0x00}, | ||
209 | {VIACR, CR9D, 0xFF, 0x80}, | ||
210 | {VIACR, CR9E, 0xFF, 0x80} | ||
211 | }; | ||
212 | |||
213 | struct io_reg KM400_ModeXregs[] = { | ||
214 | {VIASR, SR10, 0xFF, 0x01}, /* Unlock Register */ | ||
215 | {VIASR, SR16, 0xFF, 0x08}, /* Display FIFO threshold Control */ | ||
216 | {VIASR, SR17, 0xFF, 0x1F}, /* Display FIFO Control */ | ||
217 | {VIASR, SR18, 0xFF, 0x4E}, /* GFX PREQ threshold */ | ||
218 | {VIASR, SR1A, 0xFF, 0x0a}, /* GFX PREQ threshold */ | ||
219 | {VIASR, SR1F, 0xFF, 0x00}, /* Memory Control 0 */ | ||
220 | {VIASR, SR1B, 0xFF, 0xF0}, /* Power Management Control 0 */ | ||
221 | {VIASR, SR1E, 0xFF, 0x01}, /* Power Management Control */ | ||
222 | {VIASR, SR20, 0xFF, 0x00}, /* Sequencer Arbiter Control 0 */ | ||
223 | {VIASR, SR21, 0xFF, 0x00}, /* Sequencer Arbiter Control 1 */ | ||
224 | {VIASR, SR22, 0xFF, 0x1F}, /* Display Arbiter Control 1 */ | ||
225 | {VIASR, SR2A, 0xFF, 0x00}, /* Power Management Control 5 */ | ||
226 | {VIASR, SR2D, 0xFF, 0xFF}, /* Power Management Control 1 */ | ||
227 | {VIASR, SR2E, 0xFF, 0xFF}, /* Power Management Control 2 */ | ||
228 | {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ | ||
229 | {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ | ||
230 | {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ | ||
231 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ | ||
232 | {VIACR, CR33, 0xFF, 0x00}, | ||
233 | {VIACR, CR55, 0x80, 0x00}, | ||
234 | {VIACR, CR5D, 0x80, 0x00}, | ||
235 | {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */ | ||
236 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
237 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
238 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
239 | {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */ | ||
240 | {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */ | ||
241 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
242 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
243 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
244 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
245 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
246 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
247 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
248 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
249 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
250 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
251 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
252 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
253 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
254 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
255 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | ||
256 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | ||
257 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | ||
258 | {VIACR, CR8B, 0xFF, 0x2D}, /* LCD Power Sequence Control 0 */ | ||
259 | {VIACR, CR8C, 0xFF, 0x2D}, /* LCD Power Sequence Control 1 */ | ||
260 | {VIACR, CR8D, 0xFF, 0xC8}, /* LCD Power Sequence Control 2 */ | ||
261 | {VIACR, CR8E, 0xFF, 0x36}, /* LCD Power Sequence Control 3 */ | ||
262 | {VIACR, CR8F, 0xFF, 0x00}, /* LCD Power Sequence Control 4 */ | ||
263 | {VIACR, CR90, 0xFF, 0x10}, /* LCD Power Sequence Control 5 */ | ||
264 | {VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */ | ||
265 | {VIACR, CR96, 0xFF, 0x03}, /* DVP0 ; DVP0 Clock Skew */ | ||
266 | {VIACR, CR97, 0xFF, 0x03}, /* DFP high ; DFPH Clock Skew */ | ||
267 | {VIACR, CR99, 0xFF, 0x03}, /* DFP low ; DFPL Clock Skew*/ | ||
268 | {VIACR, CR9B, 0xFF, 0x07} /* DVI on DVP1 ; DVP1 Clock Skew*/ | ||
269 | }; | ||
270 | |||
271 | /* For VT3324: Common Setting for Video Mode */ | ||
272 | struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | ||
273 | {VIASR, SR15, 0x02, 0x02}, | ||
274 | {VIASR, SR16, 0xBF, 0x08}, | ||
275 | {VIASR, SR17, 0xFF, 0x1F}, | ||
276 | {VIASR, SR18, 0xFF, 0x4E}, | ||
277 | {VIASR, SR1A, 0xFB, 0x08}, | ||
278 | {VIASR, SR1B, 0xFF, 0xF0}, | ||
279 | {VIASR, SR1E, 0xFF, 0x01}, | ||
280 | {VIASR, SR2A, 0xFF, 0x00}, | ||
281 | {VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ | ||
282 | {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ | ||
283 | {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ | ||
284 | {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ | ||
285 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ | ||
286 | {VIACR, CR32, 0xFF, 0x00}, | ||
287 | {VIACR, CR33, 0xFF, 0x00}, | ||
288 | {VIACR, CR34, 0xFF, 0x00}, | ||
289 | {VIACR, CR35, 0xFF, 0x00}, | ||
290 | {VIACR, CR36, 0x08, 0x00}, | ||
291 | {VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */ | ||
292 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
293 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
294 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
295 | {VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
296 | {VIACR, CR69, 0xFF, 0x00}, | ||
297 | {VIACR, CR6A, 0xFF, 0x40}, | ||
298 | {VIACR, CR6B, 0xFF, 0x00}, | ||
299 | {VIACR, CR6C, 0xFF, 0x00}, | ||
300 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
301 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
302 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
303 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
304 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
305 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
306 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
307 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
308 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
309 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
310 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
311 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
312 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
313 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
314 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | ||
315 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | ||
316 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | ||
317 | {VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */ | ||
318 | {VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */ | ||
319 | {VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */ | ||
320 | {VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */ | ||
321 | {VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */ | ||
322 | {VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */ | ||
323 | {VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */ | ||
324 | {VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */ | ||
325 | {VIACR, CR96, 0xFF, 0x00}, | ||
326 | {VIACR, CR97, 0xFF, 0x00}, | ||
327 | {VIACR, CR99, 0xFF, 0x00}, | ||
328 | {VIACR, CR9B, 0xFF, 0x00}, | ||
329 | {VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */ | ||
330 | }; | ||
331 | |||
332 | /* For VT3353: Common Setting for Video Mode */ | ||
333 | struct io_reg VX800_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, | ||
334 | {VIASR, SR15, 0x02, 0x02}, | ||
335 | {VIASR, SR16, 0xBF, 0x08}, | ||
336 | {VIASR, SR17, 0xFF, 0x1F}, | ||
337 | {VIASR, SR18, 0xFF, 0x4E}, | ||
338 | {VIASR, SR1A, 0xFB, 0x08}, | ||
339 | {VIASR, SR1B, 0xFF, 0xF0}, | ||
340 | {VIASR, SR1E, 0xFF, 0x01}, | ||
341 | {VIASR, SR2A, 0xFF, 0x00}, | ||
342 | {VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ | ||
343 | {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ | ||
344 | {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ | ||
345 | {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ | ||
346 | {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ | ||
347 | {VIACR, CR32, 0xFF, 0x00}, | ||
348 | {VIACR, CR33, 0xFF, 0x00}, | ||
349 | {VIACR, CR34, 0xFF, 0x00}, | ||
350 | {VIACR, CR35, 0xFF, 0x00}, | ||
351 | {VIACR, CR36, 0x08, 0x00}, | ||
352 | {VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */ | ||
353 | {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
354 | {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
355 | {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
356 | {VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */ | ||
357 | {VIACR, CR69, 0xFF, 0x00}, | ||
358 | {VIACR, CR6A, 0xFF, 0x40}, | ||
359 | {VIACR, CR6B, 0xFF, 0x00}, | ||
360 | {VIACR, CR6C, 0xFF, 0x00}, | ||
361 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ | ||
362 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ | ||
363 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ | ||
364 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ | ||
365 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ | ||
366 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ | ||
367 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ | ||
368 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ | ||
369 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ | ||
370 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ | ||
371 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ | ||
372 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ | ||
373 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ | ||
374 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ | ||
375 | {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ | ||
376 | {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ | ||
377 | {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ | ||
378 | {VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */ | ||
379 | {VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */ | ||
380 | {VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */ | ||
381 | {VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */ | ||
382 | {VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */ | ||
383 | {VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */ | ||
384 | {VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */ | ||
385 | {VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */ | ||
386 | {VIACR, CR96, 0xFF, 0x00}, | ||
387 | {VIACR, CR97, 0xFF, 0x00}, | ||
388 | {VIACR, CR99, 0xFF, 0x00}, | ||
389 | {VIACR, CR9B, 0xFF, 0x00}, | ||
390 | {VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */ | ||
391 | }; | ||
392 | |||
393 | /* Video Mode Table */ | ||
394 | /* Common Setting for Video Mode */ | ||
395 | struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00}, | ||
396 | {VIASR, SR2A, 0x0F, 0x00}, | ||
397 | {VIASR, SR15, 0x02, 0x02}, | ||
398 | {VIASR, SR16, 0xBF, 0x08}, | ||
399 | {VIASR, SR17, 0xFF, 0x1F}, | ||
400 | {VIASR, SR18, 0xFF, 0x4E}, | ||
401 | {VIASR, SR1A, 0xFB, 0x08}, | ||
402 | |||
403 | {VIACR, CR32, 0xFF, 0x00}, | ||
404 | {VIACR, CR34, 0xFF, 0x00}, | ||
405 | {VIACR, CR35, 0xFF, 0x00}, | ||
406 | {VIACR, CR36, 0x08, 0x00}, | ||
407 | {VIACR, CR6A, 0xFF, 0x80}, | ||
408 | {VIACR, CR6A, 0xFF, 0xC0}, | ||
409 | |||
410 | {VIACR, CR55, 0x80, 0x00}, | ||
411 | {VIACR, CR5D, 0x80, 0x00}, | ||
412 | |||
413 | {VIAGR, GR20, 0xFF, 0x00}, | ||
414 | {VIAGR, GR21, 0xFF, 0x00}, | ||
415 | {VIAGR, GR22, 0xFF, 0x00}, | ||
416 | /* LCD Parameters */ | ||
417 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Parameter 1 */ | ||
418 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Parameter 2 */ | ||
419 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Parameter 3 */ | ||
420 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Parameter 4 */ | ||
421 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Parameter 5 */ | ||
422 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Parameter 6 */ | ||
423 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Parameter 7 */ | ||
424 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Parameter 8 */ | ||
425 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Parameter 9 */ | ||
426 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Parameter 10 */ | ||
427 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Parameter 11 */ | ||
428 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Parameter 12 */ | ||
429 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Parameter 13 */ | ||
430 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Parameter 14 */ | ||
431 | |||
432 | }; | ||
433 | |||
434 | /* Mode:1024X768 */ | ||
435 | struct io_reg PM1024x768[] = { {VIASR, 0x16, 0xBF, 0x0C}, | ||
436 | {VIASR, 0x18, 0xFF, 0x4C} | ||
437 | }; | ||
438 | |||
439 | struct patch_table res_patch_table[] = { | ||
440 | {VIA_RES_1024X768, ARRAY_SIZE(PM1024x768), PM1024x768} | ||
441 | }; | ||
442 | |||
443 | /* struct VPITTable { | ||
444 | unsigned char Misc; | ||
445 | unsigned char SR[StdSR]; | ||
446 | unsigned char CR[StdCR]; | ||
447 | unsigned char GR[StdGR]; | ||
448 | unsigned char AR[StdAR]; | ||
449 | };*/ | ||
450 | |||
451 | struct VPITTable VPIT = { | ||
452 | /* Msic */ | ||
453 | 0xC7, | ||
454 | /* Sequencer */ | ||
455 | {0x01, 0x0F, 0x00, 0x0E}, | ||
456 | /* Graphic Controller */ | ||
457 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF}, | ||
458 | /* Attribute Controller */ | ||
459 | {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
460 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
461 | 0x01, 0x00, 0x0F, 0x00} | ||
462 | }; | ||
463 | |||
464 | /********************/ | ||
465 | /* Mode Table */ | ||
466 | /********************/ | ||
467 | |||
468 | /* 480x640 */ | ||
469 | struct crt_mode_table CRTM480x640[] = { | ||
470 | /* r_rate, vclk, hsp, vsp */ | ||
471 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
472 | {REFRESH_60, CLK_25_175M, M480X640_R60_HSP, M480X640_R60_VSP, | ||
473 | {624, 480, 480, 144, 504, 48, 663, 640, 640, 23, 641, 3} } /* GTF*/ | ||
474 | }; | ||
475 | |||
476 | /* 640x480*/ | ||
477 | struct crt_mode_table CRTM640x480[] = { | ||
478 | /*r_rate,vclk,hsp,vsp */ | ||
479 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
480 | {REFRESH_60, CLK_25_175M, M640X480_R60_HSP, M640X480_R60_VSP, | ||
481 | {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} }, | ||
482 | {REFRESH_75, CLK_31_500M, M640X480_R75_HSP, M640X480_R75_VSP, | ||
483 | {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} }, | ||
484 | {REFRESH_85, CLK_36_000M, M640X480_R85_HSP, M640X480_R85_VSP, | ||
485 | {832, 640, 640, 192, 696, 56, 509, 480, 480, 29, 481, 3} }, | ||
486 | {REFRESH_100, CLK_43_163M, M640X480_R100_HSP, M640X480_R100_VSP, | ||
487 | {848, 640, 640, 208, 680, 64, 509, 480, 480, 29, 481, 3} }, /*GTF*/ | ||
488 | {REFRESH_120, CLK_52_406M, M640X480_R120_HSP, | ||
489 | M640X480_R120_VSP, | ||
490 | {848, 640, 640, 208, 680, 64, 515, 480, 480, 35, 481, | ||
491 | 3} } /*GTF*/ | ||
492 | }; | ||
493 | |||
494 | /*720x480 (GTF)*/ | ||
495 | struct crt_mode_table CRTM720x480[] = { | ||
496 | /*r_rate,vclk,hsp,vsp */ | ||
497 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
498 | {REFRESH_60, CLK_26_880M, M720X480_R60_HSP, M720X480_R60_VSP, | ||
499 | {896, 720, 720, 176, 736, 72, 497, 480, 480, 17, 481, 3} } | ||
500 | |||
501 | }; | ||
502 | |||
503 | /*720x576 (GTF)*/ | ||
504 | struct crt_mode_table CRTM720x576[] = { | ||
505 | /*r_rate,vclk,hsp,vsp */ | ||
506 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
507 | {REFRESH_60, CLK_32_668M, M720X576_R60_HSP, M720X576_R60_VSP, | ||
508 | {912, 720, 720, 192, 744, 72, 597, 576, 576, 21, 577, 3} } | ||
509 | }; | ||
510 | |||
511 | /* 800x480 (CVT) */ | ||
512 | struct crt_mode_table CRTM800x480[] = { | ||
513 | /* r_rate, vclk, hsp, vsp */ | ||
514 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
515 | {REFRESH_60, CLK_29_581M, M800X480_R60_HSP, M800X480_R60_VSP, | ||
516 | {992, 800, 800, 192, 824, 72, 500, 480, 480, 20, 483, 7} } | ||
517 | }; | ||
518 | |||
519 | /* 800x600*/ | ||
520 | struct crt_mode_table CRTM800x600[] = { | ||
521 | /*r_rate,vclk,hsp,vsp */ | ||
522 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
523 | {REFRESH_60, CLK_40_000M, M800X600_R60_HSP, M800X600_R60_VSP, | ||
524 | {1056, 800, 800, 256, 840, 128, 628, 600, 600, 28, 601, 4} }, | ||
525 | {REFRESH_75, CLK_49_500M, M800X600_R75_HSP, M800X600_R75_VSP, | ||
526 | {1056, 800, 800, 256, 816, 80, 625, 600, 600, 25, 601, 3} }, | ||
527 | {REFRESH_85, CLK_56_250M, M800X600_R85_HSP, M800X600_R85_VSP, | ||
528 | {1048, 800, 800, 248, 832, 64, 631, 600, 600, 31, 601, 3} }, | ||
529 | {REFRESH_100, CLK_68_179M, M800X600_R100_HSP, M800X600_R100_VSP, | ||
530 | {1072, 800, 800, 272, 848, 88, 636, 600, 600, 36, 601, 3} }, | ||
531 | {REFRESH_120, CLK_83_950M, M800X600_R120_HSP, | ||
532 | M800X600_R120_VSP, | ||
533 | {1088, 800, 800, 288, 856, 88, 643, 600, 600, 43, 601, | ||
534 | 3} } | ||
535 | }; | ||
536 | |||
537 | /* 848x480 (CVT) */ | ||
538 | struct crt_mode_table CRTM848x480[] = { | ||
539 | /* r_rate, vclk, hsp, vsp */ | ||
540 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
541 | {REFRESH_60, CLK_31_500M, M848X480_R60_HSP, M848X480_R60_VSP, | ||
542 | {1056, 848, 848, 208, 872, 80, 500, 480, 480, 20, 483, 5} } | ||
543 | }; | ||
544 | |||
545 | /*856x480 (GTF) convert to 852x480*/ | ||
546 | struct crt_mode_table CRTM852x480[] = { | ||
547 | /*r_rate,vclk,hsp,vsp */ | ||
548 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
549 | {REFRESH_60, CLK_31_728M, M852X480_R60_HSP, M852X480_R60_VSP, | ||
550 | {1064, 856, 856, 208, 872, 88, 497, 480, 480, 17, 481, 3} } | ||
551 | }; | ||
552 | |||
553 | /*1024x512 (GTF)*/ | ||
554 | struct crt_mode_table CRTM1024x512[] = { | ||
555 | /*r_rate,vclk,hsp,vsp */ | ||
556 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
557 | {REFRESH_60, CLK_41_291M, M1024X512_R60_HSP, M1024X512_R60_VSP, | ||
558 | {1296, 1024, 1024, 272, 1056, 104, 531, 512, 512, 19, 513, 3} } | ||
559 | |||
560 | }; | ||
561 | |||
562 | /* 1024x600*/ | ||
563 | struct crt_mode_table CRTM1024x600[] = { | ||
564 | /*r_rate,vclk,hsp,vsp */ | ||
565 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
566 | {REFRESH_60, CLK_48_875M, M1024X600_R60_HSP, M1024X600_R60_VSP, | ||
567 | {1312, 1024, 1024, 288, 1064, 104, 622, 600, 600, 22, 601, 3} }, | ||
568 | }; | ||
569 | |||
570 | /* 1024x768*/ | ||
571 | struct crt_mode_table CRTM1024x768[] = { | ||
572 | /*r_rate,vclk,hsp,vsp */ | ||
573 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
574 | {REFRESH_60, CLK_65_000M, M1024X768_R60_HSP, M1024X768_R60_VSP, | ||
575 | {1344, 1024, 1024, 320, 1048, 136, 806, 768, 768, 38, 771, 6} }, | ||
576 | {REFRESH_75, CLK_78_750M, M1024X768_R75_HSP, M1024X768_R75_VSP, | ||
577 | {1312, 1024, 1024, 288, 1040, 96, 800, 768, 768, 32, 769, 3} }, | ||
578 | {REFRESH_85, CLK_94_500M, M1024X768_R85_HSP, M1024X768_R85_VSP, | ||
579 | {1376, 1024, 1024, 352, 1072, 96, 808, 768, 768, 40, 769, 3} }, | ||
580 | {REFRESH_100, CLK_113_309M, M1024X768_R100_HSP, M1024X768_R100_VSP, | ||
581 | {1392, 1024, 1024, 368, 1096, 112, 814, 768, 768, 46, 769, 3} } | ||
582 | }; | ||
583 | |||
584 | /* 1152x864*/ | ||
585 | struct crt_mode_table CRTM1152x864[] = { | ||
586 | /*r_rate,vclk,hsp,vsp */ | ||
587 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
588 | {REFRESH_75, CLK_108_000M, M1152X864_R75_HSP, M1152X864_R75_VSP, | ||
589 | {1600, 1152, 1152, 448, 1216, 128, 900, 864, 864, 36, 865, 3} } | ||
590 | |||
591 | }; | ||
592 | |||
593 | /* 1280x720 (HDMI 720P)*/ | ||
594 | struct crt_mode_table CRTM1280x720[] = { | ||
595 | /*r_rate,vclk,hsp,vsp */ | ||
596 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
597 | {REFRESH_60, CLK_74_481M, M1280X720_R60_HSP, M1280X720_R60_VSP, | ||
598 | {1648, 1280, 1280, 368, 1392, 40, 750, 720, 720, 30, 725, 5} }, | ||
599 | {REFRESH_50, CLK_60_466M, M1280X720_R50_HSP, M1280X720_R50_VSP, | ||
600 | {1632, 1280, 1280, 352, 1328, 128, 741, 720, 720, 21, 721, 3} } | ||
601 | }; | ||
602 | |||
603 | /*1280x768 (GTF)*/ | ||
604 | struct crt_mode_table CRTM1280x768[] = { | ||
605 | /*r_rate,vclk,hsp,vsp */ | ||
606 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
607 | {REFRESH_60, CLK_80_136M, M1280X768_R60_HSP, M1280X768_R60_VSP, | ||
608 | {1680, 1280, 1280, 400, 1344, 136, 795, 768, 768, 27, 769, 3} }, | ||
609 | {REFRESH_50, CLK_65_178M, M1280X768_R50_HSP, M1280X768_R50_VSP, | ||
610 | {1648, 1280, 1280, 368, 1336, 128, 791, 768, 768, 23, 769, 3} } | ||
611 | }; | ||
612 | |||
613 | /* 1280x800 (CVT) */ | ||
614 | struct crt_mode_table CRTM1280x800[] = { | ||
615 | /* r_rate, vclk, hsp, vsp */ | ||
616 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
617 | {REFRESH_60, CLK_83_375M, M1280X800_R60_HSP, M1280X800_R60_VSP, | ||
618 | {1680, 1280, 1280, 400, 1352, 128, 831, 800, 800, 31, 803, 6} } | ||
619 | }; | ||
620 | |||
621 | /*1280x960*/ | ||
622 | struct crt_mode_table CRTM1280x960[] = { | ||
623 | /*r_rate,vclk,hsp,vsp */ | ||
624 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
625 | {REFRESH_60, CLK_108_000M, M1280X960_R60_HSP, M1280X960_R60_VSP, | ||
626 | {1800, 1280, 1280, 520, 1376, 112, 1000, 960, 960, 40, 961, 3} } | ||
627 | }; | ||
628 | |||
629 | /* 1280x1024*/ | ||
630 | struct crt_mode_table CRTM1280x1024[] = { | ||
631 | /*r_rate,vclk,,hsp,vsp */ | ||
632 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
633 | {REFRESH_60, CLK_108_000M, M1280X1024_R60_HSP, M1280X1024_R60_VSP, | ||
634 | {1688, 1280, 1280, 408, 1328, 112, 1066, 1024, 1024, 42, 1025, | ||
635 | 3} }, | ||
636 | {REFRESH_75, CLK_135_000M, M1280X1024_R75_HSP, M1280X1024_R75_VSP, | ||
637 | {1688, 1280, 1280, 408, 1296, 144, 1066, 1024, 1024, 42, 1025, | ||
638 | 3} }, | ||
639 | {REFRESH_85, CLK_157_500M, M1280X1024_R85_HSP, M1280X1024_R85_VSP, | ||
640 | {1728, 1280, 1280, 448, 1344, 160, 1072, 1024, 1024, 48, 1025, 3} } | ||
641 | }; | ||
642 | |||
643 | /* 1368x768 (GTF) */ | ||
644 | struct crt_mode_table CRTM1368x768[] = { | ||
645 | /* r_rate, vclk, hsp, vsp */ | ||
646 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
647 | {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP, | ||
648 | {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} } | ||
649 | }; | ||
650 | |||
651 | /*1440x1050 (GTF)*/ | ||
652 | struct crt_mode_table CRTM1440x1050[] = { | ||
653 | /*r_rate,vclk,hsp,vsp */ | ||
654 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
655 | {REFRESH_60, CLK_125_104M, M1440X1050_R60_HSP, M1440X1050_R60_VSP, | ||
656 | {1936, 1440, 1440, 496, 1536, 152, 1077, 1040, 1040, 37, 1041, 3} } | ||
657 | }; | ||
658 | |||
659 | /* 1600x1200*/ | ||
660 | struct crt_mode_table CRTM1600x1200[] = { | ||
661 | /*r_rate,vclk,hsp,vsp */ | ||
662 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
663 | {REFRESH_60, CLK_162_000M, M1600X1200_R60_HSP, M1600X1200_R60_VSP, | ||
664 | {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, | ||
665 | 3} }, | ||
666 | {REFRESH_75, CLK_202_500M, M1600X1200_R75_HSP, M1600X1200_R75_VSP, | ||
667 | {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 3} } | ||
668 | |||
669 | }; | ||
670 | |||
671 | /* 1680x1050 (CVT) */ | ||
672 | struct crt_mode_table CRTM1680x1050[] = { | ||
673 | /* r_rate, vclk, hsp, vsp */ | ||
674 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
675 | {REFRESH_60, CLK_146_760M, M1680x1050_R60_HSP, M1680x1050_R60_VSP, | ||
676 | {2240, 1680, 1680, 560, 1784, 176, 1089, 1050, 1050, 39, 1053, | ||
677 | 6} }, | ||
678 | {REFRESH_75, CLK_187_000M, M1680x1050_R75_HSP, M1680x1050_R75_VSP, | ||
679 | {2272, 1680, 1680, 592, 1800, 176, 1099, 1050, 1050, 49, 1053, 6} } | ||
680 | }; | ||
681 | |||
682 | /* 1680x1050 (CVT Reduce Blanking) */ | ||
683 | struct crt_mode_table CRTM1680x1050_RB[] = { | ||
684 | /* r_rate, vclk, hsp, vsp */ | ||
685 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
686 | {REFRESH_60, CLK_119_000M, M1680x1050_RB_R60_HSP, | ||
687 | M1680x1050_RB_R60_VSP, | ||
688 | {1840, 1680, 1680, 160, 1728, 32, 1080, 1050, 1050, 30, 1053, 6} } | ||
689 | }; | ||
690 | |||
691 | /* 1920x1080 (CVT)*/ | ||
692 | struct crt_mode_table CRTM1920x1080[] = { | ||
693 | /*r_rate,vclk,hsp,vsp */ | ||
694 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
695 | {REFRESH_60, CLK_172_798M, M1920X1080_R60_HSP, M1920X1080_R60_VSP, | ||
696 | {2576, 1920, 1920, 656, 2048, 200, 1120, 1080, 1080, 40, 1083, 5} } | ||
697 | }; | ||
698 | |||
699 | /* 1920x1080 (CVT with Reduce Blanking) */ | ||
700 | struct crt_mode_table CRTM1920x1080_RB[] = { | ||
701 | /* r_rate, vclk, hsp, vsp */ | ||
702 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
703 | {REFRESH_60, CLK_138_400M, M1920X1080_RB_R60_HSP, | ||
704 | M1920X1080_RB_R60_VSP, | ||
705 | {2080, 1920, 1920, 160, 1968, 32, 1111, 1080, 1080, 31, 1083, 5} } | ||
706 | }; | ||
707 | |||
708 | /* 1920x1440*/ | ||
709 | struct crt_mode_table CRTM1920x1440[] = { | ||
710 | /*r_rate,vclk,hsp,vsp */ | ||
711 | /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
712 | {REFRESH_60, CLK_234_000M, M1920X1440_R60_HSP, M1920X1440_R60_VSP, | ||
713 | {2600, 1920, 1920, 680, 2048, 208, 1500, 1440, 1440, 60, 1441, | ||
714 | 3} }, | ||
715 | {REFRESH_75, CLK_297_500M, M1920X1440_R75_HSP, M1920X1440_R75_VSP, | ||
716 | {2640, 1920, 1920, 720, 2064, 224, 1500, 1440, 1440, 60, 1441, 3} } | ||
717 | }; | ||
718 | |||
719 | /* 1400x1050 (CVT) */ | ||
720 | struct crt_mode_table CRTM1400x1050[] = { | ||
721 | /* r_rate, vclk, hsp, vsp */ | ||
722 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
723 | {REFRESH_60, CLK_121_750M, M1400X1050_R60_HSP, M1400X1050_R60_VSP, | ||
724 | {1864, 1400, 1400, 464, 1488, 144, 1089, 1050, 1050, 39, 1053, | ||
725 | 4} }, | ||
726 | {REFRESH_75, CLK_156_000M, M1400X1050_R75_HSP, M1400X1050_R75_VSP, | ||
727 | {1896, 1400, 1400, 496, 1504, 144, 1099, 1050, 1050, 49, 1053, 4} } | ||
728 | }; | ||
729 | |||
730 | /* 1400x1050 (CVT Reduce Blanking) */ | ||
731 | struct crt_mode_table CRTM1400x1050_RB[] = { | ||
732 | /* r_rate, vclk, hsp, vsp */ | ||
733 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
734 | {REFRESH_60, CLK_101_000M, M1400X1050_RB_R60_HSP, | ||
735 | M1400X1050_RB_R60_VSP, | ||
736 | {1560, 1400, 1400, 160, 1448, 32, 1080, 1050, 1050, 30, 1053, 4} } | ||
737 | }; | ||
738 | |||
739 | /* 960x600 (CVT) */ | ||
740 | struct crt_mode_table CRTM960x600[] = { | ||
741 | /* r_rate, vclk, hsp, vsp */ | ||
742 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
743 | {REFRESH_60, CLK_45_250M, M960X600_R60_HSP, M960X600_R60_VSP, | ||
744 | {1216, 960, 960, 256, 992, 96, 624, 600, 600, 24, 603, 6} } | ||
745 | }; | ||
746 | |||
747 | /* 1000x600 (GTF) */ | ||
748 | struct crt_mode_table CRTM1000x600[] = { | ||
749 | /* r_rate, vclk, hsp, vsp */ | ||
750 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
751 | {REFRESH_60, CLK_48_000M, M1000X600_R60_HSP, M1000X600_R60_VSP, | ||
752 | {1288, 1000, 1000, 288, 1040, 104, 622, 600, 600, 22, 601, 3} } | ||
753 | }; | ||
754 | |||
755 | /* 1024x576 (GTF) */ | ||
756 | struct crt_mode_table CRTM1024x576[] = { | ||
757 | /* r_rate, vclk, hsp, vsp */ | ||
758 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
759 | {REFRESH_60, CLK_46_996M, M1024X576_R60_HSP, M1024X576_R60_VSP, | ||
760 | {1312, 1024, 1024, 288, 1064, 104, 597, 576, 576, 21, 577, 3} } | ||
761 | }; | ||
762 | |||
763 | /* 1088x612 (CVT) */ | ||
764 | struct crt_mode_table CRTM1088x612[] = { | ||
765 | /* r_rate, vclk, hsp, vsp */ | ||
766 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
767 | {REFRESH_60, CLK_52_977M, M1088X612_R60_HSP, M1088X612_R60_VSP, | ||
768 | {1392, 1088, 1088, 304, 1136, 104, 636, 612, 612, 24, 615, 5} } | ||
769 | }; | ||
770 | |||
771 | /* 1152x720 (CVT) */ | ||
772 | struct crt_mode_table CRTM1152x720[] = { | ||
773 | /* r_rate, vclk, hsp, vsp */ | ||
774 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
775 | {REFRESH_60, CLK_66_750M, M1152X720_R60_HSP, M1152X720_R60_VSP, | ||
776 | {1488, 1152, 1152, 336, 1208, 112, 748, 720, 720, 28, 723, 6} } | ||
777 | }; | ||
778 | |||
779 | /* 1200x720 (GTF) */ | ||
780 | struct crt_mode_table CRTM1200x720[] = { | ||
781 | /* r_rate, vclk, hsp, vsp */ | ||
782 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
783 | {REFRESH_60, CLK_70_159M, M1200X720_R60_HSP, M1200X720_R60_VSP, | ||
784 | {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} } | ||
785 | }; | ||
786 | |||
787 | /* 1280x600 (GTF) */ | ||
788 | struct crt_mode_table CRTM1280x600[] = { | ||
789 | /* r_rate, vclk, hsp, vsp */ | ||
790 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
791 | {REFRESH_60, CLK_61_500M, M1280x600_R60_HSP, M1280x600_R60_VSP, | ||
792 | {1648, 1280, 1280, 368, 1336, 128, 622, 600, 600, 22, 601, 3} } | ||
793 | }; | ||
794 | |||
795 | /* 1360x768 (CVT) */ | ||
796 | struct crt_mode_table CRTM1360x768[] = { | ||
797 | /* r_rate, vclk, hsp, vsp */ | ||
798 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
799 | {REFRESH_60, CLK_84_750M, M1360X768_R60_HSP, M1360X768_R60_VSP, | ||
800 | {1776, 1360, 1360, 416, 1432, 136, 798, 768, 768, 30, 771, 5} } | ||
801 | }; | ||
802 | |||
803 | /* 1360x768 (CVT Reduce Blanking) */ | ||
804 | struct crt_mode_table CRTM1360x768_RB[] = { | ||
805 | /* r_rate, vclk, hsp, vsp */ | ||
806 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
807 | {REFRESH_60, CLK_72_000M, M1360X768_RB_R60_HSP, | ||
808 | M1360X768_RB_R60_VSP, | ||
809 | {1520, 1360, 1360, 160, 1408, 32, 790, 768, 768, 22, 771, 5} } | ||
810 | }; | ||
811 | |||
812 | /* 1366x768 (GTF) */ | ||
813 | struct crt_mode_table CRTM1366x768[] = { | ||
814 | /* r_rate, vclk, hsp, vsp */ | ||
815 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
816 | {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP, | ||
817 | {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} }, | ||
818 | {REFRESH_50, CLK_69_924M, M1368X768_R50_HSP, M1368X768_R50_VSP, | ||
819 | {1768, 1368, 1368, 400, 1424, 144, 791, 768, 768, 23, 769, 3} } | ||
820 | }; | ||
821 | |||
822 | /* 1440x900 (CVT) */ | ||
823 | struct crt_mode_table CRTM1440x900[] = { | ||
824 | /* r_rate, vclk, hsp, vsp */ | ||
825 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
826 | {REFRESH_60, CLK_106_500M, M1440X900_R60_HSP, M1440X900_R60_VSP, | ||
827 | {1904, 1440, 1440, 464, 1520, 152, 934, 900, 900, 34, 903, 6} }, | ||
828 | {REFRESH_75, CLK_136_700M, M1440X900_R75_HSP, M1440X900_R75_VSP, | ||
829 | {1936, 1440, 1440, 496, 1536, 152, 942, 900, 900, 42, 903, 6} } | ||
830 | }; | ||
831 | |||
832 | /* 1440x900 (CVT Reduce Blanking) */ | ||
833 | struct crt_mode_table CRTM1440x900_RB[] = { | ||
834 | /* r_rate, vclk, hsp, vsp */ | ||
835 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
836 | {REFRESH_60, CLK_88_750M, M1440X900_RB_R60_HSP, | ||
837 | M1440X900_RB_R60_VSP, | ||
838 | {1600, 1440, 1440, 160, 1488, 32, 926, 900, 900, 26, 903, 6} } | ||
839 | }; | ||
840 | |||
841 | /* 1600x900 (CVT) */ | ||
842 | struct crt_mode_table CRTM1600x900[] = { | ||
843 | /* r_rate, vclk, hsp, vsp */ | ||
844 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
845 | {REFRESH_60, CLK_118_840M, M1600X900_R60_HSP, M1600X900_R60_VSP, | ||
846 | {2112, 1600, 1600, 512, 1688, 168, 934, 900, 900, 34, 903, 5} } | ||
847 | }; | ||
848 | |||
849 | /* 1600x900 (CVT Reduce Blanking) */ | ||
850 | struct crt_mode_table CRTM1600x900_RB[] = { | ||
851 | /* r_rate, vclk, hsp, vsp */ | ||
852 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
853 | {REFRESH_60, CLK_97_750M, M1600X900_RB_R60_HSP, | ||
854 | M1600X900_RB_R60_VSP, | ||
855 | {1760, 1600, 1600, 160, 1648, 32, 926, 900, 900, 26, 903, 5} } | ||
856 | }; | ||
857 | |||
858 | /* 1600x1024 (GTF) */ | ||
859 | struct crt_mode_table CRTM1600x1024[] = { | ||
860 | /* r_rate, vclk, hsp, vsp */ | ||
861 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
862 | {REFRESH_60, CLK_136_700M, M1600X1024_R60_HSP, M1600X1024_R60_VSP, | ||
863 | {2144, 1600, 1600, 544, 1704, 168, 1060, 1024, 1024, 36, 1025, 3} } | ||
864 | }; | ||
865 | |||
866 | /* 1792x1344 (DMT) */ | ||
867 | struct crt_mode_table CRTM1792x1344[] = { | ||
868 | /* r_rate, vclk, hsp, vsp */ | ||
869 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
870 | {REFRESH_60, CLK_204_000M, M1792x1344_R60_HSP, M1792x1344_R60_VSP, | ||
871 | {2448, 1792, 1792, 656, 1920, 200, 1394, 1344, 1344, 50, 1345, 3} } | ||
872 | }; | ||
873 | |||
874 | /* 1856x1392 (DMT) */ | ||
875 | struct crt_mode_table CRTM1856x1392[] = { | ||
876 | /* r_rate, vclk, hsp, vsp */ | ||
877 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
878 | {REFRESH_60, CLK_218_500M, M1856x1392_R60_HSP, M1856x1392_R60_VSP, | ||
879 | {2528, 1856, 1856, 672, 1952, 224, 1439, 1392, 1392, 47, 1393, 3} } | ||
880 | }; | ||
881 | |||
882 | /* 1920x1200 (CVT) */ | ||
883 | struct crt_mode_table CRTM1920x1200[] = { | ||
884 | /* r_rate, vclk, hsp, vsp */ | ||
885 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
886 | {REFRESH_60, CLK_193_295M, M1920X1200_R60_HSP, M1920X1200_R60_VSP, | ||
887 | {2592, 1920, 1920, 672, 2056, 200, 1245, 1200, 1200, 45, 1203, 6} } | ||
888 | }; | ||
889 | |||
890 | /* 1920x1200 (CVT with Reduce Blanking) */ | ||
891 | struct crt_mode_table CRTM1920x1200_RB[] = { | ||
892 | /* r_rate, vclk, hsp, vsp */ | ||
893 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
894 | {REFRESH_60, CLK_153_920M, M1920X1200_RB_R60_HSP, | ||
895 | M1920X1200_RB_R60_VSP, | ||
896 | {2080, 1920, 1920, 160, 1968, 32, 1235, 1200, 1200, 35, 1203, 6} } | ||
897 | }; | ||
898 | |||
899 | /* 2048x1536 (CVT) */ | ||
900 | struct crt_mode_table CRTM2048x1536[] = { | ||
901 | /* r_rate, vclk, hsp, vsp */ | ||
902 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
903 | {REFRESH_60, CLK_267_250M, M2048x1536_R60_HSP, M2048x1536_R60_VSP, | ||
904 | {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} } | ||
905 | }; | ||
906 | |||
907 | /* Video Mode Table */ | ||
908 | /* struct VideoModeTable {*/ | ||
909 | /* int ModeIndex;*/ | ||
910 | /* struct crt_mode_table *crtc;*/ | ||
911 | /* int mode_array;*/ | ||
912 | /* };*/ | ||
913 | struct VideoModeTable CLE266Modes[] = { | ||
914 | /* Display : 480x640 (GTF) */ | ||
915 | {VIA_RES_480X640, CRTM480x640, ARRAY_SIZE(CRTM480x640)}, | ||
916 | |||
917 | /* Display : 640x480 */ | ||
918 | {VIA_RES_640X480, CRTM640x480, ARRAY_SIZE(CRTM640x480)}, | ||
919 | |||
920 | /* Display : 720x480 (GTF) */ | ||
921 | {VIA_RES_720X480, CRTM720x480, ARRAY_SIZE(CRTM720x480)}, | ||
922 | |||
923 | /* Display : 720x576 (GTF) */ | ||
924 | {VIA_RES_720X576, CRTM720x576, ARRAY_SIZE(CRTM720x576)}, | ||
925 | |||
926 | /* Display : 800x600 */ | ||
927 | {VIA_RES_800X600, CRTM800x600, ARRAY_SIZE(CRTM800x600)}, | ||
928 | |||
929 | /* Display : 800x480 (CVT) */ | ||
930 | {VIA_RES_800X480, CRTM800x480, ARRAY_SIZE(CRTM800x480)}, | ||
931 | |||
932 | /* Display : 848x480 (CVT) */ | ||
933 | {VIA_RES_848X480, CRTM848x480, ARRAY_SIZE(CRTM848x480)}, | ||
934 | |||
935 | /* Display : 852x480 (GTF) */ | ||
936 | {VIA_RES_856X480, CRTM852x480, ARRAY_SIZE(CRTM852x480)}, | ||
937 | |||
938 | /* Display : 1024x512 (GTF) */ | ||
939 | {VIA_RES_1024X512, CRTM1024x512, ARRAY_SIZE(CRTM1024x512)}, | ||
940 | |||
941 | /* Display : 1024x600 */ | ||
942 | {VIA_RES_1024X600, CRTM1024x600, ARRAY_SIZE(CRTM1024x600)}, | ||
943 | |||
944 | /* Display : 1024x576 (GTF) */ | ||
945 | /*{ VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, */ | ||
946 | |||
947 | /* Display : 1024x768 */ | ||
948 | {VIA_RES_1024X768, CRTM1024x768, ARRAY_SIZE(CRTM1024x768)}, | ||
949 | |||
950 | /* Display : 1152x864 */ | ||
951 | {VIA_RES_1152X864, CRTM1152x864, ARRAY_SIZE(CRTM1152x864)}, | ||
952 | |||
953 | /* Display : 1280x768 (GTF) */ | ||
954 | {VIA_RES_1280X768, CRTM1280x768, ARRAY_SIZE(CRTM1280x768)}, | ||
955 | |||
956 | /* Display : 960x600 (CVT) */ | ||
957 | {VIA_RES_960X600, CRTM960x600, ARRAY_SIZE(CRTM960x600)}, | ||
958 | |||
959 | /* Display : 1000x600 (GTF) */ | ||
960 | {VIA_RES_1000X600, CRTM1000x600, ARRAY_SIZE(CRTM1000x600)}, | ||
961 | |||
962 | /* Display : 1024x576 (GTF) */ | ||
963 | {VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, | ||
964 | |||
965 | /* Display : 1088x612 (GTF) */ | ||
966 | {VIA_RES_1088X612, CRTM1088x612, ARRAY_SIZE(CRTM1088x612)}, | ||
967 | |||
968 | /* Display : 1152x720 (CVT) */ | ||
969 | {VIA_RES_1152X720, CRTM1152x720, ARRAY_SIZE(CRTM1152x720)}, | ||
970 | |||
971 | /* Display : 1200x720 (GTF) */ | ||
972 | {VIA_RES_1200X720, CRTM1200x720, ARRAY_SIZE(CRTM1200x720)}, | ||
973 | |||
974 | /* Display : 1280x600 (GTF) */ | ||
975 | {VIA_RES_1280X600, CRTM1280x600, ARRAY_SIZE(CRTM1280x600)}, | ||
976 | |||
977 | /* Display : 1280x800 (CVT) */ | ||
978 | {VIA_RES_1280X800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, | ||
979 | |||
980 | /* Display : 1280x800 (GTF) */ | ||
981 | /*{ M1280x800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, */ | ||
982 | |||
983 | /* Display : 1280x960 */ | ||
984 | {VIA_RES_1280X960, CRTM1280x960, ARRAY_SIZE(CRTM1280x960)}, | ||
985 | |||
986 | /* Display : 1280x1024 */ | ||
987 | {VIA_RES_1280X1024, CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)}, | ||
988 | |||
989 | /* Display : 1360x768 (CVT) */ | ||
990 | {VIA_RES_1360X768, CRTM1360x768, ARRAY_SIZE(CRTM1360x768)}, | ||
991 | |||
992 | /* Display : 1360x768 (CVT Reduce Blanking) */ | ||
993 | {VIA_RES_1360X768_RB, CRTM1360x768_RB, | ||
994 | ARRAY_SIZE(CRTM1360x768_RB)}, | ||
995 | |||
996 | /* Display : 1366x768 */ | ||
997 | {VIA_RES_1366X768, CRTM1366x768, ARRAY_SIZE(CRTM1366x768)}, | ||
998 | |||
999 | /* Display : 1368x768 (GTF) */ | ||
1000 | /*{ M1368x768,CRTM1368x768,ARRAY_SIZE(CRTM1368x768)}, */ | ||
1001 | /* Display : 1368x768 (GTF) */ | ||
1002 | {VIA_RES_1368X768, CRTM1368x768, ARRAY_SIZE(CRTM1368x768)}, | ||
1003 | |||
1004 | /* Display : 1440x900 (CVT) */ | ||
1005 | {VIA_RES_1440X900, CRTM1440x900, ARRAY_SIZE(CRTM1440x900)}, | ||
1006 | |||
1007 | /* Display : 1440x900 (CVT Reduce Blanking) */ | ||
1008 | {VIA_RES_1440X900_RB, CRTM1440x900_RB, | ||
1009 | ARRAY_SIZE(CRTM1440x900_RB)}, | ||
1010 | |||
1011 | /* Display : 1440x1050 (GTF) */ | ||
1012 | {VIA_RES_1440X1050, CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)}, | ||
1013 | |||
1014 | /* Display : 1400x1050 (CVT Reduce Blanking) */ | ||
1015 | {VIA_RES_1400X1050_RB, CRTM1400x1050_RB, | ||
1016 | ARRAY_SIZE(CRTM1400x1050_RB)}, | ||
1017 | |||
1018 | /* Display : 1600x900 (CVT) */ | ||
1019 | {VIA_RES_1600X900, CRTM1600x900, ARRAY_SIZE(CRTM1600x900)}, | ||
1020 | |||
1021 | /* Display : 1600x900 (CVT Reduce Blanking) */ | ||
1022 | {VIA_RES_1600X900_RB, CRTM1600x900_RB, | ||
1023 | ARRAY_SIZE(CRTM1600x900_RB)}, | ||
1024 | |||
1025 | /* Display : 1600x1024 (GTF) */ | ||
1026 | {VIA_RES_1600X1024, CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)}, | ||
1027 | |||
1028 | /* Display : 1600x1200 */ | ||
1029 | {VIA_RES_1600X1200, CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)}, | ||
1030 | |||
1031 | /* Display : 1680x1050 (CVT) */ | ||
1032 | {VIA_RES_1680X1050, CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)}, | ||
1033 | |||
1034 | /* Display : 1680x1050 (CVT Reduce Blanking) */ | ||
1035 | {VIA_RES_1680X1050_RB, CRTM1680x1050_RB, | ||
1036 | ARRAY_SIZE(CRTM1680x1050_RB)}, | ||
1037 | |||
1038 | /* Display : 1792x1344 (DMT) */ | ||
1039 | {VIA_RES_1792X1344, CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)}, | ||
1040 | |||
1041 | /* Display : 1856x1392 (DMT) */ | ||
1042 | {VIA_RES_1856X1392, CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)}, | ||
1043 | |||
1044 | /* Display : 1920x1440 */ | ||
1045 | {VIA_RES_1920X1440, CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)}, | ||
1046 | |||
1047 | /* Display : 2048x1536 */ | ||
1048 | {VIA_RES_2048X1536, CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)}, | ||
1049 | |||
1050 | /* Display : 1280x720 */ | ||
1051 | {VIA_RES_1280X720, CRTM1280x720, ARRAY_SIZE(CRTM1280x720)}, | ||
1052 | |||
1053 | /* Display : 1920x1080 (CVT) */ | ||
1054 | {VIA_RES_1920X1080, CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)}, | ||
1055 | |||
1056 | /* Display : 1920x1080 (CVT Reduce Blanking) */ | ||
1057 | {VIA_RES_1920X1080_RB, CRTM1920x1080_RB, | ||
1058 | ARRAY_SIZE(CRTM1920x1080_RB)}, | ||
1059 | |||
1060 | /* Display : 1920x1200 (CVT) */ | ||
1061 | {VIA_RES_1920X1200, CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)}, | ||
1062 | |||
1063 | /* Display : 1920x1200 (CVT Reduce Blanking) */ | ||
1064 | {VIA_RES_1920X1200_RB, CRTM1920x1200_RB, | ||
1065 | ARRAY_SIZE(CRTM1920x1200_RB)}, | ||
1066 | |||
1067 | /* Display : 1400x1050 (CVT) */ | ||
1068 | {VIA_RES_1400X1050, CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)} | ||
1069 | }; | ||
1070 | struct crt_mode_table CEAM1280x720[] = { | ||
1071 | {REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP, | ||
1072 | M1280X720_CEA_R60_VSP, | ||
1073 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
1074 | {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} } | ||
1075 | }; | ||
1076 | struct crt_mode_table CEAM1920x1080[] = { | ||
1077 | {REFRESH_60, CLK_148_500M, M1920X1080_CEA_R60_HSP, | ||
1078 | M1920X1080_CEA_R60_VSP, | ||
1079 | /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ | ||
1080 | {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} } | ||
1081 | }; | ||
1082 | struct VideoModeTable CEA_HDMI_Modes[] = { | ||
1083 | /* Display : 1280x720 */ | ||
1084 | {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)}, | ||
1085 | {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} | ||
1086 | }; | ||
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h new file mode 100644 index 000000000000..1a5de50a23a2 --- /dev/null +++ b/drivers/video/via/viamode.h | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __VIAMODE_H__ | ||
23 | #define __VIAMODE_H__ | ||
24 | |||
25 | #include "global.h" | ||
26 | |||
27 | struct VPITTable { | ||
28 | unsigned char Misc; | ||
29 | unsigned char SR[StdSR]; | ||
30 | unsigned char GR[StdGR]; | ||
31 | unsigned char AR[StdAR]; | ||
32 | }; | ||
33 | |||
34 | struct VideoModeTable { | ||
35 | int ModeIndex; | ||
36 | struct crt_mode_table *crtc; | ||
37 | int mode_array; | ||
38 | }; | ||
39 | |||
40 | struct patch_table { | ||
41 | int mode_index; | ||
42 | int table_length; | ||
43 | struct io_reg *io_reg_table; | ||
44 | }; | ||
45 | |||
46 | struct res_map_refresh { | ||
47 | int hres; | ||
48 | int vres; | ||
49 | int pixclock; | ||
50 | int vmode_refresh; | ||
51 | }; | ||
52 | |||
53 | #define NUM_TOTAL_RES_MAP_REFRESH ARRAY_SIZE(res_map_refresh_tbl) | ||
54 | #define NUM_TOTAL_CEA_MODES ARRAY_SIZE(CEA_HDMI_Modes) | ||
55 | #define NUM_TOTAL_CN400_ModeXregs ARRAY_SIZE(CN400_ModeXregs) | ||
56 | #define NUM_TOTAL_CN700_ModeXregs ARRAY_SIZE(CN700_ModeXregs) | ||
57 | #define NUM_TOTAL_KM400_ModeXregs ARRAY_SIZE(KM400_ModeXregs) | ||
58 | #define NUM_TOTAL_CX700_ModeXregs ARRAY_SIZE(CX700_ModeXregs) | ||
59 | #define NUM_TOTAL_VX800_ModeXregs ARRAY_SIZE(VX800_ModeXregs) | ||
60 | #define NUM_TOTAL_CLE266_ModeXregs ARRAY_SIZE(CLE266_ModeXregs) | ||
61 | #define NUM_TOTAL_PATCH_MODE ARRAY_SIZE(res_patch_table) | ||
62 | #define NUM_TOTAL_MODETABLE ARRAY_SIZE(CLE266Modes) | ||
63 | |||
64 | /********************/ | ||
65 | /* Mode Table */ | ||
66 | /********************/ | ||
67 | |||
68 | /* 480x640 */ | ||
69 | extern struct crt_mode_table CRTM480x640[1]; | ||
70 | /* 640x480*/ | ||
71 | extern struct crt_mode_table CRTM640x480[5]; | ||
72 | /*720x480 (GTF)*/ | ||
73 | extern struct crt_mode_table CRTM720x480[1]; | ||
74 | /*720x576 (GTF)*/ | ||
75 | extern struct crt_mode_table CRTM720x576[1]; | ||
76 | /* 800x480 (CVT) */ | ||
77 | extern struct crt_mode_table CRTM800x480[1]; | ||
78 | /* 800x600*/ | ||
79 | extern struct crt_mode_table CRTM800x600[5]; | ||
80 | /* 848x480 (CVT) */ | ||
81 | extern struct crt_mode_table CRTM848x480[1]; | ||
82 | /*856x480 (GTF) convert to 852x480*/ | ||
83 | extern struct crt_mode_table CRTM852x480[1]; | ||
84 | /*1024x512 (GTF)*/ | ||
85 | extern struct crt_mode_table CRTM1024x512[1]; | ||
86 | /* 1024x600*/ | ||
87 | extern struct crt_mode_table CRTM1024x600[1]; | ||
88 | /* 1024x768*/ | ||
89 | extern struct crt_mode_table CRTM1024x768[4]; | ||
90 | /* 1152x864*/ | ||
91 | extern struct crt_mode_table CRTM1152x864[1]; | ||
92 | /* 1280x720 (HDMI 720P)*/ | ||
93 | extern struct crt_mode_table CRTM1280x720[2]; | ||
94 | /*1280x768 (GTF)*/ | ||
95 | extern struct crt_mode_table CRTM1280x768[2]; | ||
96 | /* 1280x800 (CVT) */ | ||
97 | extern struct crt_mode_table CRTM1280x800[1]; | ||
98 | /*1280x960*/ | ||
99 | extern struct crt_mode_table CRTM1280x960[1]; | ||
100 | /* 1280x1024*/ | ||
101 | extern struct crt_mode_table CRTM1280x1024[3]; | ||
102 | /* 1368x768 (GTF) */ | ||
103 | extern struct crt_mode_table CRTM1368x768[1]; | ||
104 | /*1440x1050 (GTF)*/ | ||
105 | extern struct crt_mode_table CRTM1440x1050[1]; | ||
106 | /* 1600x1200*/ | ||
107 | extern struct crt_mode_table CRTM1600x1200[2]; | ||
108 | /* 1680x1050 (CVT) */ | ||
109 | extern struct crt_mode_table CRTM1680x1050[2]; | ||
110 | /* 1680x1050 (CVT Reduce Blanking) */ | ||
111 | extern struct crt_mode_table CRTM1680x1050_RB[1]; | ||
112 | /* 1920x1080 (CVT)*/ | ||
113 | extern struct crt_mode_table CRTM1920x1080[1]; | ||
114 | /* 1920x1080 (CVT with Reduce Blanking) */ | ||
115 | extern struct crt_mode_table CRTM1920x1080_RB[1]; | ||
116 | /* 1920x1440*/ | ||
117 | extern struct crt_mode_table CRTM1920x1440[2]; | ||
118 | /* 1400x1050 (CVT) */ | ||
119 | extern struct crt_mode_table CRTM1400x1050[2]; | ||
120 | /* 1400x1050 (CVT Reduce Blanking) */ | ||
121 | extern struct crt_mode_table CRTM1400x1050_RB[1]; | ||
122 | /* 960x600 (CVT) */ | ||
123 | extern struct crt_mode_table CRTM960x600[1]; | ||
124 | /* 1000x600 (GTF) */ | ||
125 | extern struct crt_mode_table CRTM1000x600[1]; | ||
126 | /* 1024x576 (GTF) */ | ||
127 | extern struct crt_mode_table CRTM1024x576[1]; | ||
128 | /* 1088x612 (CVT) */ | ||
129 | extern struct crt_mode_table CRTM1088x612[1]; | ||
130 | /* 1152x720 (CVT) */ | ||
131 | extern struct crt_mode_table CRTM1152x720[1]; | ||
132 | /* 1200x720 (GTF) */ | ||
133 | extern struct crt_mode_table CRTM1200x720[1]; | ||
134 | /* 1280x600 (GTF) */ | ||
135 | extern struct crt_mode_table CRTM1280x600[1]; | ||
136 | /* 1360x768 (CVT) */ | ||
137 | extern struct crt_mode_table CRTM1360x768[1]; | ||
138 | /* 1360x768 (CVT Reduce Blanking) */ | ||
139 | extern struct crt_mode_table CRTM1360x768_RB[1]; | ||
140 | /* 1366x768 (GTF) */ | ||
141 | extern struct crt_mode_table CRTM1366x768[2]; | ||
142 | /* 1440x900 (CVT) */ | ||
143 | extern struct crt_mode_table CRTM1440x900[2]; | ||
144 | /* 1440x900 (CVT Reduce Blanking) */ | ||
145 | extern struct crt_mode_table CRTM1440x900_RB[1]; | ||
146 | /* 1600x900 (CVT) */ | ||
147 | extern struct crt_mode_table CRTM1600x900[1]; | ||
148 | /* 1600x900 (CVT Reduce Blanking) */ | ||
149 | extern struct crt_mode_table CRTM1600x900_RB[1]; | ||
150 | /* 1600x1024 (GTF) */ | ||
151 | extern struct crt_mode_table CRTM1600x1024[1]; | ||
152 | /* 1792x1344 (DMT) */ | ||
153 | extern struct crt_mode_table CRTM1792x1344[1]; | ||
154 | /* 1856x1392 (DMT) */ | ||
155 | extern struct crt_mode_table CRTM1856x1392[1]; | ||
156 | /* 1920x1200 (CVT) */ | ||
157 | extern struct crt_mode_table CRTM1920x1200[1]; | ||
158 | /* 1920x1200 (CVT with Reduce Blanking) */ | ||
159 | extern struct crt_mode_table CRTM1920x1200_RB[1]; | ||
160 | /* 2048x1536 (CVT) */ | ||
161 | extern struct crt_mode_table CRTM2048x1536[1]; | ||
162 | extern struct VideoModeTable CLE266Modes[47]; | ||
163 | extern struct crt_mode_table CEAM1280x720[1]; | ||
164 | extern struct crt_mode_table CEAM1920x1080[1]; | ||
165 | extern struct VideoModeTable CEA_HDMI_Modes[2]; | ||
166 | |||
167 | extern struct res_map_refresh res_map_refresh_tbl[61]; | ||
168 | extern struct io_reg CN400_ModeXregs[52]; | ||
169 | extern struct io_reg CN700_ModeXregs[66]; | ||
170 | extern struct io_reg KM400_ModeXregs[55]; | ||
171 | extern struct io_reg CX700_ModeXregs[58]; | ||
172 | extern struct io_reg VX800_ModeXregs[58]; | ||
173 | extern struct io_reg CLE266_ModeXregs[32]; | ||
174 | extern struct io_reg PM1024x768[2]; | ||
175 | extern struct patch_table res_patch_table[1]; | ||
176 | extern struct VPITTable VPIT; | ||
177 | #endif /* __VIAMODE_H__ */ | ||
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c new file mode 100644 index 000000000000..322a9f993550 --- /dev/null +++ b/drivers/video/via/vt1636.c | |||
@@ -0,0 +1,306 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | |||
24 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | ||
25 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, | ||
26 | u8 index) | ||
27 | { | ||
28 | u8 data; | ||
29 | |||
30 | viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; | ||
31 | viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); | ||
32 | |||
33 | return data; | ||
34 | } | ||
35 | |||
36 | void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information | ||
37 | *plvds_setting_info, struct lvds_chip_information | ||
38 | *plvds_chip_info, struct IODATA io_data) | ||
39 | { | ||
40 | int index, data; | ||
41 | |||
42 | viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; | ||
43 | |||
44 | index = io_data.Index; | ||
45 | data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, | ||
46 | index); | ||
47 | data = (data & (~io_data.Mask)) | io_data.Data; | ||
48 | |||
49 | viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data); | ||
50 | } | ||
51 | |||
52 | void viafb_init_lvds_vt1636(struct lvds_setting_information | ||
53 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) | ||
54 | { | ||
55 | int reg_num, i; | ||
56 | |||
57 | /* Common settings: */ | ||
58 | reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636); | ||
59 | |||
60 | for (i = 0; i < reg_num; i++) { | ||
61 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | ||
62 | plvds_chip_info, | ||
63 | COMMON_INIT_TBL_VT1636[i]); | ||
64 | } | ||
65 | |||
66 | /* Input Data Mode Select */ | ||
67 | if (plvds_setting_info->device_lcd_dualedge) { | ||
68 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | ||
69 | plvds_chip_info, | ||
70 | DUAL_CHANNEL_ENABLE_TBL_VT1636[0]); | ||
71 | } else { | ||
72 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | ||
73 | plvds_chip_info, | ||
74 | SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]); | ||
75 | } | ||
76 | |||
77 | if (plvds_setting_info->LCDDithering) { | ||
78 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | ||
79 | plvds_chip_info, | ||
80 | DITHERING_ENABLE_TBL_VT1636[0]); | ||
81 | } else { | ||
82 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | ||
83 | plvds_chip_info, | ||
84 | DITHERING_DISABLE_TBL_VT1636[0]); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | void viafb_enable_lvds_vt1636(struct lvds_setting_information | ||
89 | *plvds_setting_info, | ||
90 | struct lvds_chip_information *plvds_chip_info) | ||
91 | { | ||
92 | |||
93 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, | ||
94 | VDD_ON_TBL_VT1636[0]); | ||
95 | |||
96 | /* Pad on: */ | ||
97 | switch (plvds_chip_info->output_interface) { | ||
98 | case INTERFACE_DVP0: | ||
99 | { | ||
100 | viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0); | ||
101 | break; | ||
102 | } | ||
103 | |||
104 | case INTERFACE_DVP1: | ||
105 | { | ||
106 | viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); | ||
107 | break; | ||
108 | } | ||
109 | |||
110 | case INTERFACE_DFP_LOW: | ||
111 | { | ||
112 | viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03); | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | case INTERFACE_DFP_HIGH: | ||
117 | { | ||
118 | viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C); | ||
119 | break; | ||
120 | } | ||
121 | |||
122 | } | ||
123 | } | ||
124 | |||
125 | void viafb_disable_lvds_vt1636(struct lvds_setting_information | ||
126 | *plvds_setting_info, | ||
127 | struct lvds_chip_information *plvds_chip_info) | ||
128 | { | ||
129 | |||
130 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, | ||
131 | VDD_OFF_TBL_VT1636[0]); | ||
132 | |||
133 | /* Pad off: */ | ||
134 | switch (plvds_chip_info->output_interface) { | ||
135 | case INTERFACE_DVP0: | ||
136 | { | ||
137 | viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0); | ||
138 | break; | ||
139 | } | ||
140 | |||
141 | case INTERFACE_DVP1: | ||
142 | { | ||
143 | viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30); | ||
144 | break; | ||
145 | } | ||
146 | |||
147 | case INTERFACE_DFP_LOW: | ||
148 | { | ||
149 | viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03); | ||
150 | break; | ||
151 | } | ||
152 | |||
153 | case INTERFACE_DFP_HIGH: | ||
154 | { | ||
155 | viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C); | ||
156 | break; | ||
157 | } | ||
158 | |||
159 | } | ||
160 | } | ||
161 | |||
162 | bool viafb_lvds_identify_vt1636(void) | ||
163 | { | ||
164 | u8 Buffer[2]; | ||
165 | |||
166 | DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n"); | ||
167 | |||
168 | /* Sense VT1636 LVDS Transmiter */ | ||
169 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = | ||
170 | VT1636_LVDS_I2C_ADDR; | ||
171 | |||
172 | /* Check vendor ID first: */ | ||
173 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | ||
174 | lvds_chip_slave_addr, | ||
175 | 0x00, &Buffer[0]); | ||
176 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | ||
177 | lvds_chip_slave_addr, | ||
178 | 0x01, &Buffer[1]); | ||
179 | |||
180 | if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) | ||
181 | return false; | ||
182 | |||
183 | /* Check Chip ID: */ | ||
184 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | ||
185 | lvds_chip_slave_addr, | ||
186 | 0x02, &Buffer[0]); | ||
187 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | ||
188 | lvds_chip_slave_addr, | ||
189 | 0x03, &Buffer[1]); | ||
190 | if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { | ||
191 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | ||
192 | VT1636_LVDS; | ||
193 | return true; | ||
194 | } | ||
195 | |||
196 | return false; | ||
197 | } | ||
198 | |||
199 | static int get_clk_range_index(u32 Clk) | ||
200 | { | ||
201 | if (Clk < DPA_CLK_30M) | ||
202 | return DPA_CLK_RANGE_30M; | ||
203 | else if (Clk < DPA_CLK_50M) | ||
204 | return DPA_CLK_RANGE_30_50M; | ||
205 | else if (Clk < DPA_CLK_70M) | ||
206 | return DPA_CLK_RANGE_50_70M; | ||
207 | else if (Clk < DPA_CLK_100M) | ||
208 | return DPA_CLK_RANGE_70_100M; | ||
209 | else if (Clk < DPA_CLK_150M) | ||
210 | return DPA_CLK_RANGE_100_150M; | ||
211 | else | ||
212 | return DPA_CLK_RANGE_150M; | ||
213 | } | ||
214 | |||
215 | static int get_lvds_dpa_setting_index(int panel_size_id, | ||
216 | struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl, | ||
217 | int tbl_size) | ||
218 | { | ||
219 | int i; | ||
220 | |||
221 | for (i = 0; i < tbl_size; i++) { | ||
222 | if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID) | ||
223 | return i; | ||
224 | |||
225 | p_vt1636_dpasetting_tbl++; | ||
226 | } | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static void set_dpa_vt1636(struct lvds_setting_information | ||
232 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, | ||
233 | struct VT1636_DPA_SETTING *p_vt1636_dpa_setting) | ||
234 | { | ||
235 | struct IODATA io_data; | ||
236 | |||
237 | io_data.Index = 0x09; | ||
238 | io_data.Mask = 0x1F; | ||
239 | io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1; | ||
240 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | ||
241 | plvds_chip_info, io_data); | ||
242 | |||
243 | io_data.Index = 0x08; | ||
244 | io_data.Mask = 0x0F; | ||
245 | io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2; | ||
246 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, | ||
247 | io_data); | ||
248 | } | ||
249 | |||
250 | void viafb_vt1636_patch_skew_on_vt3324( | ||
251 | struct lvds_setting_information *plvds_setting_info, | ||
252 | struct lvds_chip_information *plvds_chip_info) | ||
253 | { | ||
254 | int index, size; | ||
255 | |||
256 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n"); | ||
257 | |||
258 | /* Graphics DPA settings: */ | ||
259 | index = get_clk_range_index(plvds_setting_info->vclk); | ||
260 | viafb_set_dpa_gfx(plvds_chip_info->output_interface, | ||
261 | &GFX_DPA_SETTING_TBL_VT3324[index]); | ||
262 | |||
263 | /* LVDS Transmitter DPA settings: */ | ||
264 | size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324); | ||
265 | index = | ||
266 | get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id, | ||
267 | VT1636_DPA_SETTING_TBL_VT3324, size); | ||
268 | set_dpa_vt1636(plvds_setting_info, plvds_chip_info, | ||
269 | &VT1636_DPA_SETTING_TBL_VT3324[index]); | ||
270 | } | ||
271 | |||
272 | void viafb_vt1636_patch_skew_on_vt3327( | ||
273 | struct lvds_setting_information *plvds_setting_info, | ||
274 | struct lvds_chip_information *plvds_chip_info) | ||
275 | { | ||
276 | int index, size; | ||
277 | |||
278 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n"); | ||
279 | |||
280 | /* Graphics DPA settings: */ | ||
281 | index = get_clk_range_index(plvds_setting_info->vclk); | ||
282 | viafb_set_dpa_gfx(plvds_chip_info->output_interface, | ||
283 | &GFX_DPA_SETTING_TBL_VT3327[index]); | ||
284 | |||
285 | /* LVDS Transmitter DPA settings: */ | ||
286 | size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327); | ||
287 | index = | ||
288 | get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id, | ||
289 | VT1636_DPA_SETTING_TBL_VT3327, size); | ||
290 | set_dpa_vt1636(plvds_setting_info, plvds_chip_info, | ||
291 | &VT1636_DPA_SETTING_TBL_VT3327[index]); | ||
292 | } | ||
293 | |||
294 | void viafb_vt1636_patch_skew_on_vt3364( | ||
295 | struct lvds_setting_information *plvds_setting_info, | ||
296 | struct lvds_chip_information *plvds_chip_info) | ||
297 | { | ||
298 | int index; | ||
299 | |||
300 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n"); | ||
301 | |||
302 | /* Graphics DPA settings: */ | ||
303 | index = get_clk_range_index(plvds_setting_info->vclk); | ||
304 | viafb_set_dpa_gfx(plvds_chip_info->output_interface, | ||
305 | &GFX_DPA_SETTING_TBL_VT3364[index]); | ||
306 | } | ||
diff --git a/drivers/video/via/vt1636.h b/drivers/video/via/vt1636.h new file mode 100644 index 000000000000..2a150c58c7ed --- /dev/null +++ b/drivers/video/via/vt1636.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef _VT1636_H_ | ||
23 | #define _VT1636_H_ | ||
24 | #include "chip.h" | ||
25 | bool viafb_lvds_identify_vt1636(void); | ||
26 | void viafb_init_lvds_vt1636(struct lvds_setting_information | ||
27 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); | ||
28 | void viafb_enable_lvds_vt1636(struct lvds_setting_information | ||
29 | *plvds_setting_info, | ||
30 | struct lvds_chip_information *plvds_chip_info); | ||
31 | void viafb_disable_lvds_vt1636(struct lvds_setting_information | ||
32 | *plvds_setting_info, | ||
33 | struct lvds_chip_information *plvds_chip_info); | ||
34 | void viafb_vt1636_patch_skew_on_vt3324( | ||
35 | struct lvds_setting_information *plvds_setting_info, | ||
36 | struct lvds_chip_information *plvds_chip_info); | ||
37 | void viafb_vt1636_patch_skew_on_vt3327( | ||
38 | struct lvds_setting_information *plvds_setting_info, | ||
39 | struct lvds_chip_information *plvds_chip_info); | ||
40 | void viafb_vt1636_patch_skew_on_vt3364( | ||
41 | struct lvds_setting_information *plvds_setting_info, | ||
42 | struct lvds_chip_information *plvds_chip_info); | ||
43 | |||
44 | #endif | ||
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index 47ed39b52f9c..a463b3dd837b 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c | |||
@@ -680,11 +680,11 @@ static struct xenbus_driver xenfb = { | |||
680 | 680 | ||
681 | static int __init xenfb_init(void) | 681 | static int __init xenfb_init(void) |
682 | { | 682 | { |
683 | if (!is_running_on_xen()) | 683 | if (!xen_domain()) |
684 | return -ENODEV; | 684 | return -ENODEV; |
685 | 685 | ||
686 | /* Nothing to do if running in dom0. */ | 686 | /* Nothing to do if running in dom0. */ |
687 | if (is_initial_xendomain()) | 687 | if (xen_initial_domain()) |
688 | return -ENODEV; | 688 | return -ENODEV; |
689 | 689 | ||
690 | return xenbus_register_frontend(&xenfb); | 690 | return xenbus_register_frontend(&xenfb); |