aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-22 15:39:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-22 15:39:58 -0400
commit71a8638480eb8fb6cfabe2ee9ca3fbc6e3453a14 (patch)
tree8ee9f7da07bb9461a41a8ded6f9da243db02b279 /drivers/video/via
parent17238005f377888b9d4583835205c77e3d781bb8 (diff)
parent8aa4d96fe3e4cda9a6469b22b3f017ed30996b10 (diff)
Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6
* 'viafb-next' of git://github.com/schandinat/linux-2.6: (24 commits) viafb: Automatic OLPC XO-1.5 configuration viafb: remove unused CEA mode viafb: try to map less memory in case of failure viafb: use write combining for video ram viafb: add X server compatibility mode viafb: reduce OLPC refresh a bit viafb: fix OLPC XO 1.5 device connection viafb: fix OLPC DCON refresh rate viafb: delete clock and PLL initialization viafb: replace custom return values viafb: some small cleanup for global variables viafb: gather common good, old VGA initialization in one place viafb: add engine clock support viafb: add VIA slapping capability viafb: split clock and PLL code to an extra file viafb: add primary/secondary clock on/off switches viafb: add clock source selection and PLL power management support viafb: prepare for PLL separation viafb: call viafb_get_clk_value only in viafb_set_vclock viafb: remove unused max_hres/vres ...
Diffstat (limited to 'drivers/video/via')
-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
18 files changed, 712 insertions, 706 deletions
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
index 96f01ee2a41..5108136e877 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 29d70244a21..3ebf20c06ee 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 41ca198b509..b1f364745ca 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 2c525c0c1ad..f473dd01097 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 1ee511b7330..e10d8249534 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 38ef5ac6695..ff969dc3459 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 dc4c778877c..47b13535ed2 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 8858593405a..c7239eb83ba 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 64bc7e76310..6e06981d638 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 c7909fe2955..75f60a655b0 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 4b7831f0d01..61b0bd596b8 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 6723d6910cd..eb112b62173 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 00000000000..af8f26b643c
--- /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 00000000000..88714ae0d15
--- /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 a542bed086e..cf43c80d27f 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 137996dc547..d9440635d1d 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 8c5bc41ff6a..58df74e1417 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 8a67ea1b5ef..3751289eb45 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[];