aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig24
-rw-r--r--drivers/video/acornfb.c26
-rw-r--r--drivers/video/atafb.c2
-rw-r--r--drivers/video/backlight/ltv350qv.c2
-rw-r--r--drivers/video/console/newport_con.c2
-rw-r--r--drivers/video/efifb.c4
-rw-r--r--drivers/video/fbmem.c223
-rw-r--r--drivers/video/imxfb.c28
-rw-r--r--drivers/video/msm/mddi.c2
-rw-r--r--drivers/video/mxsfb.c2
-rw-r--r--drivers/video/s3c-fb.c11
-rw-r--r--drivers/video/s3fb.c209
-rw-r--r--drivers/video/udlfb.c1
-rw-r--r--drivers/video/via/Makefile2
-rw-r--r--drivers/video/via/chip.h6
-rw-r--r--drivers/video/via/dvi.c160
-rw-r--r--drivers/video/via/dvi.h2
-rw-r--r--drivers/video/via/global.c4
-rw-r--r--drivers/video/via/global.h2
-rw-r--r--drivers/video/via/hw.c630
-rw-r--r--drivers/video/via/hw.h15
-rw-r--r--drivers/video/via/lcd.c23
-rw-r--r--drivers/video/via/lcd.h2
-rw-r--r--drivers/video/via/share.h17
-rw-r--r--drivers/video/via/via-core.c9
-rw-r--r--drivers/video/via/via_clock.c349
-rw-r--r--drivers/video/via/via_clock.h76
-rw-r--r--drivers/video/via/viafbdev.c62
-rw-r--r--drivers/video/via/viafbdev.h4
-rw-r--r--drivers/video/via/viamode.c46
-rw-r--r--drivers/video/via/viamode.h9
31 files changed, 1115 insertions, 839 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e6a8d8c0101d..1d0aa5eb10b9 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -8,9 +8,6 @@ menu "Graphics support"
8config HAVE_FB_ATMEL 8config HAVE_FB_ATMEL
9 bool 9 bool
10 10
11config HAVE_FB_IMX
12 bool
13
14config SH_MIPI_DSI 11config SH_MIPI_DSI
15 tristate 12 tristate
16 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK 13 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
@@ -359,7 +356,7 @@ config FB_SA1100
359 356
360config FB_IMX 357config FB_IMX
361 tristate "Freescale i.MX LCD support" 358 tristate "Freescale i.MX LCD support"
362 depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2) 359 depends on FB && IMX_HAVE_PLATFORM_IMX_FB
363 select FB_CFB_FILLRECT 360 select FB_CFB_FILLRECT
364 select FB_CFB_COPYAREA 361 select FB_CFB_COPYAREA
365 select FB_CFB_IMAGEBLIT 362 select FB_CFB_IMAGEBLIT
@@ -1463,6 +1460,14 @@ config FB_S3
1463 ---help--- 1460 ---help---
1464 Driver for graphics boards with S3 Trio / S3 Virge chip. 1461 Driver for graphics boards with S3 Trio / S3 Virge chip.
1465 1462
1463config FB_S3_DDC
1464 bool "DDC for S3 support"
1465 depends on FB_S3
1466 select FB_DDC
1467 default y
1468 help
1469 Say Y here if you want DDC support for your S3 graphics card.
1470
1466config FB_SAVAGE 1471config FB_SAVAGE
1467 tristate "S3 Savage support" 1472 tristate "S3 Savage support"
1468 depends on FB && PCI && EXPERIMENTAL 1473 depends on FB && PCI && EXPERIMENTAL
@@ -1562,6 +1567,17 @@ config FB_VIA_DIRECT_PROCFS
1562 correct output device configuration. 1567 correct output device configuration.
1563 Its use is strongly discouraged. 1568 Its use is strongly discouraged.
1564 1569
1570config FB_VIA_X_COMPATIBILITY
1571 bool "X server compatibility"
1572 depends on FB_VIA
1573 default n
1574 help
1575 This option reduces the functionality (power saving, ...) of the
1576 framebuffer to avoid negative impact on the OpenChrome X server.
1577 If you use any X server other than fbdev you should enable this
1578 otherwise it should be safe to disable it and allow using all
1579 features.
1580
1565endif 1581endif
1566 1582
1567config FB_NEOMAGIC 1583config FB_NEOMAGIC
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 82acb8dc4aa1..6183a57eb69d 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -66,7 +66,7 @@
66 * have. Allow 1% either way on the nominal for TVs. 66 * have. Allow 1% either way on the nominal for TVs.
67 */ 67 */
68#define NR_MONTYPES 6 68#define NR_MONTYPES 6
69static struct fb_monspecs monspecs[NR_MONTYPES] __initdata = { 69static struct fb_monspecs monspecs[NR_MONTYPES] __devinitdata = {
70 { /* TV */ 70 { /* TV */
71 .hfmin = 15469, 71 .hfmin = 15469,
72 .hfmax = 15781, 72 .hfmax = 15781,
@@ -873,7 +873,7 @@ static struct fb_ops acornfb_ops = {
873/* 873/*
874 * Everything after here is initialisation!!! 874 * Everything after here is initialisation!!!
875 */ 875 */
876static struct fb_videomode modedb[] __initdata = { 876static struct fb_videomode modedb[] __devinitdata = {
877 { /* 320x256 @ 50Hz */ 877 { /* 320x256 @ 50Hz */
878 NULL, 50, 320, 256, 125000, 92, 62, 35, 19, 38, 2, 878 NULL, 50, 320, 256, 125000, 92, 62, 35, 19, 38, 2,
879 FB_SYNC_COMP_HIGH_ACT, 879 FB_SYNC_COMP_HIGH_ACT,
@@ -925,8 +925,7 @@ static struct fb_videomode modedb[] __initdata = {
925 } 925 }
926}; 926};
927 927
928static struct fb_videomode __initdata 928static struct fb_videomode acornfb_default_mode __devinitdata = {
929acornfb_default_mode = {
930 .name = NULL, 929 .name = NULL,
931 .refresh = 60, 930 .refresh = 60,
932 .xres = 640, 931 .xres = 640,
@@ -942,7 +941,7 @@ acornfb_default_mode = {
942 .vmode = FB_VMODE_NONINTERLACED 941 .vmode = FB_VMODE_NONINTERLACED
943}; 942};
944 943
945static void __init acornfb_init_fbinfo(void) 944static void __devinit acornfb_init_fbinfo(void)
946{ 945{
947 static int first = 1; 946 static int first = 1;
948 947
@@ -1018,8 +1017,7 @@ static void __init acornfb_init_fbinfo(void)
1018 * size can optionally be followed by 'M' or 'K' for 1017 * size can optionally be followed by 'M' or 'K' for
1019 * MB or KB respectively. 1018 * MB or KB respectively.
1020 */ 1019 */
1021static void __init 1020static void __devinit acornfb_parse_mon(char *opt)
1022acornfb_parse_mon(char *opt)
1023{ 1021{
1024 char *p = opt; 1022 char *p = opt;
1025 1023
@@ -1066,8 +1064,7 @@ bad:
1066 current_par.montype = -1; 1064 current_par.montype = -1;
1067} 1065}
1068 1066
1069static void __init 1067static void __devinit acornfb_parse_montype(char *opt)
1070acornfb_parse_montype(char *opt)
1071{ 1068{
1072 current_par.montype = -2; 1069 current_par.montype = -2;
1073 1070
@@ -1108,8 +1105,7 @@ acornfb_parse_montype(char *opt)
1108 } 1105 }
1109} 1106}
1110 1107
1111static void __init 1108static void __devinit acornfb_parse_dram(char *opt)
1112acornfb_parse_dram(char *opt)
1113{ 1109{
1114 unsigned int size; 1110 unsigned int size;
1115 1111
@@ -1134,15 +1130,14 @@ acornfb_parse_dram(char *opt)
1134static struct options { 1130static struct options {
1135 char *name; 1131 char *name;
1136 void (*parse)(char *opt); 1132 void (*parse)(char *opt);
1137} opt_table[] __initdata = { 1133} opt_table[] __devinitdata = {
1138 { "mon", acornfb_parse_mon }, 1134 { "mon", acornfb_parse_mon },
1139 { "montype", acornfb_parse_montype }, 1135 { "montype", acornfb_parse_montype },
1140 { "dram", acornfb_parse_dram }, 1136 { "dram", acornfb_parse_dram },
1141 { NULL, NULL } 1137 { NULL, NULL }
1142}; 1138};
1143 1139
1144int __init 1140static int __devinit acornfb_setup(char *options)
1145acornfb_setup(char *options)
1146{ 1141{
1147 struct options *optp; 1142 struct options *optp;
1148 char *opt; 1143 char *opt;
@@ -1179,8 +1174,7 @@ acornfb_setup(char *options)
1179 * Detect type of monitor connected 1174 * Detect type of monitor connected
1180 * For now, we just assume SVGA 1175 * For now, we just assume SVGA
1181 */ 1176 */
1182static int __init 1177static int __devinit acornfb_detect_monitortype(void)
1183acornfb_detect_monitortype(void)
1184{ 1178{
1185 return 4; 1179 return 4;
1186} 1180}
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 5b2b5ef4edba..64e41f5448c4 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -3117,7 +3117,7 @@ int __init atafb_init(void)
3117 atafb_ops.fb_setcolreg = &falcon_setcolreg; 3117 atafb_ops.fb_setcolreg = &falcon_setcolreg;
3118 error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher, 3118 error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher,
3119 IRQ_TYPE_PRIO, 3119 IRQ_TYPE_PRIO,
3120 "framebuffer/modeswitch", 3120 "framebuffer:modeswitch",
3121 falcon_vbl_switcher); 3121 falcon_vbl_switcher);
3122 if (error) 3122 if (error)
3123 return error; 3123 return error;
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index dd0e84a9bd2f..cca43c06d3c8 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -333,7 +333,7 @@ static void __exit ltv350qv_exit(void)
333module_init(ltv350qv_init); 333module_init(ltv350qv_init);
334module_exit(ltv350qv_exit); 334module_exit(ltv350qv_exit);
335 335
336MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); 336MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
337MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver"); 337MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver");
338MODULE_LICENSE("GPL"); 338MODULE_LICENSE("GPL");
339MODULE_ALIAS("spi:ltv350qv"); 339MODULE_ALIAS("spi:ltv350qv");
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 3772433c49d1..93317b5b8740 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -6,7 +6,7 @@
6 * 6 *
7 * This driver is based on sgicons.c and cons_newport. 7 * This driver is based on sgicons.c and cons_newport.
8 * 8 *
9 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 9 * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
10 * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) 10 * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 4eb38db36e4b..fb205843c2c7 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -242,9 +242,9 @@ static int set_system(const struct dmi_system_id *id)
242 return 0; 242 return 0;
243 } 243 }
244 244
245 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " 245 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x "
246 "(%dx%d, stride %d)\n", id->ident, 246 "(%dx%d, stride %d)\n", id->ident,
247 (void *)screen_info.lfb_base, screen_info.lfb_width, 247 screen_info.lfb_base, screen_info.lfb_width,
248 screen_info.lfb_height, screen_info.lfb_linelength); 248 screen_info.lfb_height, screen_info.lfb_linelength);
249 249
250 250
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e0c2284924b6..5aac00eb1830 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -42,9 +42,34 @@
42 42
43#define FBPIXMAPSIZE (1024 * 8) 43#define FBPIXMAPSIZE (1024 * 8)
44 44
45static DEFINE_MUTEX(registration_lock);
45struct fb_info *registered_fb[FB_MAX] __read_mostly; 46struct fb_info *registered_fb[FB_MAX] __read_mostly;
46int num_registered_fb __read_mostly; 47int num_registered_fb __read_mostly;
47 48
49static struct fb_info *get_fb_info(unsigned int idx)
50{
51 struct fb_info *fb_info;
52
53 if (idx >= FB_MAX)
54 return ERR_PTR(-ENODEV);
55
56 mutex_lock(&registration_lock);
57 fb_info = registered_fb[idx];
58 if (fb_info)
59 atomic_inc(&fb_info->count);
60 mutex_unlock(&registration_lock);
61
62 return fb_info;
63}
64
65static void put_fb_info(struct fb_info *fb_info)
66{
67 if (!atomic_dec_and_test(&fb_info->count))
68 return;
69 if (fb_info->fbops->fb_destroy)
70 fb_info->fbops->fb_destroy(fb_info);
71}
72
48int lock_fb_info(struct fb_info *info) 73int lock_fb_info(struct fb_info *info)
49{ 74{
50 mutex_lock(&info->lock); 75 mutex_lock(&info->lock);
@@ -647,6 +672,7 @@ int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
647 672
648static void *fb_seq_start(struct seq_file *m, loff_t *pos) 673static void *fb_seq_start(struct seq_file *m, loff_t *pos)
649{ 674{
675 mutex_lock(&registration_lock);
650 return (*pos < FB_MAX) ? pos : NULL; 676 return (*pos < FB_MAX) ? pos : NULL;
651} 677}
652 678
@@ -658,6 +684,7 @@ static void *fb_seq_next(struct seq_file *m, void *v, loff_t *pos)
658 684
659static void fb_seq_stop(struct seq_file *m, void *v) 685static void fb_seq_stop(struct seq_file *m, void *v)
660{ 686{
687 mutex_unlock(&registration_lock);
661} 688}
662 689
663static int fb_seq_show(struct seq_file *m, void *v) 690static int fb_seq_show(struct seq_file *m, void *v)
@@ -690,13 +717,30 @@ static const struct file_operations fb_proc_fops = {
690 .release = seq_release, 717 .release = seq_release,
691}; 718};
692 719
693static ssize_t 720/*
694fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 721 * We hold a reference to the fb_info in file->private_data,
722 * but if the current registered fb has changed, we don't
723 * actually want to use it.
724 *
725 * So look up the fb_info using the inode minor number,
726 * and just verify it against the reference we have.
727 */
728static struct fb_info *file_fb_info(struct file *file)
695{ 729{
696 unsigned long p = *ppos;
697 struct inode *inode = file->f_path.dentry->d_inode; 730 struct inode *inode = file->f_path.dentry->d_inode;
698 int fbidx = iminor(inode); 731 int fbidx = iminor(inode);
699 struct fb_info *info = registered_fb[fbidx]; 732 struct fb_info *info = registered_fb[fbidx];
733
734 if (info != file->private_data)
735 info = NULL;
736 return info;
737}
738
739static ssize_t
740fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
741{
742 unsigned long p = *ppos;
743 struct fb_info *info = file_fb_info(file);
700 u8 *buffer, *dst; 744 u8 *buffer, *dst;
701 u8 __iomem *src; 745 u8 __iomem *src;
702 int c, cnt = 0, err = 0; 746 int c, cnt = 0, err = 0;
@@ -761,9 +805,7 @@ static ssize_t
761fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 805fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
762{ 806{
763 unsigned long p = *ppos; 807 unsigned long p = *ppos;
764 struct inode *inode = file->f_path.dentry->d_inode; 808 struct fb_info *info = file_fb_info(file);
765 int fbidx = iminor(inode);
766 struct fb_info *info = registered_fb[fbidx];
767 u8 *buffer, *src; 809 u8 *buffer, *src;
768 u8 __iomem *dst; 810 u8 __iomem *dst;
769 int c, cnt = 0, err = 0; 811 int c, cnt = 0, err = 0;
@@ -1141,10 +1183,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
1141 1183
1142static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1184static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1143{ 1185{
1144 struct inode *inode = file->f_path.dentry->d_inode; 1186 struct fb_info *info = file_fb_info(file);
1145 int fbidx = iminor(inode);
1146 struct fb_info *info = registered_fb[fbidx];
1147 1187
1188 if (!info)
1189 return -ENODEV;
1148 return do_fb_ioctl(info, cmd, arg); 1190 return do_fb_ioctl(info, cmd, arg);
1149} 1191}
1150 1192
@@ -1265,12 +1307,13 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd,
1265static long fb_compat_ioctl(struct file *file, unsigned int cmd, 1307static long fb_compat_ioctl(struct file *file, unsigned int cmd,
1266 unsigned long arg) 1308 unsigned long arg)
1267{ 1309{
1268 struct inode *inode = file->f_path.dentry->d_inode; 1310 struct fb_info *info = file_fb_info(file);
1269 int fbidx = iminor(inode); 1311 struct fb_ops *fb;
1270 struct fb_info *info = registered_fb[fbidx];
1271 struct fb_ops *fb = info->fbops;
1272 long ret = -ENOIOCTLCMD; 1312 long ret = -ENOIOCTLCMD;
1273 1313
1314 if (!info)
1315 return -ENODEV;
1316 fb = info->fbops;
1274 switch(cmd) { 1317 switch(cmd) {
1275 case FBIOGET_VSCREENINFO: 1318 case FBIOGET_VSCREENINFO:
1276 case FBIOPUT_VSCREENINFO: 1319 case FBIOPUT_VSCREENINFO:
@@ -1303,16 +1346,18 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
1303static int 1346static int
1304fb_mmap(struct file *file, struct vm_area_struct * vma) 1347fb_mmap(struct file *file, struct vm_area_struct * vma)
1305{ 1348{
1306 int fbidx = iminor(file->f_path.dentry->d_inode); 1349 struct fb_info *info = file_fb_info(file);
1307 struct fb_info *info = registered_fb[fbidx]; 1350 struct fb_ops *fb;
1308 struct fb_ops *fb = info->fbops;
1309 unsigned long off; 1351 unsigned long off;
1310 unsigned long start; 1352 unsigned long start;
1311 u32 len; 1353 u32 len;
1312 1354
1355 if (!info)
1356 return -ENODEV;
1313 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) 1357 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1314 return -EINVAL; 1358 return -EINVAL;
1315 off = vma->vm_pgoff << PAGE_SHIFT; 1359 off = vma->vm_pgoff << PAGE_SHIFT;
1360 fb = info->fbops;
1316 if (!fb) 1361 if (!fb)
1317 return -ENODEV; 1362 return -ENODEV;
1318 mutex_lock(&info->mm_lock); 1363 mutex_lock(&info->mm_lock);
@@ -1361,14 +1406,16 @@ __releases(&info->lock)
1361 struct fb_info *info; 1406 struct fb_info *info;
1362 int res = 0; 1407 int res = 0;
1363 1408
1364 if (fbidx >= FB_MAX) 1409 info = get_fb_info(fbidx);
1365 return -ENODEV; 1410 if (!info) {
1366 info = registered_fb[fbidx];
1367 if (!info)
1368 request_module("fb%d", fbidx); 1411 request_module("fb%d", fbidx);
1369 info = registered_fb[fbidx]; 1412 info = get_fb_info(fbidx);
1370 if (!info) 1413 if (!info)
1371 return -ENODEV; 1414 return -ENODEV;
1415 }
1416 if (IS_ERR(info))
1417 return PTR_ERR(info);
1418
1372 mutex_lock(&info->lock); 1419 mutex_lock(&info->lock);
1373 if (!try_module_get(info->fbops->owner)) { 1420 if (!try_module_get(info->fbops->owner)) {
1374 res = -ENODEV; 1421 res = -ENODEV;
@@ -1386,6 +1433,8 @@ __releases(&info->lock)
1386#endif 1433#endif
1387out: 1434out:
1388 mutex_unlock(&info->lock); 1435 mutex_unlock(&info->lock);
1436 if (res)
1437 put_fb_info(info);
1389 return res; 1438 return res;
1390} 1439}
1391 1440
@@ -1401,6 +1450,7 @@ __releases(&info->lock)
1401 info->fbops->fb_release(info,1); 1450 info->fbops->fb_release(info,1);
1402 module_put(info->fbops->owner); 1451 module_put(info->fbops->owner);
1403 mutex_unlock(&info->lock); 1452 mutex_unlock(&info->lock);
1453 put_fb_info(info);
1404 return 0; 1454 return 0;
1405} 1455}
1406 1456
@@ -1487,8 +1537,10 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena,
1487 return false; 1537 return false;
1488} 1538}
1489 1539
1540static int do_unregister_framebuffer(struct fb_info *fb_info);
1541
1490#define VGA_FB_PHYS 0xA0000 1542#define VGA_FB_PHYS 0xA0000
1491void remove_conflicting_framebuffers(struct apertures_struct *a, 1543static void do_remove_conflicting_framebuffers(struct apertures_struct *a,
1492 const char *name, bool primary) 1544 const char *name, bool primary)
1493{ 1545{
1494 int i; 1546 int i;
@@ -1510,43 +1562,32 @@ void remove_conflicting_framebuffers(struct apertures_struct *a,
1510 printk(KERN_INFO "fb: conflicting fb hw usage " 1562 printk(KERN_INFO "fb: conflicting fb hw usage "
1511 "%s vs %s - removing generic driver\n", 1563 "%s vs %s - removing generic driver\n",
1512 name, registered_fb[i]->fix.id); 1564 name, registered_fb[i]->fix.id);
1513 unregister_framebuffer(registered_fb[i]); 1565 do_unregister_framebuffer(registered_fb[i]);
1514 } 1566 }
1515 } 1567 }
1516} 1568}
1517EXPORT_SYMBOL(remove_conflicting_framebuffers);
1518 1569
1519/** 1570static int do_register_framebuffer(struct fb_info *fb_info)
1520 * register_framebuffer - registers a frame buffer device
1521 * @fb_info: frame buffer info structure
1522 *
1523 * Registers a frame buffer device @fb_info.
1524 *
1525 * Returns negative errno on error, or zero for success.
1526 *
1527 */
1528
1529int
1530register_framebuffer(struct fb_info *fb_info)
1531{ 1571{
1532 int i; 1572 int i;
1533 struct fb_event event; 1573 struct fb_event event;
1534 struct fb_videomode mode; 1574 struct fb_videomode mode;
1535 1575
1536 if (num_registered_fb == FB_MAX)
1537 return -ENXIO;
1538
1539 if (fb_check_foreignness(fb_info)) 1576 if (fb_check_foreignness(fb_info))
1540 return -ENOSYS; 1577 return -ENOSYS;
1541 1578
1542 remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, 1579 do_remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id,
1543 fb_is_primary_device(fb_info)); 1580 fb_is_primary_device(fb_info));
1544 1581
1582 if (num_registered_fb == FB_MAX)
1583 return -ENXIO;
1584
1545 num_registered_fb++; 1585 num_registered_fb++;
1546 for (i = 0 ; i < FB_MAX; i++) 1586 for (i = 0 ; i < FB_MAX; i++)
1547 if (!registered_fb[i]) 1587 if (!registered_fb[i])
1548 break; 1588 break;
1549 fb_info->node = i; 1589 fb_info->node = i;
1590 atomic_set(&fb_info->count, 1);
1550 mutex_init(&fb_info->lock); 1591 mutex_init(&fb_info->lock);
1551 mutex_init(&fb_info->mm_lock); 1592 mutex_init(&fb_info->mm_lock);
1552 1593
@@ -1592,36 +1633,14 @@ register_framebuffer(struct fb_info *fb_info)
1592 return 0; 1633 return 0;
1593} 1634}
1594 1635
1595 1636static int do_unregister_framebuffer(struct fb_info *fb_info)
1596/**
1597 * unregister_framebuffer - releases a frame buffer device
1598 * @fb_info: frame buffer info structure
1599 *
1600 * Unregisters a frame buffer device @fb_info.
1601 *
1602 * Returns negative errno on error, or zero for success.
1603 *
1604 * This function will also notify the framebuffer console
1605 * to release the driver.
1606 *
1607 * This is meant to be called within a driver's module_exit()
1608 * function. If this is called outside module_exit(), ensure
1609 * that the driver implements fb_open() and fb_release() to
1610 * check that no processes are using the device.
1611 */
1612
1613int
1614unregister_framebuffer(struct fb_info *fb_info)
1615{ 1637{
1616 struct fb_event event; 1638 struct fb_event event;
1617 int i, ret = 0; 1639 int i, ret = 0;
1618 1640
1619 i = fb_info->node; 1641 i = fb_info->node;
1620 if (!registered_fb[i]) { 1642 if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
1621 ret = -EINVAL; 1643 return -EINVAL;
1622 goto done;
1623 }
1624
1625 1644
1626 if (!lock_fb_info(fb_info)) 1645 if (!lock_fb_info(fb_info))
1627 return -ENODEV; 1646 return -ENODEV;
@@ -1629,16 +1648,14 @@ unregister_framebuffer(struct fb_info *fb_info)
1629 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); 1648 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
1630 unlock_fb_info(fb_info); 1649 unlock_fb_info(fb_info);
1631 1650
1632 if (ret) { 1651 if (ret)
1633 ret = -EINVAL; 1652 return -EINVAL;
1634 goto done;
1635 }
1636 1653
1637 if (fb_info->pixmap.addr && 1654 if (fb_info->pixmap.addr &&
1638 (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) 1655 (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
1639 kfree(fb_info->pixmap.addr); 1656 kfree(fb_info->pixmap.addr);
1640 fb_destroy_modelist(&fb_info->modelist); 1657 fb_destroy_modelist(&fb_info->modelist);
1641 registered_fb[i]=NULL; 1658 registered_fb[i] = NULL;
1642 num_registered_fb--; 1659 num_registered_fb--;
1643 fb_cleanup_device(fb_info); 1660 fb_cleanup_device(fb_info);
1644 device_destroy(fb_class, MKDEV(FB_MAJOR, i)); 1661 device_destroy(fb_class, MKDEV(FB_MAJOR, i));
@@ -1646,9 +1663,65 @@ unregister_framebuffer(struct fb_info *fb_info)
1646 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); 1663 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1647 1664
1648 /* this may free fb info */ 1665 /* this may free fb info */
1649 if (fb_info->fbops->fb_destroy) 1666 put_fb_info(fb_info);
1650 fb_info->fbops->fb_destroy(fb_info); 1667 return 0;
1651done: 1668}
1669
1670void remove_conflicting_framebuffers(struct apertures_struct *a,
1671 const char *name, bool primary)
1672{
1673 mutex_lock(&registration_lock);
1674 do_remove_conflicting_framebuffers(a, name, primary);
1675 mutex_unlock(&registration_lock);
1676}
1677EXPORT_SYMBOL(remove_conflicting_framebuffers);
1678
1679/**
1680 * register_framebuffer - registers a frame buffer device
1681 * @fb_info: frame buffer info structure
1682 *
1683 * Registers a frame buffer device @fb_info.
1684 *
1685 * Returns negative errno on error, or zero for success.
1686 *
1687 */
1688int
1689register_framebuffer(struct fb_info *fb_info)
1690{
1691 int ret;
1692
1693 mutex_lock(&registration_lock);
1694 ret = do_register_framebuffer(fb_info);
1695 mutex_unlock(&registration_lock);
1696
1697 return ret;
1698}
1699
1700/**
1701 * unregister_framebuffer - releases a frame buffer device
1702 * @fb_info: frame buffer info structure
1703 *
1704 * Unregisters a frame buffer device @fb_info.
1705 *
1706 * Returns negative errno on error, or zero for success.
1707 *
1708 * This function will also notify the framebuffer console
1709 * to release the driver.
1710 *
1711 * This is meant to be called within a driver's module_exit()
1712 * function. If this is called outside module_exit(), ensure
1713 * that the driver implements fb_open() and fb_release() to
1714 * check that no processes are using the device.
1715 */
1716int
1717unregister_framebuffer(struct fb_info *fb_info)
1718{
1719 int ret;
1720
1721 mutex_lock(&registration_lock);
1722 ret = do_unregister_framebuffer(fb_info);
1723 mutex_unlock(&registration_lock);
1724
1652 return ret; 1725 return ret;
1653} 1726}
1654 1727
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index ef72cb483834..d2ccfd6e662c 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -65,12 +65,6 @@
65#define CPOS_OP (1<<28) 65#define CPOS_OP (1<<28)
66#define CPOS_CXP(x) (((x) & 3ff) << 16) 66#define CPOS_CXP(x) (((x) & 3ff) << 16)
67 67
68#ifdef CONFIG_ARCH_MX1
69#define CPOS_CYP(y) ((y) & 0x1ff)
70#else
71#define CPOS_CYP(y) ((y) & 0x3ff)
72#endif
73
74#define LCDC_LCWHB 0x10 68#define LCDC_LCWHB 0x10
75#define LCWHB_BK_EN (1<<31) 69#define LCWHB_BK_EN (1<<31)
76#define LCWHB_CW(w) (((w) & 0x1f) << 24) 70#define LCWHB_CW(w) (((w) & 0x1f) << 24)
@@ -79,16 +73,6 @@
79 73
80#define LCDC_LCHCC 0x14 74#define LCDC_LCHCC 0x14
81 75
82#ifdef CONFIG_ARCH_MX1
83#define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11)
84#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5)
85#define LCHCC_CUR_COL_B(b) ((b) & 0x1f)
86#else
87#define LCHCC_CUR_COL_R(r) (((r) & 0x3f) << 12)
88#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 6)
89#define LCHCC_CUR_COL_B(b) ((b) & 0x3f)
90#endif
91
92#define LCDC_PCR 0x18 76#define LCDC_PCR 0x18
93 77
94#define LCDC_HCR 0x1C 78#define LCDC_HCR 0x1C
@@ -115,11 +99,7 @@
115 99
116#define LCDC_RMCR 0x34 100#define LCDC_RMCR 0x34
117 101
118#ifdef CONFIG_ARCH_MX1 102#define RMCR_LCDC_EN_MX1 (1<<1)
119#define RMCR_LCDC_EN (1<<1)
120#else
121#define RMCR_LCDC_EN 0
122#endif
123 103
124#define RMCR_SELF_REF (1<<0) 104#define RMCR_SELF_REF (1<<0)
125 105
@@ -536,7 +516,11 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
536 writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1), 516 writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1),
537 fbi->regs + LCDC_CPOS); 517 fbi->regs + LCDC_CPOS);
538 518
539 writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR); 519 /*
520 * RMCR_LCDC_EN_MX1 is present on i.MX1 only, but doesn't hurt
521 * on other SoCs
522 */
523 writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR);
540 524
541 clk_enable(fbi->clk); 525 clk_enable(fbi->clk);
542 526
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index b66d86ac7cea..178b0720bd79 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -679,7 +679,7 @@ static int __devinit mddi_probe(struct platform_device *pdev)
679 printk(KERN_ERR "mddi: no associated mem resource!\n"); 679 printk(KERN_ERR "mddi: no associated mem resource!\n");
680 return -ENOMEM; 680 return -ENOMEM;
681 } 681 }
682 mddi->base = ioremap(resource->start, resource->end - resource->start); 682 mddi->base = ioremap(resource->start, resource_size(resource));
683 if (!mddi->base) { 683 if (!mddi->base) {
684 printk(KERN_ERR "mddi: failed to remap base!\n"); 684 printk(KERN_ERR "mddi: failed to remap base!\n");
685 ret = -EINVAL; 685 ret = -EINVAL;
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 7d0284882984..0b2f2dd41416 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -401,7 +401,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
401 writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET); 401 writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
402 402
403 ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER | 403 ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER |
404 CTRL_SET_BUS_WIDTH(host->ld_intf_width);; 404 CTRL_SET_BUS_WIDTH(host->ld_intf_width);
405 405
406 switch (fb_info->var.bits_per_pixel) { 406 switch (fb_info->var.bits_per_pixel) {
407 case 16: 407 case 16:
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 3b6cdcac8f1a..3fa7911ac906 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -182,6 +182,7 @@ struct s3c_fb_vsync {
182 182
183/** 183/**
184 * struct s3c_fb - overall hardware state of the hardware 184 * struct s3c_fb - overall hardware state of the hardware
185 * @slock: The spinlock protection for this data sturcture.
185 * @dev: The device that we bound to, for printing, etc. 186 * @dev: The device that we bound to, for printing, etc.
186 * @regs_res: The resource we claimed for the IO registers. 187 * @regs_res: The resource we claimed for the IO registers.
187 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. 188 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
@@ -195,6 +196,7 @@ struct s3c_fb_vsync {
195 * @vsync_info: VSYNC-related information (count, queues...) 196 * @vsync_info: VSYNC-related information (count, queues...)
196 */ 197 */
197struct s3c_fb { 198struct s3c_fb {
199 spinlock_t slock;
198 struct device *dev; 200 struct device *dev;
199 struct resource *regs_res; 201 struct resource *regs_res;
200 struct clk *bus_clk; 202 struct clk *bus_clk;
@@ -947,6 +949,8 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id)
947 void __iomem *regs = sfb->regs; 949 void __iomem *regs = sfb->regs;
948 u32 irq_sts_reg; 950 u32 irq_sts_reg;
949 951
952 spin_lock(&sfb->slock);
953
950 irq_sts_reg = readl(regs + VIDINTCON1); 954 irq_sts_reg = readl(regs + VIDINTCON1);
951 955
952 if (irq_sts_reg & VIDINTCON1_INT_FRAME) { 956 if (irq_sts_reg & VIDINTCON1_INT_FRAME) {
@@ -963,6 +967,7 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id)
963 */ 967 */
964 s3c_fb_disable_irq(sfb); 968 s3c_fb_disable_irq(sfb);
965 969
970 spin_unlock(&sfb->slock);
966 return IRQ_HANDLED; 971 return IRQ_HANDLED;
967} 972}
968 973
@@ -1339,6 +1344,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1339 sfb->pdata = pd; 1344 sfb->pdata = pd;
1340 sfb->variant = fbdrv->variant; 1345 sfb->variant = fbdrv->variant;
1341 1346
1347 spin_lock_init(&sfb->slock);
1348
1342 sfb->bus_clk = clk_get(dev, "lcd"); 1349 sfb->bus_clk = clk_get(dev, "lcd");
1343 if (IS_ERR(sfb->bus_clk)) { 1350 if (IS_ERR(sfb->bus_clk)) {
1344 dev_err(dev, "failed to get bus clock\n"); 1351 dev_err(dev, "failed to get bus clock\n");
@@ -1549,7 +1556,7 @@ static int s3c_fb_resume(struct device *dev)
1549 return 0; 1556 return 0;
1550} 1557}
1551 1558
1552int s3c_fb_runtime_suspend(struct device *dev) 1559static int s3c_fb_runtime_suspend(struct device *dev)
1553{ 1560{
1554 struct platform_device *pdev = to_platform_device(dev); 1561 struct platform_device *pdev = to_platform_device(dev);
1555 struct s3c_fb *sfb = platform_get_drvdata(pdev); 1562 struct s3c_fb *sfb = platform_get_drvdata(pdev);
@@ -1569,7 +1576,7 @@ int s3c_fb_runtime_suspend(struct device *dev)
1569 return 0; 1576 return 0;
1570} 1577}
1571 1578
1572int s3c_fb_runtime_resume(struct device *dev) 1579static int s3c_fb_runtime_resume(struct device *dev)
1573{ 1580{
1574 struct platform_device *pdev = to_platform_device(dev); 1581 struct platform_device *pdev = to_platform_device(dev);
1575 struct s3c_fb *sfb = platform_get_drvdata(pdev); 1582 struct s3c_fb *sfb = platform_get_drvdata(pdev);
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index c4482f2e5799..4ca5d0c8fe84 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -25,6 +25,9 @@
25#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */ 25#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
26#include <video/vga.h> 26#include <video/vga.h>
27 27
28#include <linux/i2c.h>
29#include <linux/i2c-algo-bit.h>
30
28#ifdef CONFIG_MTRR 31#ifdef CONFIG_MTRR
29#include <asm/mtrr.h> 32#include <asm/mtrr.h>
30#endif 33#endif
@@ -36,6 +39,12 @@ struct s3fb_info {
36 struct mutex open_lock; 39 struct mutex open_lock;
37 unsigned int ref_count; 40 unsigned int ref_count;
38 u32 pseudo_palette[16]; 41 u32 pseudo_palette[16];
42#ifdef CONFIG_FB_S3_DDC
43 u8 __iomem *mmio;
44 bool ddc_registered;
45 struct i2c_adapter ddc_adapter;
46 struct i2c_algo_bit_data ddc_algo;
47#endif
39}; 48};
40 49
41 50
@@ -105,6 +114,9 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
105#define CHIP_UNDECIDED_FLAG 0x80 114#define CHIP_UNDECIDED_FLAG 0x80
106#define CHIP_MASK 0xFF 115#define CHIP_MASK 0xFF
107 116
117#define MMIO_OFFSET 0x1000000
118#define MMIO_SIZE 0x10000
119
108/* CRT timing register sets */ 120/* CRT timing register sets */
109 121
110static const struct vga_regset s3_h_total_regs[] = {{0x00, 0, 7}, {0x5D, 0, 0}, VGA_REGSET_END}; 122static const struct vga_regset s3_h_total_regs[] = {{0x00, 0, 7}, {0x5D, 0, 0}, VGA_REGSET_END};
@@ -140,7 +152,7 @@ static const struct svga_timing_regs s3_timing_regs = {
140/* Module parameters */ 152/* Module parameters */
141 153
142 154
143static char *mode_option __devinitdata = "640x480-8@60"; 155static char *mode_option __devinitdata;
144 156
145#ifdef CONFIG_MTRR 157#ifdef CONFIG_MTRR
146static int mtrr __devinitdata = 1; 158static int mtrr __devinitdata = 1;
@@ -169,6 +181,119 @@ MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, defau
169 181
170/* ------------------------------------------------------------------------- */ 182/* ------------------------------------------------------------------------- */
171 183
184#ifdef CONFIG_FB_S3_DDC
185
186#define DDC_REG 0xaa /* Trio 3D/1X/2X */
187#define DDC_MMIO_REG 0xff20 /* all other chips */
188#define DDC_SCL_OUT (1 << 0)
189#define DDC_SDA_OUT (1 << 1)
190#define DDC_SCL_IN (1 << 2)
191#define DDC_SDA_IN (1 << 3)
192#define DDC_DRIVE_EN (1 << 4)
193
194static bool s3fb_ddc_needs_mmio(int chip)
195{
196 return !(chip == CHIP_360_TRIO3D_1X ||
197 chip == CHIP_362_TRIO3D_2X ||
198 chip == CHIP_368_TRIO3D_2X);
199}
200
201static u8 s3fb_ddc_read(struct s3fb_info *par)
202{
203 if (s3fb_ddc_needs_mmio(par->chip))
204 return readb(par->mmio + DDC_MMIO_REG);
205 else
206 return vga_rcrt(par->state.vgabase, DDC_REG);
207}
208
209static void s3fb_ddc_write(struct s3fb_info *par, u8 val)
210{
211 if (s3fb_ddc_needs_mmio(par->chip))
212 writeb(val, par->mmio + DDC_MMIO_REG);
213 else
214 vga_wcrt(par->state.vgabase, DDC_REG, val);
215}
216
217static void s3fb_ddc_setscl(void *data, int val)
218{
219 struct s3fb_info *par = data;
220 unsigned char reg;
221
222 reg = s3fb_ddc_read(par) | DDC_DRIVE_EN;
223 if (val)
224 reg |= DDC_SCL_OUT;
225 else
226 reg &= ~DDC_SCL_OUT;
227 s3fb_ddc_write(par, reg);
228}
229
230static void s3fb_ddc_setsda(void *data, int val)
231{
232 struct s3fb_info *par = data;
233 unsigned char reg;
234
235 reg = s3fb_ddc_read(par) | DDC_DRIVE_EN;
236 if (val)
237 reg |= DDC_SDA_OUT;
238 else
239 reg &= ~DDC_SDA_OUT;
240 s3fb_ddc_write(par, reg);
241}
242
243static int s3fb_ddc_getscl(void *data)
244{
245 struct s3fb_info *par = data;
246
247 return !!(s3fb_ddc_read(par) & DDC_SCL_IN);
248}
249
250static int s3fb_ddc_getsda(void *data)
251{
252 struct s3fb_info *par = data;
253
254 return !!(s3fb_ddc_read(par) & DDC_SDA_IN);
255}
256
257static int __devinit s3fb_setup_ddc_bus(struct fb_info *info)
258{
259 struct s3fb_info *par = info->par;
260
261 strlcpy(par->ddc_adapter.name, info->fix.id,
262 sizeof(par->ddc_adapter.name));
263 par->ddc_adapter.owner = THIS_MODULE;
264 par->ddc_adapter.class = I2C_CLASS_DDC;
265 par->ddc_adapter.algo_data = &par->ddc_algo;
266 par->ddc_adapter.dev.parent = info->device;
267 par->ddc_algo.setsda = s3fb_ddc_setsda;
268 par->ddc_algo.setscl = s3fb_ddc_setscl;
269 par->ddc_algo.getsda = s3fb_ddc_getsda;
270 par->ddc_algo.getscl = s3fb_ddc_getscl;
271 par->ddc_algo.udelay = 10;
272 par->ddc_algo.timeout = 20;
273 par->ddc_algo.data = par;
274
275 i2c_set_adapdata(&par->ddc_adapter, par);
276
277 /*
278 * some Virge cards have external MUX to switch chip I2C bus between
279 * DDC and extension pins - switch it do DDC
280 */
281/* vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */
282 if (par->chip == CHIP_357_VIRGE_GX2 ||
283 par->chip == CHIP_359_VIRGE_GX2P)
284 svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03);
285 else
286 svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03);
287 /* some Virge need this or the DDC is ignored */
288 svga_wcrt_mask(par->state.vgabase, 0x5c, 0x03, 0x03);
289
290 return i2c_bit_add_bus(&par->ddc_adapter);
291}
292#endif /* CONFIG_FB_S3_DDC */
293
294
295/* ------------------------------------------------------------------------- */
296
172/* Set font in S3 fast text mode */ 297/* Set font in S3 fast text mode */
173 298
174static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map) 299static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
@@ -994,6 +1119,7 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
994 struct s3fb_info *par; 1119 struct s3fb_info *par;
995 int rc; 1120 int rc;
996 u8 regval, cr38, cr39; 1121 u8 regval, cr38, cr39;
1122 bool found = false;
997 1123
998 /* Ignore secondary VGA device because there is no VGA arbitration */ 1124 /* Ignore secondary VGA device because there is no VGA arbitration */
999 if (! svga_primary_device(dev)) { 1125 if (! svga_primary_device(dev)) {
@@ -1110,12 +1236,69 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1110 info->fix.ypanstep = 0; 1236 info->fix.ypanstep = 0;
1111 info->fix.accel = FB_ACCEL_NONE; 1237 info->fix.accel = FB_ACCEL_NONE;
1112 info->pseudo_palette = (void*) (par->pseudo_palette); 1238 info->pseudo_palette = (void*) (par->pseudo_palette);
1239 info->var.bits_per_pixel = 8;
1240
1241#ifdef CONFIG_FB_S3_DDC
1242 /* Enable MMIO if needed */
1243 if (s3fb_ddc_needs_mmio(par->chip)) {
1244 par->mmio = ioremap(info->fix.smem_start + MMIO_OFFSET, MMIO_SIZE);
1245 if (par->mmio)
1246 svga_wcrt_mask(par->state.vgabase, 0x53, 0x08, 0x08); /* enable MMIO */
1247 else
1248 dev_err(info->device, "unable to map MMIO at 0x%lx, disabling DDC",
1249 info->fix.smem_start + MMIO_OFFSET);
1250 }
1251 if (!s3fb_ddc_needs_mmio(par->chip) || par->mmio)
1252 if (s3fb_setup_ddc_bus(info) == 0) {
1253 u8 *edid = fb_ddc_read(&par->ddc_adapter);
1254 par->ddc_registered = true;
1255 if (edid) {
1256 fb_edid_to_monspecs(edid, &info->monspecs);
1257 kfree(edid);
1258 if (!info->monspecs.modedb)
1259 dev_err(info->device, "error getting mode database\n");
1260 else {
1261 const struct fb_videomode *m;
1262
1263 fb_videomode_to_modelist(info->monspecs.modedb,
1264 info->monspecs.modedb_len,
1265 &info->modelist);
1266 m = fb_find_best_display(&info->monspecs, &info->modelist);
1267 if (m) {
1268 fb_videomode_to_var(&info->var, m);
1269 /* fill all other info->var's fields */
1270 if (s3fb_check_var(&info->var, info) == 0)
1271 found = true;
1272 }
1273 }
1274 }
1275 }
1276#endif
1277 if (!mode_option && !found)
1278 mode_option = "640x480-8@60";
1113 1279
1114 /* Prepare startup mode */ 1280 /* Prepare startup mode */
1115 rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); 1281 if (mode_option) {
1116 if (! ((rc == 1) || (rc == 2))) { 1282 rc = fb_find_mode(&info->var, info, mode_option,
1117 rc = -EINVAL; 1283 info->monspecs.modedb, info->monspecs.modedb_len,
1118 dev_err(info->device, "mode %s not found\n", mode_option); 1284 NULL, info->var.bits_per_pixel);
1285 if (!rc || rc == 4) {
1286 rc = -EINVAL;
1287 dev_err(info->device, "mode %s not found\n", mode_option);
1288 fb_destroy_modedb(info->monspecs.modedb);
1289 info->monspecs.modedb = NULL;
1290 goto err_find_mode;
1291 }
1292 }
1293
1294 fb_destroy_modedb(info->monspecs.modedb);
1295 info->monspecs.modedb = NULL;
1296
1297 /* maximize virtual vertical size for fast scrolling */
1298 info->var.yres_virtual = info->fix.smem_len * 8 /
1299 (info->var.bits_per_pixel * info->var.xres_virtual);
1300 if (info->var.yres_virtual < info->var.yres) {
1301 dev_err(info->device, "virtual vertical size smaller than real\n");
1119 goto err_find_mode; 1302 goto err_find_mode;
1120 } 1303 }
1121 1304
@@ -1164,6 +1347,12 @@ err_reg_fb:
1164 fb_dealloc_cmap(&info->cmap); 1347 fb_dealloc_cmap(&info->cmap);
1165err_alloc_cmap: 1348err_alloc_cmap:
1166err_find_mode: 1349err_find_mode:
1350#ifdef CONFIG_FB_S3_DDC
1351 if (par->ddc_registered)
1352 i2c_del_adapter(&par->ddc_adapter);
1353 if (par->mmio)
1354 iounmap(par->mmio);
1355#endif
1167 pci_iounmap(dev, info->screen_base); 1356 pci_iounmap(dev, info->screen_base);
1168err_iomap: 1357err_iomap:
1169 pci_release_regions(dev); 1358 pci_release_regions(dev);
@@ -1180,12 +1369,11 @@ err_enable_device:
1180static void __devexit s3_pci_remove(struct pci_dev *dev) 1369static void __devexit s3_pci_remove(struct pci_dev *dev)
1181{ 1370{
1182 struct fb_info *info = pci_get_drvdata(dev); 1371 struct fb_info *info = pci_get_drvdata(dev);
1372 struct s3fb_info __maybe_unused *par = info->par;
1183 1373
1184 if (info) { 1374 if (info) {
1185 1375
1186#ifdef CONFIG_MTRR 1376#ifdef CONFIG_MTRR
1187 struct s3fb_info *par = info->par;
1188
1189 if (par->mtrr_reg >= 0) { 1377 if (par->mtrr_reg >= 0) {
1190 mtrr_del(par->mtrr_reg, 0, 0); 1378 mtrr_del(par->mtrr_reg, 0, 0);
1191 par->mtrr_reg = -1; 1379 par->mtrr_reg = -1;
@@ -1195,6 +1383,13 @@ static void __devexit s3_pci_remove(struct pci_dev *dev)
1195 unregister_framebuffer(info); 1383 unregister_framebuffer(info);
1196 fb_dealloc_cmap(&info->cmap); 1384 fb_dealloc_cmap(&info->cmap);
1197 1385
1386#ifdef CONFIG_FB_S3_DDC
1387 if (par->ddc_registered)
1388 i2c_del_adapter(&par->ddc_adapter);
1389 if (par->mmio)
1390 iounmap(par->mmio);
1391#endif
1392
1198 pci_iounmap(dev, info->screen_base); 1393 pci_iounmap(dev, info->screen_base);
1199 pci_release_regions(dev); 1394 pci_release_regions(dev);
1200/* pci_disable_device(dev); */ 1395/* pci_disable_device(dev); */
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 68041d9dc260..695066b5b2e6 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -27,6 +27,7 @@
27#include <linux/fb.h> 27#include <linux/fb.h>
28#include <linux/vmalloc.h> 28#include <linux/vmalloc.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/prefetch.h>
30#include <linux/delay.h> 31#include <linux/delay.h>
31#include <video/udlfb.h> 32#include <video/udlfb.h>
32#include "edid.h" 33#include "edid.h"
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
index 96f01ee2a412..5108136e8776 100644
--- a/drivers/video/via/Makefile
+++ b/drivers/video/via/Makefile
@@ -6,4 +6,4 @@ obj-$(CONFIG_FB_VIA) += viafb.o
6 6
7viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ 7viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \
8 via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ 8 via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \
9 via-core.o via-gpio.o via_modesetting.o 9 via-core.o via-gpio.o via_modesetting.o via_clock.o
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index 29d70244a21f..3ebf20c06eef 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -137,17 +137,11 @@ struct chip_information {
137 struct lvds_chip_information lvds_chip_info2; 137 struct lvds_chip_information lvds_chip_info2;
138}; 138};
139 139
140struct crt_setting_information {
141 int iga_path;
142};
143
144struct tmds_setting_information { 140struct tmds_setting_information {
145 int iga_path; 141 int iga_path;
146 int h_active; 142 int h_active;
147 int v_active; 143 int v_active;
148 int max_pixel_clock; 144 int max_pixel_clock;
149 int max_hres;
150 int max_vres;
151}; 145};
152 146
153struct lvds_setting_information { 147struct lvds_setting_information {
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index 41ca198b5098..b1f364745ca0 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -28,17 +28,11 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
28static void __devinit dvi_get_panel_size_from_DDCv1( 28static void __devinit dvi_get_panel_size_from_DDCv1(
29 struct tmds_chip_information *tmds_chip, 29 struct tmds_chip_information *tmds_chip,
30 struct tmds_setting_information *tmds_setting); 30 struct tmds_setting_information *tmds_setting);
31static void __devinit dvi_get_panel_size_from_DDCv2(
32 struct tmds_chip_information *tmds_chip,
33 struct tmds_setting_information *tmds_setting);
34static int viafb_dvi_query_EDID(void); 31static int viafb_dvi_query_EDID(void);
35 32
36static int check_tmds_chip(int device_id_subaddr, int device_id) 33static inline bool check_tmds_chip(int device_id_subaddr, int device_id)
37{ 34{
38 if (tmds_register_read(device_id_subaddr) == device_id) 35 return tmds_register_read(device_id_subaddr) == device_id;
39 return OK;
40 else
41 return FAIL;
42} 36}
43 37
44void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, 38void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
@@ -47,22 +41,13 @@ void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
47 DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); 41 DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
48 42
49 viafb_dvi_sense(); 43 viafb_dvi_sense();
50 switch (viafb_dvi_query_EDID()) { 44 if (viafb_dvi_query_EDID() == 1)
51 case 1:
52 dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting); 45 dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting);
53 break;
54 case 2:
55 dvi_get_panel_size_from_DDCv2(tmds_chip, tmds_setting);
56 break;
57 default:
58 printk(KERN_WARNING "viafb_init_dvi_size: DVI panel size undetected!\n");
59 break;
60 }
61 46
62 return; 47 return;
63} 48}
64 49
65int __devinit viafb_tmds_trasmitter_identify(void) 50bool __devinit viafb_tmds_trasmitter_identify(void)
66{ 51{
67 unsigned char sr2a = 0, sr1e = 0, sr3e = 0; 52 unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
68 53
@@ -101,7 +86,7 @@ int __devinit viafb_tmds_trasmitter_identify(void)
101 viaparinfo->chip_info-> 86 viaparinfo->chip_info->
102 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; 87 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
103 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31; 88 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31;
104 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { 89 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) {
105 /* 90 /*
106 * Currently only support 12bits,dual edge,add 24bits mode later 91 * Currently only support 12bits,dual edge,add 24bits mode later
107 */ 92 */
@@ -112,11 +97,10 @@ int __devinit viafb_tmds_trasmitter_identify(void)
112 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); 97 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
113 DEBUG_MSG(KERN_INFO "\n %2d", 98 DEBUG_MSG(KERN_INFO "\n %2d",
114 viaparinfo->chip_info->tmds_chip_info.i2c_port); 99 viaparinfo->chip_info->tmds_chip_info.i2c_port);
115 return OK; 100 return true;
116 } else { 101 } else {
117 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C; 102 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C;
118 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) 103 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) {
119 != FAIL) {
120 tmds_register_write(0x08, 0x3b); 104 tmds_register_write(0x08, 0x3b);
121 DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); 105 DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
122 DEBUG_MSG(KERN_INFO "\n %2d", 106 DEBUG_MSG(KERN_INFO "\n %2d",
@@ -125,7 +109,7 @@ int __devinit viafb_tmds_trasmitter_identify(void)
125 DEBUG_MSG(KERN_INFO "\n %2d", 109 DEBUG_MSG(KERN_INFO "\n %2d",
126 viaparinfo->chip_info-> 110 viaparinfo->chip_info->
127 tmds_chip_info.i2c_port); 111 tmds_chip_info.i2c_port);
128 return OK; 112 return true;
129 } 113 }
130 } 114 }
131 115
@@ -135,7 +119,7 @@ int __devinit viafb_tmds_trasmitter_identify(void)
135 ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) || 119 ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
136 (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) { 120 (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
137 DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n"); 121 DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
138 return OK; 122 return true;
139 } 123 }
140 124
141 switch (viaparinfo->chip_info->gfx_chip_name) { 125 switch (viaparinfo->chip_info->gfx_chip_name) {
@@ -159,7 +143,7 @@ int __devinit viafb_tmds_trasmitter_identify(void)
159 tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER; 143 tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
160 viaparinfo->chip_info->tmds_chip_info. 144 viaparinfo->chip_info->tmds_chip_info.
161 tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; 145 tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
162 return FAIL; 146 return false;
163} 147}
164 148
165static void tmds_register_write(int index, u8 data) 149static void tmds_register_write(int index, u8 data)
@@ -306,12 +290,7 @@ static int viafb_dvi_query_EDID(void)
306 return EDID_VERSION_1; /* Found EDID1 Table */ 290 return EDID_VERSION_1; /* Found EDID1 Table */
307 } 291 }
308 292
309 data0 = (u8) tmds_register_read(0x00); 293 return false;
310 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
311 if (data0 == 0x20)
312 return EDID_VERSION_2; /* Found EDID2 Table */
313 else
314 return false;
315} 294}
316 295
317/* Get Panel Size Using EDID1 Table */ 296/* Get Panel Size Using EDID1 Table */
@@ -319,50 +298,15 @@ static void __devinit dvi_get_panel_size_from_DDCv1(
319 struct tmds_chip_information *tmds_chip, 298 struct tmds_chip_information *tmds_chip,
320 struct tmds_setting_information *tmds_setting) 299 struct tmds_setting_information *tmds_setting)
321{ 300{
322 int i, max_h = 0, tmp, restore; 301 int i, restore;
323 unsigned char rData;
324 unsigned char EDID_DATA[18]; 302 unsigned char EDID_DATA[18];
325 303
326 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n"); 304 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
327 305
328 restore = tmds_chip->tmds_chip_slave_addr; 306 restore = tmds_chip->tmds_chip_slave_addr;
329 tmds_chip->tmds_chip_slave_addr = 0xA0; 307 tmds_chip->tmds_chip_slave_addr = 0xA0;
330
331 rData = tmds_register_read(0x23);
332 if (rData & 0x3C)
333 max_h = 640;
334 if (rData & 0xC0)
335 max_h = 720;
336 if (rData & 0x03)
337 max_h = 800;
338
339 rData = tmds_register_read(0x24);
340 if (rData & 0xC0)
341 max_h = 800;
342 if (rData & 0x1E)
343 max_h = 1024;
344 if (rData & 0x01)
345 max_h = 1280;
346
347 for (i = 0x25; i < 0x6D; i++) { 308 for (i = 0x25; i < 0x6D; i++) {
348 switch (i) { 309 switch (i) {
349 case 0x26:
350 case 0x28:
351 case 0x2A:
352 case 0x2C:
353 case 0x2E:
354 case 0x30:
355 case 0x32:
356 case 0x34:
357 rData = tmds_register_read(i);
358 if (rData == 1)
359 break;
360 /* data = (data + 31) * 8 */
361 tmp = (rData + 31) << 3;
362 if (tmp > max_h)
363 max_h = tmp;
364 break;
365
366 case 0x36: 310 case 0x36:
367 case 0x48: 311 case 0x48:
368 case 0x5A: 312 case 0x5A:
@@ -383,91 +327,11 @@ static void __devinit dvi_get_panel_size_from_DDCv1(
383 } 327 }
384 } 328 }
385 329
386 tmds_setting->max_hres = max_h;
387 switch (max_h) {
388 case 640:
389 tmds_setting->max_vres = 480;
390 break;
391 case 800:
392 tmds_setting->max_vres = 600;
393 break;
394 case 1024:
395 tmds_setting->max_vres = 768;
396 break;
397 case 1280:
398 tmds_setting->max_vres = 1024;
399 break;
400 case 1400:
401 tmds_setting->max_vres = 1050;
402 break;
403 case 1440:
404 tmds_setting->max_vres = 1050;
405 break;
406 case 1600:
407 tmds_setting->max_vres = 1200;
408 break;
409 case 1920:
410 tmds_setting->max_vres = 1080;
411 break;
412 default:
413 DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d ! "
414 "set default panel size.\n", max_h);
415 break;
416 }
417
418 DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n", 330 DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
419 tmds_setting->max_pixel_clock); 331 tmds_setting->max_pixel_clock);
420 tmds_chip->tmds_chip_slave_addr = restore; 332 tmds_chip->tmds_chip_slave_addr = restore;
421} 333}
422 334
423/* Get Panel Size Using EDID2 Table */
424static void __devinit dvi_get_panel_size_from_DDCv2(
425 struct tmds_chip_information *tmds_chip,
426 struct tmds_setting_information *tmds_setting)
427{
428 int restore;
429 unsigned char R_Buffer[2];
430
431 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
432
433 restore = tmds_chip->tmds_chip_slave_addr;
434 tmds_chip->tmds_chip_slave_addr = 0xA2;
435
436 /* Horizontal: 0x76, 0x77 */
437 tmds_register_read_bytes(0x76, R_Buffer, 2);
438 tmds_setting->max_hres = R_Buffer[0] + (R_Buffer[1] << 8);
439
440 switch (tmds_setting->max_hres) {
441 case 640:
442 tmds_setting->max_vres = 480;
443 break;
444 case 800:
445 tmds_setting->max_vres = 600;
446 break;
447 case 1024:
448 tmds_setting->max_vres = 768;
449 break;
450 case 1280:
451 tmds_setting->max_vres = 1024;
452 break;
453 case 1400:
454 tmds_setting->max_vres = 1050;
455 break;
456 case 1440:
457 tmds_setting->max_vres = 1050;
458 break;
459 case 1600:
460 tmds_setting->max_vres = 1200;
461 break;
462 default:
463 DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d! "
464 "set default panel size.\n", tmds_setting->max_hres);
465 break;
466 }
467
468 tmds_chip->tmds_chip_slave_addr = restore;
469}
470
471/* If Disable DVI, turn off pad */ 335/* If Disable DVI, turn off pad */
472void viafb_dvi_disable(void) 336void viafb_dvi_disable(void)
473{ 337{
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
index 2c525c0c1adb..f473dd010977 100644
--- a/drivers/video/via/dvi.h
+++ b/drivers/video/via/dvi.h
@@ -56,7 +56,7 @@
56int viafb_dvi_sense(void); 56int viafb_dvi_sense(void);
57void viafb_dvi_disable(void); 57void viafb_dvi_disable(void);
58void viafb_dvi_enable(void); 58void viafb_dvi_enable(void);
59int __devinit viafb_tmds_trasmitter_identify(void); 59bool __devinit viafb_tmds_trasmitter_identify(void);
60void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, 60void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
61 struct tmds_setting_information *tmds_setting); 61 struct tmds_setting_information *tmds_setting);
62void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, 62void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp,
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
index 1ee511b73307..e10d8249534c 100644
--- a/drivers/video/via/global.c
+++ b/drivers/video/via/global.c
@@ -40,10 +40,6 @@ int viafb_hotplug_Yres = 480;
40int viafb_hotplug_bpp = 32; 40int viafb_hotplug_bpp = 32;
41int viafb_hotplug_refresh = 60; 41int viafb_hotplug_refresh = 60;
42int viafb_primary_dev = None_Device; 42int viafb_primary_dev = None_Device;
43unsigned int viafb_second_xres = 640;
44unsigned int viafb_second_yres = 480;
45unsigned int viafb_second_virtual_xres;
46unsigned int viafb_second_virtual_yres;
47int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; 43int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
48struct fb_info *viafbinfo; 44struct fb_info *viafbinfo;
49struct fb_info *viafbinfo1; 45struct fb_info *viafbinfo1;
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
index 38ef5ac66953..ff969dc34593 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/via/global.h
@@ -73,8 +73,6 @@ extern int viafb_hotplug_bpp;
73extern int viafb_hotplug_refresh; 73extern int viafb_hotplug_refresh;
74extern int viafb_primary_dev; 74extern int viafb_primary_dev;
75 75
76extern unsigned int viafb_second_xres;
77extern unsigned int viafb_second_yres;
78extern int viafb_lcd_panel_id; 76extern int viafb_lcd_panel_id;
79 77
80#endif /* __GLOBAL_H__ */ 78#endif /* __GLOBAL_H__ */
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index dc4c778877ce..47b13535ed2b 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -20,274 +20,84 @@
20 */ 20 */
21 21
22#include <linux/via-core.h> 22#include <linux/via-core.h>
23#include <asm/olpc.h>
23#include "global.h" 24#include "global.h"
24 25#include "via_clock.h"
25static struct pll_config cle266_pll_config[] = { 26
26 {19, 4, 0}, 27static struct pll_limit cle266_pll_limits[] = {
27 {26, 5, 0}, 28 {19, 19, 4, 0},
28 {28, 5, 0}, 29 {26, 102, 5, 0},
29 {31, 5, 0}, 30 {53, 112, 6, 0},
30 {33, 5, 0}, 31 {41, 100, 7, 0},
31 {55, 5, 0}, 32 {83, 108, 8, 0},
32 {102, 5, 0}, 33 {87, 118, 9, 0},
33 {53, 6, 0}, 34 {95, 115, 12, 0},
34 {92, 6, 0}, 35 {108, 108, 13, 0},
35 {98, 6, 0}, 36 {83, 83, 17, 0},
36 {112, 6, 0}, 37 {67, 98, 20, 0},
37 {41, 7, 0}, 38 {121, 121, 24, 0},
38 {60, 7, 0}, 39 {99, 99, 29, 0},
39 {99, 7, 0}, 40 {33, 33, 3, 1},
40 {100, 7, 0}, 41 {15, 23, 4, 1},
41 {83, 8, 0}, 42 {37, 121, 5, 1},
42 {86, 8, 0}, 43 {82, 82, 6, 1},
43 {108, 8, 0}, 44 {31, 84, 7, 1},
44 {87, 9, 0}, 45 {83, 83, 8, 1},
45 {118, 9, 0}, 46 {76, 127, 9, 1},
46 {95, 12, 0}, 47 {33, 121, 4, 2},
47 {115, 12, 0}, 48 {91, 118, 5, 2},
48 {108, 13, 0}, 49 {83, 109, 6, 2},
49 {83, 17, 0}, 50 {90, 90, 7, 2},
50 {67, 20, 0}, 51 {93, 93, 2, 3},
51 {86, 20, 0}, 52 {53, 53, 3, 3},
52 {98, 20, 0}, 53 {73, 117, 4, 3},
53 {121, 24, 0}, 54 {101, 127, 5, 3},
54 {99, 29, 0}, 55 {99, 99, 7, 3}
55 {33, 3, 1},
56 {15, 4, 1},
57 {23, 4, 1},
58 {37, 5, 1},
59 {83, 5, 1},
60 {85, 5, 1},
61 {94, 5, 1},
62 {103, 5, 1},
63 {109, 5, 1},
64 {113, 5, 1},
65 {121, 5, 1},
66 {82, 6, 1},
67 {31, 7, 1},
68 {55, 7, 1},
69 {84, 7, 1},
70 {83, 8, 1},
71 {76, 9, 1},
72 {127, 9, 1},
73 {33, 4, 2},
74 {75, 4, 2},
75 {119, 4, 2},
76 {121, 4, 2},
77 {91, 5, 2},
78 {118, 5, 2},
79 {83, 6, 2},
80 {109, 6, 2},
81 {90, 7, 2},
82 {93, 2, 3},
83 {53, 3, 3},
84 {73, 4, 3},
85 {89, 4, 3},
86 {105, 4, 3},
87 {117, 4, 3},
88 {101, 5, 3},
89 {121, 5, 3},
90 {127, 5, 3},
91 {99, 7, 3}
92}; 56};
93 57
94static struct pll_config k800_pll_config[] = { 58static struct pll_limit k800_pll_limits[] = {
95 {22, 2, 0}, 59 {22, 22, 2, 0},
96 {28, 3, 0}, 60 {28, 28, 3, 0},
97 {81, 3, 1}, 61 {81, 112, 3, 1},
98 {85, 3, 1}, 62 {86, 166, 4, 1},
99 {98, 3, 1}, 63 {109, 153, 5, 1},
100 {112, 3, 1}, 64 {66, 116, 3, 2},
101 {86, 4, 1}, 65 {93, 137, 4, 2},
102 {166, 4, 1}, 66 {117, 208, 5, 2},
103 {109, 5, 1}, 67 {30, 30, 2, 3},
104 {113, 5, 1}, 68 {69, 125, 3, 3},
105 {121, 5, 1}, 69 {89, 161, 4, 3},
106 {131, 5, 1}, 70 {121, 208, 5, 3},
107 {143, 5, 1}, 71 {66, 66, 2, 4},
108 {153, 5, 1}, 72 {85, 85, 3, 4},
109 {66, 3, 2}, 73 {141, 161, 4, 4},
110 {68, 3, 2}, 74 {177, 177, 5, 4}
111 {95, 3, 2},
112 {106, 3, 2},
113 {116, 3, 2},
114 {93, 4, 2},
115 {119, 4, 2},
116 {121, 4, 2},
117 {133, 4, 2},
118 {137, 4, 2},
119 {117, 5, 2},
120 {118, 5, 2},
121 {120, 5, 2},
122 {124, 5, 2},
123 {132, 5, 2},
124 {137, 5, 2},
125 {141, 5, 2},
126 {166, 5, 2},
127 {170, 5, 2},
128 {191, 5, 2},
129 {206, 5, 2},
130 {208, 5, 2},
131 {30, 2, 3},
132 {69, 3, 3},
133 {82, 3, 3},
134 {83, 3, 3},
135 {109, 3, 3},
136 {114, 3, 3},
137 {125, 3, 3},
138 {89, 4, 3},
139 {103, 4, 3},
140 {117, 4, 3},
141 {126, 4, 3},
142 {150, 4, 3},
143 {161, 4, 3},
144 {121, 5, 3},
145 {127, 5, 3},
146 {131, 5, 3},
147 {134, 5, 3},
148 {148, 5, 3},
149 {169, 5, 3},
150 {172, 5, 3},
151 {182, 5, 3},
152 {195, 5, 3},
153 {196, 5, 3},
154 {208, 5, 3},
155 {66, 2, 4},
156 {85, 3, 4},
157 {141, 4, 4},
158 {146, 4, 4},
159 {161, 4, 4},
160 {177, 5, 4}
161}; 75};
162 76
163static struct pll_config cx700_pll_config[] = { 77static struct pll_limit cx700_pll_limits[] = {
164 {98, 3, 1}, 78 {98, 98, 3, 1},
165 {86, 4, 1}, 79 {86, 86, 4, 1},
166 {109, 5, 1}, 80 {109, 208, 5, 1},
167 {110, 5, 1}, 81 {68, 68, 2, 2},
168 {113, 5, 1}, 82 {95, 116, 3, 2},
169 {121, 5, 1}, 83 {93, 166, 4, 2},
170 {131, 5, 1}, 84 {110, 206, 5, 2},
171 {135, 5, 1}, 85 {174, 174, 7, 2},
172 {142, 5, 1}, 86 {82, 109, 3, 3},
173 {143, 5, 1}, 87 {117, 161, 4, 3},
174 {153, 5, 1}, 88 {112, 208, 5, 3},
175 {187, 5, 1}, 89 {141, 202, 5, 4}
176 {208, 5, 1},
177 {68, 2, 2},
178 {95, 3, 2},
179 {116, 3, 2},
180 {93, 4, 2},
181 {119, 4, 2},
182 {133, 4, 2},
183 {137, 4, 2},
184 {151, 4, 2},
185 {166, 4, 2},
186 {110, 5, 2},
187 {112, 5, 2},
188 {117, 5, 2},
189 {118, 5, 2},
190 {120, 5, 2},
191 {132, 5, 2},
192 {137, 5, 2},
193 {141, 5, 2},
194 {151, 5, 2},
195 {166, 5, 2},
196 {175, 5, 2},
197 {191, 5, 2},
198 {206, 5, 2},
199 {174, 7, 2},
200 {82, 3, 3},
201 {109, 3, 3},
202 {117, 4, 3},
203 {150, 4, 3},
204 {161, 4, 3},
205 {112, 5, 3},
206 {115, 5, 3},
207 {121, 5, 3},
208 {127, 5, 3},
209 {129, 5, 3},
210 {131, 5, 3},
211 {134, 5, 3},
212 {138, 5, 3},
213 {148, 5, 3},
214 {157, 5, 3},
215 {169, 5, 3},
216 {172, 5, 3},
217 {190, 5, 3},
218 {195, 5, 3},
219 {196, 5, 3},
220 {208, 5, 3},
221 {141, 5, 4},
222 {150, 5, 4},
223 {166, 5, 4},
224 {176, 5, 4},
225 {177, 5, 4},
226 {183, 5, 4},
227 {202, 5, 4}
228}; 90};
229 91
230static struct pll_config vx855_pll_config[] = { 92static struct pll_limit vx855_pll_limits[] = {
231 {86, 4, 1}, 93 {86, 86, 4, 1},
232 {108, 5, 1}, 94 {108, 208, 5, 1},
233 {110, 5, 1}, 95 {110, 208, 5, 2},
234 {113, 5, 1}, 96 {83, 112, 3, 3},
235 {121, 5, 1}, 97 {103, 161, 4, 3},
236 {131, 5, 1}, 98 {112, 209, 5, 3},
237 {135, 5, 1}, 99 {142, 161, 4, 4},
238 {142, 5, 1}, 100 {141, 176, 5, 4}
239 {143, 5, 1},
240 {153, 5, 1},
241 {164, 5, 1},
242 {187, 5, 1},
243 {208, 5, 1},
244 {110, 5, 2},
245 {112, 5, 2},
246 {117, 5, 2},
247 {118, 5, 2},
248 {124, 5, 2},
249 {132, 5, 2},
250 {137, 5, 2},
251 {141, 5, 2},
252 {149, 5, 2},
253 {151, 5, 2},
254 {159, 5, 2},
255 {166, 5, 2},
256 {167, 5, 2},
257 {172, 5, 2},
258 {189, 5, 2},
259 {191, 5, 2},
260 {194, 5, 2},
261 {206, 5, 2},
262 {208, 5, 2},
263 {83, 3, 3},
264 {88, 3, 3},
265 {109, 3, 3},
266 {112, 3, 3},
267 {103, 4, 3},
268 {105, 4, 3},
269 {161, 4, 3},
270 {112, 5, 3},
271 {115, 5, 3},
272 {121, 5, 3},
273 {127, 5, 3},
274 {134, 5, 3},
275 {137, 5, 3},
276 {148, 5, 3},
277 {157, 5, 3},
278 {169, 5, 3},
279 {172, 5, 3},
280 {182, 5, 3},
281 {191, 5, 3},
282 {195, 5, 3},
283 {209, 5, 3},
284 {142, 4, 4},
285 {146, 4, 4},
286 {161, 4, 4},
287 {141, 5, 4},
288 {150, 5, 4},
289 {165, 5, 4},
290 {176, 5, 4}
291}; 101};
292 102
293/* according to VIA Technologies these values are based on experiment */ 103/* according to VIA Technologies these values are based on experiment */
@@ -308,6 +118,42 @@ static struct io_reg scaling_parameters[] = {
308 {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ 118 {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
309}; 119};
310 120
121static struct io_reg common_vga[] = {
122 {VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8)
123 [1] vertical display end (bit 8)
124 [2] vertical retrace start (bit 8)
125 [3] start vertical blanking (bit 8)
126 [4] line compare (bit 8)
127 [5] vertical total (bit 9)
128 [6] vertical display end (bit 9)
129 [7] vertical retrace start (bit 9) */
130 {VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan
131 [5-6] byte panning */
132 {VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line
133 [5] start vertical blanking (bit 9)
134 [6] line compare (bit 9)
135 [7] scan doubling */
136 {VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start
137 [5] cursor disable */
138 {VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end
139 [5-6] cursor skew */
140 {VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */
141 {VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */
142 {VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end
143 [6] memory refresh bandwidth
144 [7] CRTC register protect enable */
145 {VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location
146 [5] divide memory address clock by 4
147 [6] double word addressing */
148 {VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14
149 [2] divide scan line clock by 2
150 [3] divide memory address clock by 2
151 [5] address wrap
152 [6] byte mode select
153 [7] sync enable */
154 {VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */
155};
156
311static struct fifo_depth_select display_fifo_depth_reg = { 157static struct fifo_depth_select display_fifo_depth_reg = {
312 /* IGA1 FIFO Depth_Select */ 158 /* IGA1 FIFO Depth_Select */
313 {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } }, 159 {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
@@ -676,6 +522,9 @@ static struct via_device_mapping device_mapping[] = {
676 {VIA_LVDS2, "LVDS2"} 522 {VIA_LVDS2, "LVDS2"}
677}; 523};
678 524
525/* structure with function pointers to support clock control */
526static struct via_clock clock;
527
679static void load_fix_bit_crtc_reg(void); 528static void load_fix_bit_crtc_reg(void);
680static void __devinit init_gfx_chip_info(int chip_type); 529static void __devinit init_gfx_chip_info(int chip_type);
681static void __devinit init_tmds_chip_info(void); 530static void __devinit init_tmds_chip_info(void);
@@ -770,13 +619,14 @@ static u32 get_lcd_devices(int output_interface)
770/*Set IGA path for each device*/ 619/*Set IGA path for each device*/
771void viafb_set_iga_path(void) 620void viafb_set_iga_path(void)
772{ 621{
622 int crt_iga_path = 0;
773 623
774 if (viafb_SAMM_ON == 1) { 624 if (viafb_SAMM_ON == 1) {
775 if (viafb_CRT_ON) { 625 if (viafb_CRT_ON) {
776 if (viafb_primary_dev == CRT_Device) 626 if (viafb_primary_dev == CRT_Device)
777 viaparinfo->crt_setting_info->iga_path = IGA1; 627 crt_iga_path = IGA1;
778 else 628 else
779 viaparinfo->crt_setting_info->iga_path = IGA2; 629 crt_iga_path = IGA2;
780 } 630 }
781 631
782 if (viafb_DVI_ON) { 632 if (viafb_DVI_ON) {
@@ -793,8 +643,7 @@ void viafb_set_iga_path(void)
793 UNICHROME_CLE266)) { 643 UNICHROME_CLE266)) {
794 viaparinfo-> 644 viaparinfo->
795 lvds_setting_info->iga_path = IGA2; 645 lvds_setting_info->iga_path = IGA2;
796 viaparinfo-> 646 crt_iga_path = IGA1;
797 crt_setting_info->iga_path = IGA1;
798 viaparinfo-> 647 viaparinfo->
799 tmds_setting_info->iga_path = IGA1; 648 tmds_setting_info->iga_path = IGA1;
800 } else 649 } else
@@ -814,10 +663,10 @@ void viafb_set_iga_path(void)
814 viafb_SAMM_ON = 0; 663 viafb_SAMM_ON = 0;
815 664
816 if (viafb_CRT_ON && viafb_LCD_ON) { 665 if (viafb_CRT_ON && viafb_LCD_ON) {
817 viaparinfo->crt_setting_info->iga_path = IGA1; 666 crt_iga_path = IGA1;
818 viaparinfo->lvds_setting_info->iga_path = IGA2; 667 viaparinfo->lvds_setting_info->iga_path = IGA2;
819 } else if (viafb_CRT_ON && viafb_DVI_ON) { 668 } else if (viafb_CRT_ON && viafb_DVI_ON) {
820 viaparinfo->crt_setting_info->iga_path = IGA1; 669 crt_iga_path = IGA1;
821 viaparinfo->tmds_setting_info->iga_path = IGA2; 670 viaparinfo->tmds_setting_info->iga_path = IGA2;
822 } else if (viafb_LCD_ON && viafb_DVI_ON) { 671 } else if (viafb_LCD_ON && viafb_DVI_ON) {
823 viaparinfo->tmds_setting_info->iga_path = IGA1; 672 viaparinfo->tmds_setting_info->iga_path = IGA1;
@@ -826,7 +675,7 @@ void viafb_set_iga_path(void)
826 viaparinfo->lvds_setting_info->iga_path = IGA2; 675 viaparinfo->lvds_setting_info->iga_path = IGA2;
827 viaparinfo->lvds_setting_info2->iga_path = IGA2; 676 viaparinfo->lvds_setting_info2->iga_path = IGA2;
828 } else if (viafb_CRT_ON) { 677 } else if (viafb_CRT_ON) {
829 viaparinfo->crt_setting_info->iga_path = IGA1; 678 crt_iga_path = IGA1;
830 } else if (viafb_LCD_ON) { 679 } else if (viafb_LCD_ON) {
831 viaparinfo->lvds_setting_info->iga_path = IGA2; 680 viaparinfo->lvds_setting_info->iga_path = IGA2;
832 } else if (viafb_DVI_ON) { 681 } else if (viafb_DVI_ON) {
@@ -837,7 +686,7 @@ void viafb_set_iga_path(void)
837 viaparinfo->shared->iga1_devices = 0; 686 viaparinfo->shared->iga1_devices = 0;
838 viaparinfo->shared->iga2_devices = 0; 687 viaparinfo->shared->iga2_devices = 0;
839 if (viafb_CRT_ON) { 688 if (viafb_CRT_ON) {
840 if (viaparinfo->crt_setting_info->iga_path == IGA1) 689 if (crt_iga_path == IGA1)
841 viaparinfo->shared->iga1_devices |= VIA_CRT; 690 viaparinfo->shared->iga1_devices |= VIA_CRT;
842 else 691 else
843 viaparinfo->shared->iga2_devices |= VIA_CRT; 692 viaparinfo->shared->iga2_devices |= VIA_CRT;
@@ -875,6 +724,10 @@ void viafb_set_iga_path(void)
875 viaparinfo->chip_info-> 724 viaparinfo->chip_info->
876 lvds_chip_info2.output_interface); 725 lvds_chip_info2.output_interface);
877 } 726 }
727
728 /* looks like the OLPC has its display wired to DVP1 and LVDS2 */
729 if (machine_is_olpc())
730 viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2;
878} 731}
879 732
880static void set_color_register(u8 index, u8 red, u8 green, u8 blue) 733static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
@@ -1162,25 +1015,17 @@ void via_odev_to_seq(struct seq_file *m, u32 odev)
1162 1015
1163static void load_fix_bit_crtc_reg(void) 1016static void load_fix_bit_crtc_reg(void)
1164{ 1017{
1018 viafb_unlock_crt();
1019
1165 /* always set to 1 */ 1020 /* always set to 1 */
1166 viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7); 1021 viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
1167 /* line compare should set all bits = 1 (extend modes) */ 1022 /* line compare should set all bits = 1 (extend modes) */
1168 viafb_write_reg(CR18, VIACR, 0xff);
1169 /* line compare should set all bits = 1 (extend modes) */
1170 viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4);
1171 /* line compare should set all bits = 1 (extend modes) */
1172 viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6);
1173 /* line compare should set all bits = 1 (extend modes) */
1174 viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4); 1023 viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
1175 /* line compare should set all bits = 1 (extend modes) */ 1024 /* line compare should set all bits = 1 (extend modes) */
1176 viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2); 1025 viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
1177 /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */ 1026 /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
1178 /* extend mode always set to e3h */ 1027
1179 viafb_write_reg(CR17, VIACR, 0xe3); 1028 viafb_lock_crt();
1180 /* extend mode always set to 0h */
1181 viafb_write_reg(CR08, VIACR, 0x00);
1182 /* extend mode always set to 0h */
1183 viafb_write_reg(CR14, VIACR, 0x00);
1184 1029
1185 /* If K8M800, enable Prefetch Mode. */ 1030 /* If K8M800, enable Prefetch Mode. */
1186 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) 1031 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
@@ -1601,69 +1446,54 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1601 1446
1602} 1447}
1603 1448
1604static u32 cle266_encode_pll(struct pll_config pll) 1449static struct via_pll_config get_pll_config(struct pll_limit *limits, int size,
1605{
1606 return (pll.multiplier << 8)
1607 | (pll.rshift << 6)
1608 | pll.divisor;
1609}
1610
1611static u32 k800_encode_pll(struct pll_config pll)
1612{
1613 return ((pll.divisor - 2) << 16)
1614 | (pll.rshift << 10)
1615 | (pll.multiplier - 2);
1616}
1617
1618static u32 vx855_encode_pll(struct pll_config pll)
1619{
1620 return (pll.divisor << 16)
1621 | (pll.rshift << 10)
1622 | pll.multiplier;
1623}
1624
1625static inline u32 get_pll_internal_frequency(u32 ref_freq,
1626 struct pll_config pll)
1627{
1628 return ref_freq / pll.divisor * pll.multiplier;
1629}
1630
1631static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll)
1632{
1633 return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift;
1634}
1635
1636static struct pll_config get_pll_config(struct pll_config *config, int size,
1637 int clk) 1450 int clk)
1638{ 1451{
1639 struct pll_config best = config[0]; 1452 struct via_pll_config cur, up, down, best = {0, 1, 0};
1640 const u32 f0 = 14318180; /* X1 frequency */ 1453 const u32 f0 = 14318180; /* X1 frequency */
1641 int i; 1454 int i, f;
1642 1455
1643 for (i = 1; i < size; i++) { 1456 for (i = 0; i < size; i++) {
1644 if (abs(get_pll_output_frequency(f0, config[i]) - clk) 1457 cur.rshift = limits[i].rshift;
1645 < abs(get_pll_output_frequency(f0, best) - clk)) 1458 cur.divisor = limits[i].divisor;
1646 best = config[i]; 1459 cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift);
1460 f = abs(get_pll_output_frequency(f0, cur) - clk);
1461 up = down = cur;
1462 up.multiplier++;
1463 down.multiplier--;
1464 if (abs(get_pll_output_frequency(f0, up) - clk) < f)
1465 cur = up;
1466 else if (abs(get_pll_output_frequency(f0, down) - clk) < f)
1467 cur = down;
1468
1469 if (cur.multiplier < limits[i].multiplier_min)
1470 cur.multiplier = limits[i].multiplier_min;
1471 else if (cur.multiplier > limits[i].multiplier_max)
1472 cur.multiplier = limits[i].multiplier_max;
1473
1474 f = abs(get_pll_output_frequency(f0, cur) - clk);
1475 if (f < abs(get_pll_output_frequency(f0, best) - clk))
1476 best = cur;
1647 } 1477 }
1648 1478
1649 return best; 1479 return best;
1650} 1480}
1651 1481
1652u32 viafb_get_clk_value(int clk) 1482static struct via_pll_config get_best_pll_config(int clk)
1653{ 1483{
1654 u32 value = 0; 1484 struct via_pll_config config;
1655 1485
1656 switch (viaparinfo->chip_info->gfx_chip_name) { 1486 switch (viaparinfo->chip_info->gfx_chip_name) {
1657 case UNICHROME_CLE266: 1487 case UNICHROME_CLE266:
1658 case UNICHROME_K400: 1488 case UNICHROME_K400:
1659 value = cle266_encode_pll(get_pll_config(cle266_pll_config, 1489 config = get_pll_config(cle266_pll_limits,
1660 ARRAY_SIZE(cle266_pll_config), clk)); 1490 ARRAY_SIZE(cle266_pll_limits), clk);
1661 break; 1491 break;
1662 case UNICHROME_K800: 1492 case UNICHROME_K800:
1663 case UNICHROME_PM800: 1493 case UNICHROME_PM800:
1664 case UNICHROME_CN700: 1494 case UNICHROME_CN700:
1665 value = k800_encode_pll(get_pll_config(k800_pll_config, 1495 config = get_pll_config(k800_pll_limits,
1666 ARRAY_SIZE(k800_pll_config), clk)); 1496 ARRAY_SIZE(k800_pll_limits), clk);
1667 break; 1497 break;
1668 case UNICHROME_CX700: 1498 case UNICHROME_CX700:
1669 case UNICHROME_CN750: 1499 case UNICHROME_CN750:
@@ -1671,92 +1501,28 @@ u32 viafb_get_clk_value(int clk)
1671 case UNICHROME_P4M890: 1501 case UNICHROME_P4M890:
1672 case UNICHROME_P4M900: 1502 case UNICHROME_P4M900:
1673 case UNICHROME_VX800: 1503 case UNICHROME_VX800:
1674 value = k800_encode_pll(get_pll_config(cx700_pll_config, 1504 config = get_pll_config(cx700_pll_limits,
1675 ARRAY_SIZE(cx700_pll_config), clk)); 1505 ARRAY_SIZE(cx700_pll_limits), clk);
1676 break; 1506 break;
1677 case UNICHROME_VX855: 1507 case UNICHROME_VX855:
1678 case UNICHROME_VX900: 1508 case UNICHROME_VX900:
1679 value = vx855_encode_pll(get_pll_config(vx855_pll_config, 1509 config = get_pll_config(vx855_pll_limits,
1680 ARRAY_SIZE(vx855_pll_config), clk)); 1510 ARRAY_SIZE(vx855_pll_limits), clk);
1681 break; 1511 break;
1682 } 1512 }
1683 1513
1684 return value; 1514 return config;
1685} 1515}
1686 1516
1687/* Set VCLK*/ 1517/* Set VCLK*/
1688void viafb_set_vclock(u32 clk, int set_iga) 1518void viafb_set_vclock(u32 clk, int set_iga)
1689{ 1519{
1690 /* H.W. Reset : ON */ 1520 struct via_pll_config config = get_best_pll_config(clk);
1691 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1692 1521
1693 if (set_iga == IGA1) { 1522 if (set_iga == IGA1)
1694 /* Change D,N FOR VCLK */ 1523 clock.set_primary_pll(config);
1695 switch (viaparinfo->chip_info->gfx_chip_name) { 1524 if (set_iga == IGA2)
1696 case UNICHROME_CLE266: 1525 clock.set_secondary_pll(config);
1697 case UNICHROME_K400:
1698 via_write_reg(VIASR, SR46, (clk & 0x00FF));
1699 via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8);
1700 break;
1701
1702 case UNICHROME_K800:
1703 case UNICHROME_PM800:
1704 case UNICHROME_CN700:
1705 case UNICHROME_CX700:
1706 case UNICHROME_CN750:
1707 case UNICHROME_K8M890:
1708 case UNICHROME_P4M890:
1709 case UNICHROME_P4M900:
1710 case UNICHROME_VX800:
1711 case UNICHROME_VX855:
1712 case UNICHROME_VX900:
1713 via_write_reg(VIASR, SR44, (clk & 0x0000FF));
1714 via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8);
1715 via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16);
1716 break;
1717 }
1718 }
1719
1720 if (set_iga == IGA2) {
1721 /* Change D,N FOR LCK */
1722 switch (viaparinfo->chip_info->gfx_chip_name) {
1723 case UNICHROME_CLE266:
1724 case UNICHROME_K400:
1725 via_write_reg(VIASR, SR44, (clk & 0x00FF));
1726 via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8);
1727 break;
1728
1729 case UNICHROME_K800:
1730 case UNICHROME_PM800:
1731 case UNICHROME_CN700:
1732 case UNICHROME_CX700:
1733 case UNICHROME_CN750:
1734 case UNICHROME_K8M890:
1735 case UNICHROME_P4M890:
1736 case UNICHROME_P4M900:
1737 case UNICHROME_VX800:
1738 case UNICHROME_VX855:
1739 case UNICHROME_VX900:
1740 via_write_reg(VIASR, SR4A, (clk & 0x0000FF));
1741 via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8);
1742 via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16);
1743 break;
1744 }
1745 }
1746
1747 /* H.W. Reset : OFF */
1748 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1749
1750 /* Reset PLL */
1751 if (set_iga == IGA1) {
1752 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
1753 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
1754 }
1755
1756 if (set_iga == IGA2) {
1757 viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2);
1758 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2);
1759 }
1760 1526
1761 /* Fire! */ 1527 /* Fire! */
1762 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ 1528 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
@@ -2002,7 +1768,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2002 int i; 1768 int i;
2003 int index = 0; 1769 int index = 0;
2004 int h_addr, v_addr; 1770 int h_addr, v_addr;
2005 u32 pll_D_N, clock, refresh = viafb_refresh; 1771 u32 clock, refresh = viafb_refresh;
2006 1772
2007 if (viafb_SAMM_ON && set_iga == IGA2) 1773 if (viafb_SAMM_ON && set_iga == IGA2)
2008 refresh = viafb_refresh1; 1774 refresh = viafb_refresh1;
@@ -2033,8 +1799,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2033 v_addr = crt_reg.ver_addr; 1799 v_addr = crt_reg.ver_addr;
2034 if (set_iga == IGA1) { 1800 if (set_iga == IGA1) {
2035 viafb_unlock_crt(); 1801 viafb_unlock_crt();
2036 viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */
2037 viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);
2038 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); 1802 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
2039 } 1803 }
2040 1804
@@ -2047,7 +1811,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2047 break; 1811 break;
2048 } 1812 }
2049 1813
2050 load_fix_bit_crtc_reg();
2051 viafb_lock_crt(); 1814 viafb_lock_crt();
2052 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); 1815 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
2053 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); 1816 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
@@ -2059,20 +1822,17 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2059 1822
2060 clock = crt_reg.hor_total * crt_reg.ver_total 1823 clock = crt_reg.hor_total * crt_reg.ver_total
2061 * crt_table[index].refresh_rate; 1824 * crt_table[index].refresh_rate;
2062 pll_D_N = viafb_get_clk_value(clock); 1825 viafb_set_vclock(clock, set_iga);
2063 DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
2064 viafb_set_vclock(pll_D_N, set_iga);
2065 1826
2066} 1827}
2067 1828
2068void __devinit viafb_init_chip_info(int chip_type) 1829void __devinit viafb_init_chip_info(int chip_type)
2069{ 1830{
1831 via_clock_init(&clock, chip_type);
2070 init_gfx_chip_info(chip_type); 1832 init_gfx_chip_info(chip_type);
2071 init_tmds_chip_info(); 1833 init_tmds_chip_info();
2072 init_lvds_chip_info(); 1834 init_lvds_chip_info();
2073 1835
2074 viaparinfo->crt_setting_info->iga_path = IGA1;
2075
2076 /*Set IGA path for each device */ 1836 /*Set IGA path for each device */
2077 viafb_set_iga_path(); 1837 viafb_set_iga_path();
2078 1838
@@ -2354,6 +2114,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2354 outb(0x00, VIAAR); 2114 outb(0x00, VIAAR);
2355 2115
2356 /* Write Common Setting for Video Mode */ 2116 /* Write Common Setting for Video Mode */
2117 viafb_write_regx(common_vga, ARRAY_SIZE(common_vga));
2357 switch (viaparinfo->chip_info->gfx_chip_name) { 2118 switch (viaparinfo->chip_info->gfx_chip_name) {
2358 case UNICHROME_CLE266: 2119 case UNICHROME_CLE266:
2359 viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs); 2120 viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
@@ -2400,9 +2161,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2400 2161
2401 viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); 2162 viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
2402 2163
2403 /* Write CRTC */
2404 viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
2405
2406 /* Write Graphic Controller */ 2164 /* Write Graphic Controller */
2407 for (i = 0; i < StdGR; i++) 2165 for (i = 0; i < StdGR; i++)
2408 via_write_reg(VIAGR, i, VPIT.GR[i]); 2166 via_write_reg(VIAGR, i, VPIT.GR[i]);
@@ -2432,6 +2190,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2432 } 2190 }
2433 } 2191 }
2434 2192
2193 load_fix_bit_crtc_reg();
2435 via_set_primary_pitch(viafbinfo->fix.line_length); 2194 via_set_primary_pitch(viafbinfo->fix.line_length);
2436 via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length 2195 via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
2437 : viafbinfo->fix.line_length); 2196 : viafbinfo->fix.line_length);
@@ -2451,15 +2210,15 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2451 2210
2452 /* CRT set mode */ 2211 /* CRT set mode */
2453 if (viafb_CRT_ON) { 2212 if (viafb_CRT_ON) {
2454 if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == 2213 if (viafb_SAMM_ON &&
2455 IGA2)) { 2214 viaparinfo->shared->iga2_devices & VIA_CRT) {
2456 viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, 2215 viafb_fill_crtc_timing(crt_timing1, vmode_tbl1,
2457 video_bpp1 / 8, 2216 video_bpp1 / 8, IGA2);
2458 viaparinfo->crt_setting_info->iga_path);
2459 } else { 2217 } else {
2460 viafb_fill_crtc_timing(crt_timing, vmode_tbl, 2218 viafb_fill_crtc_timing(crt_timing, vmode_tbl,
2461 video_bpp / 8, 2219 video_bpp / 8,
2462 viaparinfo->crt_setting_info->iga_path); 2220 (viaparinfo->shared->iga1_devices & VIA_CRT)
2221 ? IGA1 : IGA2);
2463 } 2222 }
2464 2223
2465 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode 2224 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
@@ -2557,6 +2316,33 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2557 get_sync(viafbinfo1)); 2316 get_sync(viafbinfo1));
2558 } 2317 }
2559 2318
2319 clock.set_engine_pll_state(VIA_STATE_ON);
2320 clock.set_primary_clock_source(VIA_CLKSRC_X1, true);
2321 clock.set_secondary_clock_source(VIA_CLKSRC_X1, true);
2322
2323#ifdef CONFIG_FB_VIA_X_COMPATIBILITY
2324 clock.set_primary_pll_state(VIA_STATE_ON);
2325 clock.set_primary_clock_state(VIA_STATE_ON);
2326 clock.set_secondary_pll_state(VIA_STATE_ON);
2327 clock.set_secondary_clock_state(VIA_STATE_ON);
2328#else
2329 if (viaparinfo->shared->iga1_devices) {
2330 clock.set_primary_pll_state(VIA_STATE_ON);
2331 clock.set_primary_clock_state(VIA_STATE_ON);
2332 } else {
2333 clock.set_primary_pll_state(VIA_STATE_OFF);
2334 clock.set_primary_clock_state(VIA_STATE_OFF);
2335 }
2336
2337 if (viaparinfo->shared->iga2_devices) {
2338 clock.set_secondary_pll_state(VIA_STATE_ON);
2339 clock.set_secondary_clock_state(VIA_STATE_ON);
2340 } else {
2341 clock.set_secondary_pll_state(VIA_STATE_OFF);
2342 clock.set_secondary_clock_state(VIA_STATE_OFF);
2343 }
2344#endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/
2345
2560 via_set_state(devices, VIA_STATE_ON); 2346 via_set_state(devices, VIA_STATE_ON);
2561 device_screen_on(); 2347 device_screen_on();
2562 return 1; 2348 return 1;
@@ -2598,8 +2384,12 @@ int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2598 best = &vmode->crtc[i]; 2384 best = &vmode->crtc[i];
2599 } 2385 }
2600 2386
2601 if (abs(best->refresh_rate - long_refresh) > 3) 2387 if (abs(best->refresh_rate - long_refresh) > 3) {
2602 return 60; 2388 if (hres == 1200 && vres == 900)
2389 return 49; /* OLPC DCON only supports 50 Hz */
2390 else
2391 return 60;
2392 }
2603 2393
2604 return best->refresh_rate; 2394 return best->refresh_rate;
2605} 2395}
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 8858593405aa..c7239eb83bae 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -732,20 +732,13 @@ struct _lcd_scaling_factor {
732 struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; 732 struct _lcd_ver_scaling_factor lcd_ver_scaling_factor;
733}; 733};
734 734
735struct pll_config { 735struct pll_limit {
736 u16 multiplier; 736 u16 multiplier_min;
737 u16 multiplier_max;
737 u8 divisor; 738 u8 divisor;
738 u8 rshift; 739 u8 rshift;
739}; 740};
740 741
741struct pll_map {
742 u32 clk;
743 struct pll_config cle266_pll;
744 struct pll_config k800_pll;
745 struct pll_config cx700_pll;
746 struct pll_config vx855_pll;
747};
748
749struct rgbLUT { 742struct rgbLUT {
750 u8 red; 743 u8 red;
751 u8 green; 744 u8 green;
@@ -910,7 +903,6 @@ struct via_device_mapping {
910 const char *name; 903 const char *name;
911}; 904};
912 905
913extern unsigned int viafb_second_virtual_xres;
914extern int viafb_SAMM_ON; 906extern int viafb_SAMM_ON;
915extern int viafb_dual_fb; 907extern int viafb_dual_fb;
916extern int viafb_LCD2_ON; 908extern int viafb_LCD2_ON;
@@ -936,7 +928,6 @@ void viafb_lock_crt(void);
936void viafb_unlock_crt(void); 928void viafb_unlock_crt(void);
937void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); 929void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
938void viafb_write_regx(struct io_reg RegTable[], int ItemNum); 930void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
939u32 viafb_get_clk_value(int clk);
940void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); 931void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
941void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ 932void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
942 *p_gfx_dpa_setting); 933 *p_gfx_dpa_setting);
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 64bc7e763103..6e06981d638b 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -48,7 +48,6 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
48 {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } } 48 {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }
49}; 49};
50 50
51static int check_lvds_chip(int device_id_subaddr, int device_id);
52static bool lvds_identify_integratedlvds(void); 51static bool lvds_identify_integratedlvds(void);
53static void __devinit fp_id_to_vindex(int panel_id); 52static void __devinit fp_id_to_vindex(int panel_id);
54static int lvds_register_read(int index); 53static int lvds_register_read(int index);
@@ -84,12 +83,9 @@ static struct display_timing lcd_centering_timging(struct display_timing
84 mode_crt_reg, 83 mode_crt_reg,
85 struct display_timing panel_crt_reg); 84 struct display_timing panel_crt_reg);
86 85
87static int check_lvds_chip(int device_id_subaddr, int device_id) 86static inline bool check_lvds_chip(int device_id_subaddr, int device_id)
88{ 87{
89 if (lvds_register_read(device_id_subaddr) == device_id) 88 return lvds_register_read(device_id_subaddr) == device_id;
90 return OK;
91 else
92 return FAIL;
93} 89}
94 90
95void __devinit viafb_init_lcd_size(void) 91void __devinit viafb_init_lcd_size(void)
@@ -150,7 +146,7 @@ static bool lvds_identify_integratedlvds(void)
150 return true; 146 return true;
151} 147}
152 148
153int __devinit viafb_lvds_trasmitter_identify(void) 149bool __devinit viafb_lvds_trasmitter_identify(void)
154{ 150{
155 if (viafb_lvds_identify_vt1636(VIA_PORT_31)) { 151 if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
156 viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31; 152 viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
@@ -175,20 +171,20 @@ int __devinit viafb_lvds_trasmitter_identify(void)
175 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 171 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
176 VT1631_LVDS_I2C_ADDR; 172 VT1631_LVDS_I2C_ADDR;
177 173
178 if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) { 174 if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID)) {
179 DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n"); 175 DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");
180 DEBUG_MSG(KERN_INFO "\n %2d", 176 DEBUG_MSG(KERN_INFO "\n %2d",
181 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); 177 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
182 DEBUG_MSG(KERN_INFO "\n %2d", 178 DEBUG_MSG(KERN_INFO "\n %2d",
183 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); 179 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
184 return OK; 180 return true;
185 } 181 }
186 182
187 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 183 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
188 NON_LVDS_TRANSMITTER; 184 NON_LVDS_TRANSMITTER;
189 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 185 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
190 VT1631_LVDS_I2C_ADDR; 186 VT1631_LVDS_I2C_ADDR;
191 return FAIL; 187 return false;
192} 188}
193 189
194static void __devinit fp_id_to_vindex(int panel_id) 190static void __devinit fp_id_to_vindex(int panel_id)
@@ -562,7 +558,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
562 int set_vres = plvds_setting_info->v_active; 558 int set_vres = plvds_setting_info->v_active;
563 int panel_hres = plvds_setting_info->lcd_panel_hres; 559 int panel_hres = plvds_setting_info->lcd_panel_hres;
564 int panel_vres = plvds_setting_info->lcd_panel_vres; 560 int panel_vres = plvds_setting_info->lcd_panel_vres;
565 u32 pll_D_N, clock; 561 u32 clock;
566 struct display_timing mode_crt_reg, panel_crt_reg; 562 struct display_timing mode_crt_reg, panel_crt_reg;
567 struct crt_mode_table *panel_crt_table = NULL; 563 struct crt_mode_table *panel_crt_table = NULL;
568 struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, 564 struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres,
@@ -613,10 +609,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
613 viafb_load_FIFO_reg(set_iga, set_hres, set_vres); 609 viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
614 610
615 fill_lcd_format(); 611 fill_lcd_format();
616 612 viafb_set_vclock(clock, set_iga);
617 pll_D_N = viafb_get_clk_value(clock);
618 DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
619 viafb_set_vclock(pll_D_N, set_iga);
620 lcd_patch_skew(plvds_setting_info, plvds_chip_info); 613 lcd_patch_skew(plvds_setting_info, plvds_chip_info);
621 614
622 /* If K8M800, enable LCD Prefetch Mode. */ 615 /* If K8M800, enable LCD Prefetch Mode. */
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
index c7909fe29550..75f60a655b0e 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/via/lcd.h
@@ -79,7 +79,7 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
79void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, 79void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
80 struct lvds_setting_information *plvds_setting_info, 80 struct lvds_setting_information *plvds_setting_info,
81 struct lvds_chip_information *plvds_chip_info); 81 struct lvds_chip_information *plvds_chip_info);
82int __devinit viafb_lvds_trasmitter_identify(void); 82bool __devinit viafb_lvds_trasmitter_identify(void);
83void viafb_init_lvds_output_interface(struct lvds_chip_information 83void viafb_init_lvds_output_interface(struct lvds_chip_information
84 *plvds_chip_info, 84 *plvds_chip_info,
85 struct lvds_setting_information 85 struct lvds_setting_information
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 4b7831f0d012..61b0bd596b85 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -22,14 +22,6 @@
22#ifndef __SHARE_H__ 22#ifndef __SHARE_H__
23#define __SHARE_H__ 23#define __SHARE_H__
24 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 */ 25/* Define Bit Field */
34#define BIT0 0x01 26#define BIT0 0x01
35#define BIT1 0x02 27#define BIT1 0x02
@@ -290,6 +282,7 @@
290#define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10 282#define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10
291 283
292/* Definition Refresh Rate */ 284/* Definition Refresh Rate */
285#define REFRESH_49 49
293#define REFRESH_50 50 286#define REFRESH_50 50
294#define REFRESH_60 60 287#define REFRESH_60 60
295#define REFRESH_75 75 288#define REFRESH_75 75
@@ -575,10 +568,6 @@
575#define M1280X720_R50_HSP NEGATIVE 568#define M1280X720_R50_HSP NEGATIVE
576#define M1280X720_R50_VSP POSITIVE 569#define M1280X720_R50_VSP POSITIVE
577 570
578/* 1280x720@60 Sync Polarity (CEA Mode) */
579#define M1280X720_CEA_R60_HSP POSITIVE
580#define M1280X720_CEA_R60_VSP POSITIVE
581
582/* 1440x900@60 Sync Polarity (CVT Mode) */ 571/* 1440x900@60 Sync Polarity (CVT Mode) */
583#define M1440X900_R60_HSP NEGATIVE 572#define M1440X900_R60_HSP NEGATIVE
584#define M1440X900_R60_VSP POSITIVE 573#define M1440X900_R60_VSP POSITIVE
@@ -619,10 +608,6 @@
619#define M1920X1200_RB_R60_HSP POSITIVE 608#define M1920X1200_RB_R60_HSP POSITIVE
620#define M1920X1200_RB_R60_VSP NEGATIVE 609#define M1920X1200_RB_R60_VSP NEGATIVE
621 610
622/* 1920x1080@60 Sync Polarity (CEA Mode) */
623#define M1920X1080_CEA_R60_HSP POSITIVE
624#define M1920X1080_CEA_R60_VSP POSITIVE
625
626/* 2048x1536@60 Sync Polarity (CVT Mode) */ 611/* 2048x1536@60 Sync Polarity (CVT Mode) */
627#define M2048x1536_R60_HSP NEGATIVE 612#define M2048x1536_R60_HSP NEGATIVE
628#define M2048x1536_R60_VSP POSITIVE 613#define M2048x1536_R60_VSP POSITIVE
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c
index 6723d6910cde..eb112b621735 100644
--- a/drivers/video/via/via-core.c
+++ b/drivers/video/via/via-core.c
@@ -505,7 +505,14 @@ static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev)
505 ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type); 505 ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type);
506 if (ret < 0) 506 if (ret < 0)
507 goto out_unmap; 507 goto out_unmap;
508 vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len); 508
509 /* try to map less memory on failure, 8 MB should be still enough */
510 for (; vdev->fbmem_len >= 8 << 20; vdev->fbmem_len /= 2) {
511 vdev->fbmem = ioremap_wc(vdev->fbmem_start, vdev->fbmem_len);
512 if (vdev->fbmem)
513 break;
514 }
515
509 if (vdev->fbmem == NULL) { 516 if (vdev->fbmem == NULL) {
510 ret = -ENOMEM; 517 ret = -ENOMEM;
511 goto out_unmap; 518 goto out_unmap;
diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c
new file mode 100644
index 000000000000..af8f26b643c1
--- /dev/null
+++ b/drivers/video/via/via_clock.c
@@ -0,0 +1,349 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation;
9 * either version 2, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
13 * the implied warranty of MERCHANTABILITY or FITNESS FOR
14 * A PARTICULAR PURPOSE.See the GNU General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22/*
23 * clock and PLL management functions
24 */
25
26#include <linux/kernel.h>
27#include <linux/via-core.h>
28#include "via_clock.h"
29#include "global.h"
30#include "debug.h"
31
32const char *via_slap = "Please slap VIA Technologies to motivate them "
33 "releasing full documentation for your platform!\n";
34
35static inline u32 cle266_encode_pll(struct via_pll_config pll)
36{
37 return (pll.multiplier << 8)
38 | (pll.rshift << 6)
39 | pll.divisor;
40}
41
42static inline u32 k800_encode_pll(struct via_pll_config pll)
43{
44 return ((pll.divisor - 2) << 16)
45 | (pll.rshift << 10)
46 | (pll.multiplier - 2);
47}
48
49static inline u32 vx855_encode_pll(struct via_pll_config pll)
50{
51 return (pll.divisor << 16)
52 | (pll.rshift << 10)
53 | pll.multiplier;
54}
55
56static inline void cle266_set_primary_pll_encoded(u32 data)
57{
58 via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */
59 via_write_reg(VIASR, 0x46, data & 0xFF);
60 via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF);
61 via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */
62}
63
64static inline void k800_set_primary_pll_encoded(u32 data)
65{
66 via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */
67 via_write_reg(VIASR, 0x44, data & 0xFF);
68 via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF);
69 via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF);
70 via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */
71}
72
73static inline void cle266_set_secondary_pll_encoded(u32 data)
74{
75 via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */
76 via_write_reg(VIASR, 0x44, data & 0xFF);
77 via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF);
78 via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */
79}
80
81static inline void k800_set_secondary_pll_encoded(u32 data)
82{
83 via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */
84 via_write_reg(VIASR, 0x4A, data & 0xFF);
85 via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF);
86 via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF);
87 via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */
88}
89
90static inline void set_engine_pll_encoded(u32 data)
91{
92 via_write_reg_mask(VIASR, 0x40, 0x01, 0x01); /* enable reset */
93 via_write_reg(VIASR, 0x47, data & 0xFF);
94 via_write_reg(VIASR, 0x48, (data >> 8) & 0xFF);
95 via_write_reg(VIASR, 0x49, (data >> 16) & 0xFF);
96 via_write_reg_mask(VIASR, 0x40, 0x00, 0x01); /* disable reset */
97}
98
99static void cle266_set_primary_pll(struct via_pll_config config)
100{
101 cle266_set_primary_pll_encoded(cle266_encode_pll(config));
102}
103
104static void k800_set_primary_pll(struct via_pll_config config)
105{
106 k800_set_primary_pll_encoded(k800_encode_pll(config));
107}
108
109static void vx855_set_primary_pll(struct via_pll_config config)
110{
111 k800_set_primary_pll_encoded(vx855_encode_pll(config));
112}
113
114static void cle266_set_secondary_pll(struct via_pll_config config)
115{
116 cle266_set_secondary_pll_encoded(cle266_encode_pll(config));
117}
118
119static void k800_set_secondary_pll(struct via_pll_config config)
120{
121 k800_set_secondary_pll_encoded(k800_encode_pll(config));
122}
123
124static void vx855_set_secondary_pll(struct via_pll_config config)
125{
126 k800_set_secondary_pll_encoded(vx855_encode_pll(config));
127}
128
129static void k800_set_engine_pll(struct via_pll_config config)
130{
131 set_engine_pll_encoded(k800_encode_pll(config));
132}
133
134static void vx855_set_engine_pll(struct via_pll_config config)
135{
136 set_engine_pll_encoded(vx855_encode_pll(config));
137}
138
139static void set_primary_pll_state(u8 state)
140{
141 u8 value;
142
143 switch (state) {
144 case VIA_STATE_ON:
145 value = 0x20;
146 break;
147 case VIA_STATE_OFF:
148 value = 0x00;
149 break;
150 default:
151 return;
152 }
153
154 via_write_reg_mask(VIASR, 0x2D, value, 0x30);
155}
156
157static void set_secondary_pll_state(u8 state)
158{
159 u8 value;
160
161 switch (state) {
162 case VIA_STATE_ON:
163 value = 0x08;
164 break;
165 case VIA_STATE_OFF:
166 value = 0x00;
167 break;
168 default:
169 return;
170 }
171
172 via_write_reg_mask(VIASR, 0x2D, value, 0x0C);
173}
174
175static void set_engine_pll_state(u8 state)
176{
177 u8 value;
178
179 switch (state) {
180 case VIA_STATE_ON:
181 value = 0x02;
182 break;
183 case VIA_STATE_OFF:
184 value = 0x00;
185 break;
186 default:
187 return;
188 }
189
190 via_write_reg_mask(VIASR, 0x2D, value, 0x03);
191}
192
193static void set_primary_clock_state(u8 state)
194{
195 u8 value;
196
197 switch (state) {
198 case VIA_STATE_ON:
199 value = 0x20;
200 break;
201 case VIA_STATE_OFF:
202 value = 0x00;
203 break;
204 default:
205 return;
206 }
207
208 via_write_reg_mask(VIASR, 0x1B, value, 0x30);
209}
210
211static void set_secondary_clock_state(u8 state)
212{
213 u8 value;
214
215 switch (state) {
216 case VIA_STATE_ON:
217 value = 0x80;
218 break;
219 case VIA_STATE_OFF:
220 value = 0x00;
221 break;
222 default:
223 return;
224 }
225
226 via_write_reg_mask(VIASR, 0x1B, value, 0xC0);
227}
228
229static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll)
230{
231 u8 data = 0;
232
233 switch (source) {
234 case VIA_CLKSRC_X1:
235 data = 0x00;
236 break;
237 case VIA_CLKSRC_TVX1:
238 data = 0x02;
239 break;
240 case VIA_CLKSRC_TVPLL:
241 data = 0x04; /* 0x06 should be the same */
242 break;
243 case VIA_CLKSRC_DVP1TVCLKR:
244 data = 0x0A;
245 break;
246 case VIA_CLKSRC_CAP0:
247 data = 0xC;
248 break;
249 case VIA_CLKSRC_CAP1:
250 data = 0x0E;
251 break;
252 }
253
254 if (!use_pll)
255 data |= 1;
256
257 return data;
258}
259
260static void set_primary_clock_source(enum via_clksrc source, bool use_pll)
261{
262 u8 data = set_clock_source_common(source, use_pll) << 4;
263 via_write_reg_mask(VIACR, 0x6C, data, 0xF0);
264}
265
266static void set_secondary_clock_source(enum via_clksrc source, bool use_pll)
267{
268 u8 data = set_clock_source_common(source, use_pll);
269 via_write_reg_mask(VIACR, 0x6C, data, 0x0F);
270}
271
272static void dummy_set_clock_state(u8 state)
273{
274 printk(KERN_INFO "Using undocumented set clock state.\n%s", via_slap);
275}
276
277static void dummy_set_clock_source(enum via_clksrc source, bool use_pll)
278{
279 printk(KERN_INFO "Using undocumented set clock source.\n%s", via_slap);
280}
281
282static void dummy_set_pll_state(u8 state)
283{
284 printk(KERN_INFO "Using undocumented set PLL state.\n%s", via_slap);
285}
286
287static void dummy_set_pll(struct via_pll_config config)
288{
289 printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap);
290}
291
292void via_clock_init(struct via_clock *clock, int gfx_chip)
293{
294 switch (gfx_chip) {
295 case UNICHROME_CLE266:
296 case UNICHROME_K400:
297 clock->set_primary_clock_state = dummy_set_clock_state;
298 clock->set_primary_clock_source = dummy_set_clock_source;
299 clock->set_primary_pll_state = dummy_set_pll_state;
300 clock->set_primary_pll = cle266_set_primary_pll;
301
302 clock->set_secondary_clock_state = dummy_set_clock_state;
303 clock->set_secondary_clock_source = dummy_set_clock_source;
304 clock->set_secondary_pll_state = dummy_set_pll_state;
305 clock->set_secondary_pll = cle266_set_secondary_pll;
306
307 clock->set_engine_pll_state = dummy_set_pll_state;
308 clock->set_engine_pll = dummy_set_pll;
309 break;
310 case UNICHROME_K800:
311 case UNICHROME_PM800:
312 case UNICHROME_CN700:
313 case UNICHROME_CX700:
314 case UNICHROME_CN750:
315 case UNICHROME_K8M890:
316 case UNICHROME_P4M890:
317 case UNICHROME_P4M900:
318 case UNICHROME_VX800:
319 clock->set_primary_clock_state = set_primary_clock_state;
320 clock->set_primary_clock_source = set_primary_clock_source;
321 clock->set_primary_pll_state = set_primary_pll_state;
322 clock->set_primary_pll = k800_set_primary_pll;
323
324 clock->set_secondary_clock_state = set_secondary_clock_state;
325 clock->set_secondary_clock_source = set_secondary_clock_source;
326 clock->set_secondary_pll_state = set_secondary_pll_state;
327 clock->set_secondary_pll = k800_set_secondary_pll;
328
329 clock->set_engine_pll_state = set_engine_pll_state;
330 clock->set_engine_pll = k800_set_engine_pll;
331 break;
332 case UNICHROME_VX855:
333 case UNICHROME_VX900:
334 clock->set_primary_clock_state = set_primary_clock_state;
335 clock->set_primary_clock_source = set_primary_clock_source;
336 clock->set_primary_pll_state = set_primary_pll_state;
337 clock->set_primary_pll = vx855_set_primary_pll;
338
339 clock->set_secondary_clock_state = set_secondary_clock_state;
340 clock->set_secondary_clock_source = set_secondary_clock_source;
341 clock->set_secondary_pll_state = set_secondary_pll_state;
342 clock->set_secondary_pll = vx855_set_secondary_pll;
343
344 clock->set_engine_pll_state = set_engine_pll_state;
345 clock->set_engine_pll = vx855_set_engine_pll;
346 break;
347
348 }
349}
diff --git a/drivers/video/via/via_clock.h b/drivers/video/via/via_clock.h
new file mode 100644
index 000000000000..88714ae0d157
--- /dev/null
+++ b/drivers/video/via/via_clock.h
@@ -0,0 +1,76 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation;
9 * either version 2, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
13 * the implied warranty of MERCHANTABILITY or FITNESS FOR
14 * A PARTICULAR PURPOSE.See the GNU General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22/*
23 * clock and PLL management functions
24 */
25
26#ifndef __VIA_CLOCK_H__
27#define __VIA_CLOCK_H__
28
29#include <linux/types.h>
30
31enum via_clksrc {
32 VIA_CLKSRC_X1 = 0,
33 VIA_CLKSRC_TVX1,
34 VIA_CLKSRC_TVPLL,
35 VIA_CLKSRC_DVP1TVCLKR,
36 VIA_CLKSRC_CAP0,
37 VIA_CLKSRC_CAP1,
38};
39
40struct via_pll_config {
41 u16 multiplier;
42 u8 divisor;
43 u8 rshift;
44};
45
46struct via_clock {
47 void (*set_primary_clock_state)(u8 state);
48 void (*set_primary_clock_source)(enum via_clksrc src, bool use_pll);
49 void (*set_primary_pll_state)(u8 state);
50 void (*set_primary_pll)(struct via_pll_config config);
51
52 void (*set_secondary_clock_state)(u8 state);
53 void (*set_secondary_clock_source)(enum via_clksrc src, bool use_pll);
54 void (*set_secondary_pll_state)(u8 state);
55 void (*set_secondary_pll)(struct via_pll_config config);
56
57 void (*set_engine_pll_state)(u8 state);
58 void (*set_engine_pll)(struct via_pll_config config);
59};
60
61
62static inline u32 get_pll_internal_frequency(u32 ref_freq,
63 struct via_pll_config pll)
64{
65 return ref_freq / pll.divisor * pll.multiplier;
66}
67
68static inline u32 get_pll_output_frequency(u32 ref_freq,
69 struct via_pll_config pll)
70{
71 return get_pll_internal_frequency(ref_freq, pll) >> pll.rshift;
72}
73
74void via_clock_init(struct via_clock *clock, int gfx_chip);
75
76#endif /* __VIA_CLOCK_H__ */
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index a542bed086e2..cf43c80d27f6 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/stat.h> 25#include <linux/stat.h>
26#include <linux/via-core.h> 26#include <linux/via-core.h>
27#include <asm/olpc.h>
27 28
28#define _MASTER_FILE 29#define _MASTER_FILE
29#include "global.h" 30#include "global.h"
@@ -37,6 +38,8 @@ static char *viafb_mode1;
37static int viafb_bpp = 32; 38static int viafb_bpp = 32;
38static int viafb_bpp1 = 32; 39static int viafb_bpp1 = 32;
39 40
41static unsigned int viafb_second_xres = 640;
42static unsigned int viafb_second_yres = 480;
40static unsigned int viafb_second_offset; 43static unsigned int viafb_second_offset;
41static int viafb_second_size; 44static int viafb_second_size;
42 45
@@ -440,8 +443,8 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
440 if (viafb_SAMM_ON == 1) { 443 if (viafb_SAMM_ON == 1) {
441 u.viamode.xres_sec = viafb_second_xres; 444 u.viamode.xres_sec = viafb_second_xres;
442 u.viamode.yres_sec = viafb_second_yres; 445 u.viamode.yres_sec = viafb_second_yres;
443 u.viamode.virtual_xres_sec = viafb_second_virtual_xres; 446 u.viamode.virtual_xres_sec = viafb_dual_fb ? viafbinfo1->var.xres_virtual : viafbinfo->var.xres_virtual;
444 u.viamode.virtual_yres_sec = viafb_second_virtual_yres; 447 u.viamode.virtual_yres_sec = viafb_dual_fb ? viafbinfo1->var.yres_virtual : viafbinfo->var.yres_virtual;
445 u.viamode.refresh_sec = viafb_refresh1; 448 u.viamode.refresh_sec = viafb_refresh1;
446 u.viamode.bpp_sec = viafb_bpp1; 449 u.viamode.bpp_sec = viafb_bpp1;
447 } else { 450 } else {
@@ -930,10 +933,8 @@ static int get_primary_device(void)
930 /* Rule: device on iga1 path are the primary device. */ 933 /* Rule: device on iga1 path are the primary device. */
931 if (viafb_SAMM_ON) { 934 if (viafb_SAMM_ON) {
932 if (viafb_CRT_ON) { 935 if (viafb_CRT_ON) {
933 if (viaparinfo->crt_setting_info->iga_path == IGA1) { 936 if (viaparinfo->shared->iga1_devices & VIA_CRT) {
934 DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", 937 DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", IGA1);
935 viaparinfo->
936 crt_setting_info->iga_path);
937 primary_device = CRT_Device; 938 primary_device = CRT_Device;
938 } 939 }
939 } 940 }
@@ -1011,8 +1012,13 @@ static int __init parse_active_dev(void)
1011 /* Note: The previous of active_dev is primary device, 1012 /* Note: The previous of active_dev is primary device,
1012 and the following is secondary device. */ 1013 and the following is secondary device. */
1013 if (!viafb_active_dev) { 1014 if (!viafb_active_dev) {
1014 viafb_CRT_ON = STATE_ON; 1015 if (machine_is_olpc()) { /* LCD only */
1015 viafb_SAMM_ON = STATE_OFF; 1016 viafb_LCD_ON = STATE_ON;
1017 viafb_SAMM_ON = STATE_OFF;
1018 } else {
1019 viafb_CRT_ON = STATE_ON;
1020 viafb_SAMM_ON = STATE_OFF;
1021 }
1016 } else if (!strcmp(viafb_active_dev, "CRT+DVI")) { 1022 } else if (!strcmp(viafb_active_dev, "CRT+DVI")) {
1017 /* CRT+DVI */ 1023 /* CRT+DVI */
1018 viafb_CRT_ON = STATE_ON; 1024 viafb_CRT_ON = STATE_ON;
@@ -1665,8 +1671,13 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres)
1665 char *ptr; 1671 char *ptr;
1666 1672
1667 if (!str) { 1673 if (!str) {
1668 *xres = 640; 1674 if (machine_is_olpc()) {
1669 *yres = 480; 1675 *xres = 1200;
1676 *yres = 900;
1677 } else {
1678 *xres = 640;
1679 *yres = 480;
1680 }
1670 return 0; 1681 return 0;
1671 } 1682 }
1672 1683
@@ -1746,7 +1757,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1746 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; 1757 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info;
1747 viaparinfo->lvds_setting_info2 = 1758 viaparinfo->lvds_setting_info2 =
1748 &viaparinfo->shared->lvds_setting_info2; 1759 &viaparinfo->shared->lvds_setting_info2;
1749 viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info;
1750 viaparinfo->chip_info = &viaparinfo->shared->chip_info; 1760 viaparinfo->chip_info = &viaparinfo->shared->chip_info;
1751 1761
1752 if (viafb_dual_fb) 1762 if (viafb_dual_fb)
@@ -1793,14 +1803,10 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1793 1803
1794 parse_mode(viafb_mode, &default_xres, &default_yres); 1804 parse_mode(viafb_mode, &default_xres, &default_yres);
1795 vmode_entry = viafb_get_mode(default_xres, default_yres); 1805 vmode_entry = viafb_get_mode(default_xres, default_yres);
1796 if (viafb_SAMM_ON == 1) { 1806 if (viafb_SAMM_ON == 1)
1797 parse_mode(viafb_mode1, &viafb_second_xres, 1807 parse_mode(viafb_mode1, &viafb_second_xres,
1798 &viafb_second_yres); 1808 &viafb_second_yres);
1799 1809
1800 viafb_second_virtual_xres = viafb_second_xres;
1801 viafb_second_virtual_yres = viafb_second_yres;
1802 }
1803
1804 default_var.xres = default_xres; 1810 default_var.xres = default_xres;
1805 default_var.yres = default_yres; 1811 default_var.yres = default_yres;
1806 default_var.xres_virtual = default_xres; 1812 default_var.xres_virtual = default_xres;
@@ -1844,8 +1850,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1844 1850
1845 default_var.xres = viafb_second_xres; 1851 default_var.xres = viafb_second_xres;
1846 default_var.yres = viafb_second_yres; 1852 default_var.yres = viafb_second_yres;
1847 default_var.xres_virtual = viafb_second_virtual_xres; 1853 default_var.xres_virtual = viafb_second_xres;
1848 default_var.yres_virtual = viafb_second_virtual_yres; 1854 default_var.yres_virtual = viafb_second_yres;
1849 default_var.bits_per_pixel = viafb_bpp1; 1855 default_var.bits_per_pixel = viafb_bpp1;
1850 viafb_fill_var_timing_info(&default_var, viafb_get_refresh( 1856 viafb_fill_var_timing_info(&default_var, viafb_get_refresh(
1851 default_var.xres, default_var.yres, viafb_refresh1), 1857 default_var.xres, default_var.yres, viafb_refresh1),
@@ -1927,11 +1933,16 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev)
1927} 1933}
1928 1934
1929#ifndef MODULE 1935#ifndef MODULE
1930static int __init viafb_setup(char *options) 1936static int __init viafb_setup(void)
1931{ 1937{
1932 char *this_opt; 1938 char *this_opt;
1939 char *options;
1940
1933 DEBUG_MSG(KERN_INFO "viafb_setup!\n"); 1941 DEBUG_MSG(KERN_INFO "viafb_setup!\n");
1934 1942
1943 if (fb_get_options("viafb", &options))
1944 return -ENODEV;
1945
1935 if (!options || !*options) 1946 if (!options || !*options)
1936 return 0; 1947 return 0;
1937 1948
@@ -2005,11 +2016,16 @@ static int __init viafb_setup(char *options)
2005int __init viafb_init(void) 2016int __init viafb_init(void)
2006{ 2017{
2007 u32 dummy_x, dummy_y; 2018 u32 dummy_x, dummy_y;
2019 int r;
2020
2021 if (machine_is_olpc())
2022 /* Apply XO-1.5-specific configuration. */
2023 viafb_lcd_panel_id = 23;
2024
2008#ifndef MODULE 2025#ifndef MODULE
2009 char *option = NULL; 2026 r = viafb_setup();
2010 if (fb_get_options("viafb", &option)) 2027 if (r < 0)
2011 return -ENODEV; 2028 return r;
2012 viafb_setup(option);
2013#endif 2029#endif
2014 if (parse_mode(viafb_mode, &dummy_x, &dummy_y) 2030 if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
2015 || !viafb_get_mode(dummy_x, dummy_y) 2031 || !viafb_get_mode(dummy_x, dummy_y)
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 137996dc547e..d9440635d1d4 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -50,7 +50,6 @@ struct viafb_shared {
50 50
51 /* All the information will be needed to set engine */ 51 /* All the information will be needed to set engine */
52 struct tmds_setting_information tmds_setting_info; 52 struct tmds_setting_information tmds_setting_info;
53 struct crt_setting_information crt_setting_info;
54 struct lvds_setting_information lvds_setting_info; 53 struct lvds_setting_information lvds_setting_info;
55 struct lvds_setting_information lvds_setting_info2; 54 struct lvds_setting_information lvds_setting_info2;
56 struct chip_information chip_info; 55 struct chip_information chip_info;
@@ -79,14 +78,11 @@ struct viafb_par {
79 /* All the information will be needed to set engine */ 78 /* All the information will be needed to set engine */
80 /* depreciated, use the ones in shared directly */ 79 /* depreciated, use the ones in shared directly */
81 struct tmds_setting_information *tmds_setting_info; 80 struct tmds_setting_information *tmds_setting_info;
82 struct crt_setting_information *crt_setting_info;
83 struct lvds_setting_information *lvds_setting_info; 81 struct lvds_setting_information *lvds_setting_info;
84 struct lvds_setting_information *lvds_setting_info2; 82 struct lvds_setting_information *lvds_setting_info2;
85 struct chip_information *chip_info; 83 struct chip_information *chip_info;
86}; 84};
87 85
88extern unsigned int viafb_second_virtual_yres;
89extern unsigned int viafb_second_virtual_xres;
90extern int viafb_SAMM_ON; 86extern int viafb_SAMM_ON;
91extern int viafb_dual_fb; 87extern int viafb_dual_fb;
92extern int viafb_LCD2_ON; 88extern int viafb_LCD2_ON;
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
index 8c5bc41ff6a4..58df74e1417e 100644
--- a/drivers/video/via/viamode.c
+++ b/drivers/video/via/viamode.c
@@ -30,10 +30,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
30{VIASR, SR1A, 0xFB, 0x08}, 30{VIASR, SR1A, 0xFB, 0x08},
31{VIASR, SR1E, 0x0F, 0x01}, 31{VIASR, SR1E, 0x0F, 0x01},
32{VIASR, SR2A, 0xFF, 0x00}, 32{VIASR, SR2A, 0xFF, 0x00},
33{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
34{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
35{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
36{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
37{VIACR, CR32, 0xFF, 0x00}, 33{VIACR, CR32, 0xFF, 0x00},
38{VIACR, CR33, 0xFF, 0x00}, 34{VIACR, CR33, 0xFF, 0x00},
39{VIACR, CR35, 0xFF, 0x00}, 35{VIACR, CR35, 0xFF, 0x00},
@@ -41,7 +37,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
41{VIACR, CR69, 0xFF, 0x00}, 37{VIACR, CR69, 0xFF, 0x00},
42{VIACR, CR6A, 0xFF, 0x40}, 38{VIACR, CR6A, 0xFF, 0x40},
43{VIACR, CR6B, 0xFF, 0x00}, 39{VIACR, CR6B, 0xFF, 0x00},
44{VIACR, CR6C, 0xFF, 0x00},
45{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 40{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
46{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 41{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
47{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 42{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
@@ -87,7 +82,6 @@ struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
87{VIACR, CR69, 0xFF, 0x00}, 82{VIACR, CR69, 0xFF, 0x00},
88{VIACR, CR6A, 0xFD, 0x40}, 83{VIACR, CR6A, 0xFD, 0x40},
89{VIACR, CR6B, 0xFF, 0x00}, 84{VIACR, CR6B, 0xFF, 0x00},
90{VIACR, CR6C, 0xFF, 0x00},
91{VIACR, CR77, 0xFF, 0x00}, /* LCD scaling Factor */ 85{VIACR, CR77, 0xFF, 0x00}, /* LCD scaling Factor */
92{VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */ 86{VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */
93{VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */ 87{VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */
@@ -125,10 +119,6 @@ struct io_reg KM400_ModeXregs[] = {
125 {VIASR, SR2A, 0xFF, 0x00}, /* Power Management Control 5 */ 119 {VIASR, SR2A, 0xFF, 0x00}, /* Power Management Control 5 */
126 {VIASR, SR2D, 0xFF, 0xFF}, /* Power Management Control 1 */ 120 {VIASR, SR2D, 0xFF, 0xFF}, /* Power Management Control 1 */
127 {VIASR, SR2E, 0xFF, 0xFF}, /* Power Management Control 2 */ 121 {VIASR, SR2E, 0xFF, 0xFF}, /* Power Management Control 2 */
128 {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
129 {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
130 {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
131 {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
132 {VIACR, CR33, 0xFF, 0x00}, 122 {VIACR, CR33, 0xFF, 0x00},
133 {VIACR, CR55, 0x80, 0x00}, 123 {VIACR, CR55, 0x80, 0x00},
134 {VIACR, CR5D, 0x80, 0x00}, 124 {VIACR, CR5D, 0x80, 0x00},
@@ -161,11 +151,7 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
161{VIASR, SR1B, 0xFF, 0xF0}, 151{VIASR, SR1B, 0xFF, 0xF0},
162{VIASR, SR1E, 0xFF, 0x01}, 152{VIASR, SR1E, 0xFF, 0x01},
163{VIASR, SR2A, 0xFF, 0x00}, 153{VIASR, SR2A, 0xFF, 0x00},
164{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ 154{VIASR, SR2D, 0xC0, 0xC0}, /* delayed E3_ECK */
165{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
166{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
167{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
168{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
169{VIACR, CR32, 0xFF, 0x00}, 155{VIACR, CR32, 0xFF, 0x00},
170{VIACR, CR33, 0xFF, 0x00}, 156{VIACR, CR33, 0xFF, 0x00},
171{VIACR, CR35, 0xFF, 0x00}, 157{VIACR, CR35, 0xFF, 0x00},
@@ -174,7 +160,6 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
174{VIACR, CR69, 0xFF, 0x00}, 160{VIACR, CR69, 0xFF, 0x00},
175{VIACR, CR6A, 0xFF, 0x40}, 161{VIACR, CR6A, 0xFF, 0x40},
176{VIACR, CR6B, 0xFF, 0x00}, 162{VIACR, CR6B, 0xFF, 0x00},
177{VIACR, CR6C, 0xFF, 0x00},
178{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 163{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
179{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 164{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
180{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 165{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
@@ -204,14 +189,7 @@ struct io_reg VX855_ModeXregs[] = {
204{VIASR, SR2A, 0xF0, 0x00}, 189{VIASR, SR2A, 0xF0, 0x00},
205{VIASR, SR58, 0xFF, 0x00}, 190{VIASR, SR58, 0xFF, 0x00},
206{VIASR, SR59, 0xFF, 0x00}, 191{VIASR, SR59, 0xFF, 0x00},
207{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ 192{VIASR, SR2D, 0xC0, 0xC0}, /* delayed E3_ECK */
208{VIACR, CR09, 0xFF, 0x00}, /* Initial CR09=0*/
209{VIACR, CR11, 0x8F, 0x00}, /* IGA1 initial Vertical end */
210{VIACR, CR17, 0x7F, 0x00}, /* IGA1 CRT Mode control init */
211{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
212{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
213{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
214{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
215{VIACR, CR32, 0xFF, 0x00}, 193{VIACR, CR32, 0xFF, 0x00},
216{VIACR, CR33, 0x7F, 0x00}, 194{VIACR, CR33, 0x7F, 0x00},
217{VIACR, CR35, 0xFF, 0x00}, 195{VIACR, CR35, 0xFF, 0x00},
@@ -219,7 +197,6 @@ struct io_reg VX855_ModeXregs[] = {
219{VIACR, CR69, 0xFF, 0x00}, 197{VIACR, CR69, 0xFF, 0x00},
220{VIACR, CR6A, 0xFD, 0x60}, 198{VIACR, CR6A, 0xFD, 0x60},
221{VIACR, CR6B, 0xFF, 0x00}, 199{VIACR, CR6B, 0xFF, 0x00},
222{VIACR, CR6C, 0xFF, 0x00},
223{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 200{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
224{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 201{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
225{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ 202{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
@@ -606,7 +583,7 @@ static struct crt_mode_table CRTM1200x720[] = {
606/* 1200x900 (DCON) */ 583/* 1200x900 (DCON) */
607static struct crt_mode_table DCON1200x900[] = { 584static struct crt_mode_table DCON1200x900[] = {
608 /* r_rate, hsp, vsp */ 585 /* r_rate, hsp, vsp */
609 {REFRESH_60, M1200X900_R60_HSP, M1200X900_R60_VSP, 586 {REFRESH_49, M1200X900_R60_HSP, M1200X900_R60_VSP,
610 /* The correct htotal is 1240, but this doesn't raster on VX855. */ 587 /* The correct htotal is 1240, but this doesn't raster on VX855. */
611 /* Via suggested changing to a multiple of 16, hence 1264. */ 588 /* Via suggested changing to a multiple of 16, hence 1264. */
612 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 589 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
@@ -877,23 +854,6 @@ static struct VideoModeTable viafb_rb_modes[] = {
877 {CRTM1920x1200_RB, ARRAY_SIZE(CRTM1920x1200_RB)} 854 {CRTM1920x1200_RB, ARRAY_SIZE(CRTM1920x1200_RB)}
878}; 855};
879 856
880struct crt_mode_table CEAM1280x720[] = {
881 {REFRESH_60, M1280X720_CEA_R60_HSP, M1280X720_CEA_R60_VSP,
882 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
883 {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} }
884};
885struct crt_mode_table CEAM1920x1080[] = {
886 {REFRESH_60, M1920X1080_CEA_R60_HSP, M1920X1080_CEA_R60_VSP,
887 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
888 {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} }
889};
890struct VideoModeTable CEA_HDMI_Modes[] = {
891 /* Display : 1280x720 */
892 {CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
893 {CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
894};
895
896int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes);
897int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs); 857int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs);
898int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs); 858int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs);
899int NUM_TOTAL_KM400_ModeXregs = ARRAY_SIZE(KM400_ModeXregs); 859int NUM_TOTAL_KM400_ModeXregs = ARRAY_SIZE(KM400_ModeXregs);
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
index 8a67ea1b5ef0..3751289eb450 100644
--- a/drivers/video/via/viamode.h
+++ b/drivers/video/via/viamode.h
@@ -41,7 +41,6 @@ struct patch_table {
41 struct io_reg *io_reg_table; 41 struct io_reg *io_reg_table;
42}; 42};
43 43
44extern int NUM_TOTAL_CEA_MODES;
45extern int NUM_TOTAL_CN400_ModeXregs; 44extern int NUM_TOTAL_CN400_ModeXregs;
46extern int NUM_TOTAL_CN700_ModeXregs; 45extern int NUM_TOTAL_CN700_ModeXregs;
47extern int NUM_TOTAL_KM400_ModeXregs; 46extern int NUM_TOTAL_KM400_ModeXregs;
@@ -50,14 +49,6 @@ extern int NUM_TOTAL_VX855_ModeXregs;
50extern int NUM_TOTAL_CLE266_ModeXregs; 49extern int NUM_TOTAL_CLE266_ModeXregs;
51extern int NUM_TOTAL_PATCH_MODE; 50extern int NUM_TOTAL_PATCH_MODE;
52 51
53/********************/
54/* Mode Table */
55/********************/
56
57extern struct crt_mode_table CEAM1280x720[];
58extern struct crt_mode_table CEAM1920x1080[];
59extern struct VideoModeTable CEA_HDMI_Modes[];
60
61extern struct io_reg CN400_ModeXregs[]; 52extern struct io_reg CN400_ModeXregs[];
62extern struct io_reg CN700_ModeXregs[]; 53extern struct io_reg CN700_ModeXregs[];
63extern struct io_reg KM400_ModeXregs[]; 54extern struct io_reg KM400_ModeXregs[];