summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 12:24:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 12:24:30 -0500
commite0c8453769fcaec654cd5870e84c63175658c842 (patch)
treee5f114f236689a8db8f44bcecb5c1f1e14462932 /drivers/video
parenta323ae93a74f669d890926187c68c711895e3454 (diff)
parentd6c2152b3efd73be265f426b5a1bb50ec436d999 (diff)
Merge tag 'fbdev-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux
Pull fbdev changes from Tomi Valkeinen: - omapdss: add DRA7xxx SoC support - fbdev: support DMT (Display Monitor Timing) calculation * tag 'fbdev-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (40 commits) omapfb: Return error code when applying overlay settings fails OMAPDSS: DPI: DRA7xx support OMAPDSS: HDMI: Add DRA7xx support OMAPDSS: DISPC: program dispc polarities to control module OMAPDSS: DISPC: Add DRA7xx support OMAPDSS: Add Video PLLs for DRA7xx OMAPDSS: Add functions for external control of PLL OMAPDSS: DSS: Add DRA7xx base support Doc/DT: Add DT binding doc for DRA7xx DSS OMAPDSS: add define for DRA7xx HW version OMAPDSS: encoder-tpd12s015: Fix race issue with LS_OE OMAPDSS: OMAP5: fix digit output's allowed mgrs OMAPDSS: constify port arrays OMAPDSS: PLL: add dss_pll_wait_reset_done() OMAPDSS: Add enum dss_pll_id video: fbdev: fix sys_copyarea video/mmpfb: allow modular build fb: via: turn gpiolib and i2c selects into dependencies fbdev: ssd1307fb: return proper error code if write command fails fbdev: fix CVT vertical front and back porch values ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/console/Kconfig16
-rw-r--r--drivers/video/console/dummycon.c5
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/fbdev/Kconfig5
-rw-r--r--drivers/video/fbdev/aty/atyfb_base.c9
-rw-r--r--drivers/video/fbdev/core/fbcvt.c6
-rw-r--r--drivers/video/fbdev/core/fbmon.c103
-rw-r--r--drivers/video/fbdev/core/modedb.c111
-rw-r--r--drivers/video/fbdev/core/syscopyarea.c137
-rw-r--r--drivers/video/fbdev/geode/gx1fb_core.c6
-rw-r--r--drivers/video/fbdev/geode/gxfb_core.c6
-rw-r--r--drivers/video/fbdev/geode/lxfb_core.c6
-rw-r--r--drivers/video/fbdev/hgafb.c3
-rw-r--r--drivers/video/fbdev/mmp/Makefile4
-rw-r--r--drivers/video/fbdev/mmp/fb/Kconfig2
-rw-r--r--drivers/video/fbdev/ocfb.c2
-rw-r--r--drivers/video/fbdev/omap2/displays-new/Kconfig6
-rw-r--r--drivers/video/fbdev/omap2/displays-new/Makefile1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c2
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-opa362.c285
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c57
-rw-r--r--drivers/video/fbdev/omap2/dss/Makefile2
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c54
-rw-r--r--drivers/video/fbdev/omap2/dss/dpi.c26
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.c219
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.h22
-rw-r--r--drivers/video/fbdev/omap2/dss/dss_features.c3
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_phy.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_pll.c6
-rw-r--r--drivers/video/fbdev/omap2/dss/omapdss-boot-init.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/pll.c10
-rw-r--r--drivers/video/fbdev/omap2/dss/video-pll.c211
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c7
-rw-r--r--drivers/video/fbdev/savage/savagefb.h12
-rw-r--r--drivers/video/fbdev/ssd1307fb.c86
-rw-r--r--drivers/video/fbdev/vt8500lcdfb.c4
-rw-r--r--drivers/video/vgastate.c82
39 files changed, 1223 insertions, 301 deletions
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fe1cd0148e13..ba97efc3bf70 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -77,18 +77,22 @@ config DUMMY_CONSOLE
77 77
78config DUMMY_CONSOLE_COLUMNS 78config DUMMY_CONSOLE_COLUMNS
79 int "Initial number of console screen columns" 79 int "Initial number of console screen columns"
80 depends on PARISC && DUMMY_CONSOLE 80 depends on DUMMY_CONSOLE && !ARM
81 default "160" 81 default 160 if PARISC
82 default 80
82 help 83 help
83 The default value is 160, which should fit a 1280x1024 monitor. 84 On PA-RISC, the default value is 160, which should fit a 1280x1024
85 monitor.
84 Select 80 if you use a 640x480 resolution by default. 86 Select 80 if you use a 640x480 resolution by default.
85 87
86config DUMMY_CONSOLE_ROWS 88config DUMMY_CONSOLE_ROWS
87 int "Initial number of console screen rows" 89 int "Initial number of console screen rows"
88 depends on PARISC && DUMMY_CONSOLE 90 depends on DUMMY_CONSOLE && !ARM
89 default "64" 91 default 64 if PARISC
92 default 25
90 help 93 help
91 The default value is 64, which should fit a 1280x1024 monitor. 94 On PA-RISC, the default value is 64, which should fit a 1280x1024
95 monitor.
92 Select 25 if you use a 640x480 resolution by default. 96 Select 25 if you use a 640x480 resolution by default.
93 97
94config FRAMEBUFFER_CONSOLE 98config FRAMEBUFFER_CONSOLE
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index 40bec8d64b0a..0efc52f11ad0 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -20,13 +20,10 @@
20#if defined(__arm__) 20#if defined(__arm__)
21#define DUMMY_COLUMNS screen_info.orig_video_cols 21#define DUMMY_COLUMNS screen_info.orig_video_cols
22#define DUMMY_ROWS screen_info.orig_video_lines 22#define DUMMY_ROWS screen_info.orig_video_lines
23#elif defined(__hppa__) 23#else
24/* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */ 24/* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */
25#define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS 25#define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS
26#define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS 26#define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS
27#else
28#define DUMMY_COLUMNS 80
29#define DUMMY_ROWS 25
30#endif 27#endif
31 28
32static const char *dummycon_startup(void) 29static const char *dummycon_startup(void)
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index ea437245562e..b97210671a81 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -146,9 +146,6 @@ static const struct consw fb_con;
146 146
147static int fbcon_set_origin(struct vc_data *); 147static int fbcon_set_origin(struct vc_data *);
148 148
149#define CURSOR_DRAW_DELAY (1)
150
151static int vbl_cursor_cnt;
152static int fbcon_cursor_noblink; 149static int fbcon_cursor_noblink;
153 150
154#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1) 151#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
@@ -1329,7 +1326,6 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
1329 1326
1330 ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1), 1327 ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1),
1331 get_color(vc, info, c, 0)); 1328 get_color(vc, info, c, 0));
1332 vbl_cursor_cnt = CURSOR_DRAW_DELAY;
1333} 1329}
1334 1330
1335static int scrollback_phys_max = 0; 1331static int scrollback_phys_max = 0;
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 4916c97216f8..b3dd417b4719 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1530,13 +1530,11 @@ config FB_SIS_315
1530 1530
1531config FB_VIA 1531config FB_VIA
1532 tristate "VIA UniChrome (Pro) and Chrome9 display support" 1532 tristate "VIA UniChrome (Pro) and Chrome9 display support"
1533 depends on FB && PCI && X86 1533 depends on FB && PCI && X86 && GPIOLIB && I2C
1534 select FB_CFB_FILLRECT 1534 select FB_CFB_FILLRECT
1535 select FB_CFB_COPYAREA 1535 select FB_CFB_COPYAREA
1536 select FB_CFB_IMAGEBLIT 1536 select FB_CFB_IMAGEBLIT
1537 select I2C_ALGOBIT 1537 select I2C_ALGOBIT
1538 select I2C
1539 select GPIOLIB
1540 help 1538 help
1541 This is the frame buffer device driver for Graphics chips of VIA 1539 This is the frame buffer device driver for Graphics chips of VIA
1542 UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ 1540 UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
@@ -2151,7 +2149,6 @@ config FB_PS3
2151 select FB_SYS_COPYAREA 2149 select FB_SYS_COPYAREA
2152 select FB_SYS_IMAGEBLIT 2150 select FB_SYS_IMAGEBLIT
2153 select FB_SYS_FOPS 2151 select FB_SYS_FOPS
2154 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
2155 ---help--- 2152 ---help---
2156 Include support for the virtual frame buffer in the PS3 platform. 2153 Include support for the virtual frame buffer in the PS3 platform.
2157 2154
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index 37ec09b3fffd..8789e487b96e 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3948,7 +3948,7 @@ static struct notifier_block atyfb_reboot_notifier = {
3948 .notifier_call = atyfb_reboot_notify, 3948 .notifier_call = atyfb_reboot_notify,
3949}; 3949};
3950 3950
3951static const struct dmi_system_id atyfb_reboot_ids[] = { 3951static const struct dmi_system_id atyfb_reboot_ids[] __initconst = {
3952 { 3952 {
3953 .ident = "HP OmniBook 500", 3953 .ident = "HP OmniBook 500",
3954 .matches = { 3954 .matches = {
@@ -3960,6 +3960,7 @@ static const struct dmi_system_id atyfb_reboot_ids[] = {
3960 3960
3961 { } 3961 { }
3962}; 3962};
3963static bool registered_notifier = false;
3963 3964
3964static int __init atyfb_init(void) 3965static int __init atyfb_init(void)
3965{ 3966{
@@ -3982,15 +3983,17 @@ static int __init atyfb_init(void)
3982 if (err1 && err2) 3983 if (err1 && err2)
3983 return -ENODEV; 3984 return -ENODEV;
3984 3985
3985 if (dmi_check_system(atyfb_reboot_ids)) 3986 if (dmi_check_system(atyfb_reboot_ids)) {
3986 register_reboot_notifier(&atyfb_reboot_notifier); 3987 register_reboot_notifier(&atyfb_reboot_notifier);
3988 registered_notifier = true;
3989 }
3987 3990
3988 return 0; 3991 return 0;
3989} 3992}
3990 3993
3991static void __exit atyfb_exit(void) 3994static void __exit atyfb_exit(void)
3992{ 3995{
3993 if (dmi_check_system(atyfb_reboot_ids)) 3996 if (registered_notifier)
3994 unregister_reboot_notifier(&atyfb_reboot_notifier); 3997 unregister_reboot_notifier(&atyfb_reboot_notifier);
3995 3998
3996#ifdef CONFIG_PCI 3999#ifdef CONFIG_PCI
diff --git a/drivers/video/fbdev/core/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c
index 7cb715dfc0e1..55d2bd0ce5c0 100644
--- a/drivers/video/fbdev/core/fbcvt.c
+++ b/drivers/video/fbdev/core/fbcvt.c
@@ -369,9 +369,9 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb)
369 cvt.h_back_porch = cvt.hblank/2 + cvt.h_margin; 369 cvt.h_back_porch = cvt.hblank/2 + cvt.h_margin;
370 cvt.h_front_porch = cvt.hblank - cvt.hsync - cvt.h_back_porch + 370 cvt.h_front_porch = cvt.hblank - cvt.hsync - cvt.h_back_porch +
371 2 * cvt.h_margin; 371 2 * cvt.h_margin;
372 cvt.v_back_porch = 3 + cvt.v_margin; 372 cvt.v_front_porch = 3 + cvt.v_margin;
373 cvt.v_front_porch = cvt.vtotal - cvt.yres/cvt.interlace - 373 cvt.v_back_porch = cvt.vtotal - cvt.yres/cvt.interlace -
374 cvt.v_back_porch - cvt.vsync; 374 cvt.v_front_porch - cvt.vsync;
375 fb_cvt_print_name(&cvt); 375 fb_cvt_print_name(&cvt);
376 fb_cvt_convert_to_mode(&cvt, mode); 376 fb_cvt_convert_to_mode(&cvt, mode);
377 377
diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
index 5b0e313849bd..95338593ebf4 100644
--- a/drivers/video/fbdev/core/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -496,56 +496,71 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
496} 496}
497 497
498static int get_std_timing(unsigned char *block, struct fb_videomode *mode, 498static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
499 int ver, int rev) 499 int ver, int rev, const struct fb_monspecs *specs)
500{ 500{
501 int xres, yres = 0, refresh, ratio, i; 501 int i;
502
503 xres = (block[0] + 31) * 8;
504 if (xres <= 256)
505 return 0;
506 502
507 ratio = (block[1] & 0xc0) >> 6; 503 for (i = 0; i < DMT_SIZE; i++) {
508 switch (ratio) { 504 u32 std_2byte_code = block[0] << 8 | block[1];
509 case 0: 505 if (std_2byte_code == dmt_modes[i].std_2byte_code)
510 /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */ 506 break;
511 if (ver < 1 || (ver == 1 && rev < 3))
512 yres = xres;
513 else
514 yres = (xres * 10)/16;
515 break;
516 case 1:
517 yres = (xres * 3)/4;
518 break;
519 case 2:
520 yres = (xres * 4)/5;
521 break;
522 case 3:
523 yres = (xres * 9)/16;
524 break;
525 } 507 }
526 refresh = (block[1] & 0x3f) + 60; 508
527 509 if (i < DMT_SIZE && dmt_modes[i].mode) {
528 DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); 510 /* DMT mode found */
529 for (i = 0; i < VESA_MODEDB_SIZE; i++) { 511 *mode = *dmt_modes[i].mode;
530 if (vesa_modes[i].xres == xres && 512 mode->flag |= FB_MODE_IS_STANDARD;
531 vesa_modes[i].yres == yres && 513 DPRINTK(" DMT id=%d\n", dmt_modes[i].dmt_id);
532 vesa_modes[i].refresh == refresh) { 514
533 *mode = vesa_modes[i]; 515 } else {
534 mode->flag |= FB_MODE_IS_STANDARD; 516 int xres, yres = 0, refresh, ratio;
535 return 1; 517
518 xres = (block[0] + 31) * 8;
519 if (xres <= 256)
520 return 0;
521
522 ratio = (block[1] & 0xc0) >> 6;
523 switch (ratio) {
524 case 0:
525 /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */
526 if (ver < 1 || (ver == 1 && rev < 3))
527 yres = xres;
528 else
529 yres = (xres * 10)/16;
530 break;
531 case 1:
532 yres = (xres * 3)/4;
533 break;
534 case 2:
535 yres = (xres * 4)/5;
536 break;
537 case 3:
538 yres = (xres * 9)/16;
539 break;
536 } 540 }
541 refresh = (block[1] & 0x3f) + 60;
542 DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh);
543
544 calc_mode_timings(xres, yres, refresh, mode);
537 } 545 }
538 calc_mode_timings(xres, yres, refresh, mode); 546
547 /* Check the mode we got is within valid spec of the monitor */
548 if (specs && specs->dclkmax
549 && PICOS2KHZ(mode->pixclock) * 1000 > specs->dclkmax) {
550 DPRINTK(" mode exceed max DCLK\n");
551 return 0;
552 }
553
539 return 1; 554 return 1;
540} 555}
541 556
542static int get_dst_timing(unsigned char *block, 557static int get_dst_timing(unsigned char *block, struct fb_videomode *mode,
543 struct fb_videomode *mode, int ver, int rev) 558 int ver, int rev, const struct fb_monspecs *specs)
544{ 559{
545 int j, num = 0; 560 int j, num = 0;
546 561
547 for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE) 562 for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
548 num += get_std_timing(block, &mode[num], ver, rev); 563 num += get_std_timing(block, &mode[num], ver, rev, specs);
549 564
550 return num; 565 return num;
551} 566}
@@ -601,7 +616,8 @@ static void get_detailed_timing(unsigned char *block,
601 * This function builds a mode database using the contents of the EDID 616 * This function builds a mode database using the contents of the EDID
602 * data 617 * data
603 */ 618 */
604static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) 619static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize,
620 const struct fb_monspecs *specs)
605{ 621{
606 struct fb_videomode *mode, *m; 622 struct fb_videomode *mode, *m;
607 unsigned char *block; 623 unsigned char *block;
@@ -643,12 +659,13 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
643 DPRINTK(" Standard Timings\n"); 659 DPRINTK(" Standard Timings\n");
644 block = edid + STD_TIMING_DESCRIPTIONS_START; 660 block = edid + STD_TIMING_DESCRIPTIONS_START;
645 for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) 661 for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
646 num += get_std_timing(block, &mode[num], ver, rev); 662 num += get_std_timing(block, &mode[num], ver, rev, specs);
647 663
648 block = edid + DETAILED_TIMING_DESCRIPTIONS_START; 664 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
649 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { 665 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
650 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) 666 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
651 num += get_dst_timing(block + 5, &mode[num], ver, rev); 667 num += get_dst_timing(block + 5, &mode[num],
668 ver, rev, specs);
652 } 669 }
653 670
654 /* Yikes, EDID data is totally useless */ 671 /* Yikes, EDID data is totally useless */
@@ -707,7 +724,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
707 int num_modes, hz, hscan, pixclock; 724 int num_modes, hz, hscan, pixclock;
708 int vtotal, htotal; 725 int vtotal, htotal;
709 726
710 modes = fb_create_modedb(edid, &num_modes); 727 modes = fb_create_modedb(edid, &num_modes, specs);
711 if (!modes) { 728 if (!modes) {
712 DPRINTK("None Available\n"); 729 DPRINTK("None Available\n");
713 return 1; 730 return 1;
@@ -964,7 +981,7 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
964 DPRINTK(" Display Characteristics:\n"); 981 DPRINTK(" Display Characteristics:\n");
965 get_monspecs(edid, specs); 982 get_monspecs(edid, specs);
966 983
967 specs->modedb = fb_create_modedb(edid, &specs->modedb_len); 984 specs->modedb = fb_create_modedb(edid, &specs->modedb_len, specs);
968 985
969 /* 986 /*
970 * Workaround for buggy EDIDs that sets that the first 987 * Workaround for buggy EDIDs that sets that the first
diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c
index 388f7971494b..7d07cf824b64 100644
--- a/drivers/video/fbdev/core/modedb.c
+++ b/drivers/video/fbdev/core/modedb.c
@@ -468,8 +468,119 @@ const struct fb_videomode vesa_modes[] = {
468 /* 33 1920x1440-75 VESA */ 468 /* 33 1920x1440-75 VESA */
469 { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, 469 { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
470 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 470 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
471 /* 34 1920x1200-60 RB VESA */
472 { NULL, 60, 1920, 1200, 6493, 80, 48, 26, 3, 32, 6,
473 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
474 /* 35 1920x1200-60 VESA */
475 { NULL, 60, 1920, 1200, 5174, 336, 136, 36, 3, 200, 6,
476 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
477 /* 36 1920x1200-75 VESA */
478 { NULL, 75, 1920, 1200, 4077, 344, 136, 46, 3, 208, 6,
479 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
480 /* 37 1920x1200-85 VESA */
481 { NULL, 85, 1920, 1200, 3555, 352, 144, 53, 3, 208, 6,
482 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
483 /* 38 2560x1600-60 RB VESA */
484 { NULL, 60, 2560, 1600, 3724, 80, 48, 37, 3, 32, 6,
485 FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
486 /* 39 2560x1600-60 VESA */
487 { NULL, 60, 2560, 1600, 2869, 472, 192, 49, 3, 280, 6,
488 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
489 /* 40 2560x1600-75 VESA */
490 { NULL, 75, 2560, 1600, 2256, 488, 208, 63, 3, 280, 6,
491 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
492 /* 41 2560x1600-85 VESA */
493 { NULL, 85, 2560, 1600, 1979, 488, 208, 73, 3, 280, 6,
494 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
495 /* 42 2560x1600-120 RB VESA */
496 { NULL, 120, 2560, 1600, 1809, 80, 48, 85, 3, 32, 6,
497 FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
471}; 498};
472EXPORT_SYMBOL(vesa_modes); 499EXPORT_SYMBOL(vesa_modes);
500
501const struct dmt_videomode dmt_modes[DMT_SIZE] = {
502 { 0x01, 0x0000, 0x000000, &vesa_modes[0] },
503 { 0x02, 0x3119, 0x000000, &vesa_modes[1] },
504 { 0x03, 0x0000, 0x000000, &vesa_modes[2] },
505 { 0x04, 0x3140, 0x000000, &vesa_modes[3] },
506 { 0x05, 0x314c, 0x000000, &vesa_modes[4] },
507 { 0x06, 0x314f, 0x000000, &vesa_modes[5] },
508 { 0x07, 0x3159, 0x000000, &vesa_modes[6] },
509 { 0x08, 0x0000, 0x000000, &vesa_modes[7] },
510 { 0x09, 0x4540, 0x000000, &vesa_modes[8] },
511 { 0x0a, 0x454c, 0x000000, &vesa_modes[9] },
512 { 0x0b, 0x454f, 0x000000, &vesa_modes[10] },
513 { 0x0c, 0x4559, 0x000000, &vesa_modes[11] },
514 { 0x0d, 0x0000, 0x000000, NULL },
515 { 0x0e, 0x0000, 0x000000, NULL },
516 { 0x0f, 0x0000, 0x000000, &vesa_modes[12] },
517 { 0x10, 0x6140, 0x000000, &vesa_modes[13] },
518 { 0x11, 0x614a, 0x000000, &vesa_modes[14] },
519 { 0x12, 0x614f, 0x000000, &vesa_modes[15] },
520 { 0x13, 0x6159, 0x000000, &vesa_modes[16] },
521 { 0x14, 0x0000, 0x000000, NULL },
522 { 0x15, 0x714f, 0x000000, &vesa_modes[17] },
523 { 0x16, 0x0000, 0x7f1c21, NULL },
524 { 0x17, 0x0000, 0x7f1c28, NULL },
525 { 0x18, 0x0000, 0x7f1c44, NULL },
526 { 0x19, 0x0000, 0x7f1c62, NULL },
527 { 0x1a, 0x0000, 0x000000, NULL },
528 { 0x1b, 0x0000, 0x8f1821, NULL },
529 { 0x1c, 0x8100, 0x8f1828, NULL },
530 { 0x1d, 0x810f, 0x8f1844, NULL },
531 { 0x1e, 0x8119, 0x8f1862, NULL },
532 { 0x1f, 0x0000, 0x000000, NULL },
533 { 0x20, 0x8140, 0x000000, &vesa_modes[18] },
534 { 0x21, 0x8159, 0x000000, &vesa_modes[19] },
535 { 0x22, 0x0000, 0x000000, NULL },
536 { 0x23, 0x8180, 0x000000, &vesa_modes[20] },
537 { 0x24, 0x818f, 0x000000, &vesa_modes[21] },
538 { 0x25, 0x8199, 0x000000, &vesa_modes[22] },
539 { 0x26, 0x0000, 0x000000, NULL },
540 { 0x27, 0x0000, 0x000000, NULL },
541 { 0x28, 0x0000, 0x000000, NULL },
542 { 0x29, 0x0000, 0x0c2021, NULL },
543 { 0x2a, 0x9040, 0x0c2028, NULL },
544 { 0x2b, 0x904f, 0x0c2044, NULL },
545 { 0x2c, 0x9059, 0x0c2062, NULL },
546 { 0x2d, 0x0000, 0x000000, NULL },
547 { 0x2e, 0x9500, 0xc11821, NULL },
548 { 0x2f, 0x9500, 0xc11828, NULL },
549 { 0x30, 0x950f, 0xc11844, NULL },
550 { 0x31, 0x9519, 0xc11868, NULL },
551 { 0x32, 0x0000, 0x000000, NULL },
552 { 0x33, 0xa940, 0x000000, &vesa_modes[23] },
553 { 0x34, 0xa945, 0x000000, &vesa_modes[24] },
554 { 0x35, 0xa94a, 0x000000, &vesa_modes[25] },
555 { 0x36, 0xa94f, 0x000000, &vesa_modes[26] },
556 { 0x37, 0xa959, 0x000000, &vesa_modes[27] },
557 { 0x38, 0x0000, 0x000000, NULL },
558 { 0x39, 0x0000, 0x0c2821, NULL },
559 { 0x3a, 0xb300, 0x0c2828, NULL },
560 { 0x3b, 0xb30f, 0x0c2844, NULL },
561 { 0x3c, 0xb319, 0x0c2868, NULL },
562 { 0x3d, 0x0000, 0x000000, NULL },
563 { 0x3e, 0xc140, 0x000000, &vesa_modes[28] },
564 { 0x3f, 0xc14f, 0x000000, &vesa_modes[29] },
565 { 0x40, 0x0000, 0x000000, NULL},
566 { 0x41, 0xc940, 0x000000, &vesa_modes[30] },
567 { 0x42, 0xc94f, 0x000000, &vesa_modes[31] },
568 { 0x43, 0x0000, 0x000000, NULL },
569 { 0x44, 0x0000, 0x572821, &vesa_modes[34] },
570 { 0x45, 0xd100, 0x572828, &vesa_modes[35] },
571 { 0x46, 0xd10f, 0x572844, &vesa_modes[36] },
572 { 0x47, 0xd119, 0x572862, &vesa_modes[37] },
573 { 0x48, 0x0000, 0x000000, NULL },
574 { 0x49, 0xd140, 0x000000, &vesa_modes[32] },
575 { 0x4a, 0xd14f, 0x000000, &vesa_modes[33] },
576 { 0x4b, 0x0000, 0x000000, NULL },
577 { 0x4c, 0x0000, 0x1f3821, &vesa_modes[38] },
578 { 0x4d, 0x0000, 0x1f3828, &vesa_modes[39] },
579 { 0x4e, 0x0000, 0x1f3844, &vesa_modes[40] },
580 { 0x4f, 0x0000, 0x1f3862, &vesa_modes[41] },
581 { 0x50, 0x0000, 0x000000, &vesa_modes[42] },
582};
583EXPORT_SYMBOL(dmt_modes);
473#endif /* CONFIG_FB_MODE_HELPERS */ 584#endif /* CONFIG_FB_MODE_HELPERS */
474 585
475/** 586/**
diff --git a/drivers/video/fbdev/core/syscopyarea.c b/drivers/video/fbdev/core/syscopyarea.c
index 844a32fd38ed..c1eda3190968 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -25,8 +25,8 @@
25 */ 25 */
26 26
27static void 27static void
28bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx, 28bitcpy(struct fb_info *p, unsigned long *dst, unsigned dst_idx,
29 const unsigned long *src, int src_idx, int bits, unsigned n) 29 const unsigned long *src, unsigned src_idx, int bits, unsigned n)
30{ 30{
31 unsigned long first, last; 31 unsigned long first, last;
32 int const shift = dst_idx-src_idx; 32 int const shift = dst_idx-src_idx;
@@ -86,15 +86,15 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
86 first &= last; 86 first &= last;
87 if (shift > 0) { 87 if (shift > 0) {
88 /* Single source word */ 88 /* Single source word */
89 *dst = comp(*src >> right, *dst, first); 89 *dst = comp(*src << left, *dst, first);
90 } else if (src_idx+n <= bits) { 90 } else if (src_idx+n <= bits) {
91 /* Single source word */ 91 /* Single source word */
92 *dst = comp(*src << left, *dst, first); 92 *dst = comp(*src >> right, *dst, first);
93 } else { 93 } else {
94 /* 2 source words */ 94 /* 2 source words */
95 d0 = *src++; 95 d0 = *src++;
96 d1 = *src; 96 d1 = *src;
97 *dst = comp(d0 << left | d1 >> right, *dst, 97 *dst = comp(d0 >> right | d1 << left, *dst,
98 first); 98 first);
99 } 99 }
100 } else { 100 } else {
@@ -109,13 +109,14 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
109 /* Leading bits */ 109 /* Leading bits */
110 if (shift > 0) { 110 if (shift > 0) {
111 /* Single source word */ 111 /* Single source word */
112 *dst = comp(d0 >> right, *dst, first); 112 *dst = comp(d0 << left, *dst, first);
113 dst++; 113 dst++;
114 n -= bits - dst_idx; 114 n -= bits - dst_idx;
115 } else { 115 } else {
116 /* 2 source words */ 116 /* 2 source words */
117 d1 = *src++; 117 d1 = *src++;
118 *dst = comp(d0 << left | *dst >> right, *dst, first); 118 *dst = comp(d0 >> right | d1 << left, *dst,
119 first);
119 d0 = d1; 120 d0 = d1;
120 dst++; 121 dst++;
121 n -= bits - dst_idx; 122 n -= bits - dst_idx;
@@ -126,36 +127,36 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
126 n /= bits; 127 n /= bits;
127 while (n >= 4) { 128 while (n >= 4) {
128 d1 = *src++; 129 d1 = *src++;
129 *dst++ = d0 << left | d1 >> right; 130 *dst++ = d0 >> right | d1 << left;
130 d0 = d1; 131 d0 = d1;
131 d1 = *src++; 132 d1 = *src++;
132 *dst++ = d0 << left | d1 >> right; 133 *dst++ = d0 >> right | d1 << left;
133 d0 = d1; 134 d0 = d1;
134 d1 = *src++; 135 d1 = *src++;
135 *dst++ = d0 << left | d1 >> right; 136 *dst++ = d0 >> right | d1 << left;
136 d0 = d1; 137 d0 = d1;
137 d1 = *src++; 138 d1 = *src++;
138 *dst++ = d0 << left | d1 >> right; 139 *dst++ = d0 >> right | d1 << left;
139 d0 = d1; 140 d0 = d1;
140 n -= 4; 141 n -= 4;
141 } 142 }
142 while (n--) { 143 while (n--) {
143 d1 = *src++; 144 d1 = *src++;
144 *dst++ = d0 << left | d1 >> right; 145 *dst++ = d0 >> right | d1 << left;
145 d0 = d1; 146 d0 = d1;
146 } 147 }
147 148
148 /* Trailing bits */ 149 /* Trailing bits */
149 if (last) { 150 if (m) {
150 if (m <= right) { 151 if (m <= bits - right) {
151 /* Single source word */ 152 /* Single source word */
152 *dst = comp(d0 << left, *dst, last); 153 d0 >>= right;
153 } else { 154 } else {
154 /* 2 source words */ 155 /* 2 source words */
155 d1 = *src; 156 d1 = *src;
156 *dst = comp(d0 << left | d1 >> right, 157 d0 = d0 >> right | d1 << left;
157 *dst, last);
158 } 158 }
159 *dst = comp(d0, *dst, last);
159 } 160 }
160 } 161 }
161 } 162 }
@@ -166,40 +167,35 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx,
166 */ 167 */
167 168
168static void 169static void
169bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx, 170bitcpy_rev(struct fb_info *p, unsigned long *dst, unsigned dst_idx,
170 const unsigned long *src, int src_idx, int bits, unsigned n) 171 const unsigned long *src, unsigned src_idx, unsigned bits,
172 unsigned n)
171{ 173{
172 unsigned long first, last; 174 unsigned long first, last;
173 int shift; 175 int shift;
174 176
175 dst += (n-1)/bits; 177 dst += (dst_idx + n - 1) / bits;
176 src += (n-1)/bits; 178 src += (src_idx + n - 1) / bits;
177 if ((n-1) % bits) { 179 dst_idx = (dst_idx + n - 1) % bits;
178 dst_idx += (n-1) % bits; 180 src_idx = (src_idx + n - 1) % bits;
179 dst += dst_idx >> (ffs(bits) - 1);
180 dst_idx &= bits - 1;
181 src_idx += (n-1) % bits;
182 src += src_idx >> (ffs(bits) - 1);
183 src_idx &= bits - 1;
184 }
185 181
186 shift = dst_idx-src_idx; 182 shift = dst_idx-src_idx;
187 183
188 first = FB_SHIFT_LOW(p, ~0UL, bits - 1 - dst_idx); 184 first = ~FB_SHIFT_HIGH(p, ~0UL, (dst_idx + 1) % bits);
189 last = ~(FB_SHIFT_LOW(p, ~0UL, bits - 1 - ((dst_idx-n) % bits))); 185 last = FB_SHIFT_HIGH(p, ~0UL, (bits + dst_idx + 1 - n) % bits);
190 186
191 if (!shift) { 187 if (!shift) {
192 /* Same alignment for source and dest */ 188 /* Same alignment for source and dest */
193 if ((unsigned long)dst_idx+1 >= n) { 189 if ((unsigned long)dst_idx+1 >= n) {
194 /* Single word */ 190 /* Single word */
195 if (last) 191 if (first)
196 first &= last; 192 last &= first;
197 *dst = comp(*src, *dst, first); 193 *dst = comp(*src, *dst, last);
198 } else { 194 } else {
199 /* Multiple destination words */ 195 /* Multiple destination words */
200 196
201 /* Leading bits */ 197 /* Leading bits */
202 if (first != ~0UL) { 198 if (first) {
203 *dst = comp(*src, *dst, first); 199 *dst = comp(*src, *dst, first);
204 dst--; 200 dst--;
205 src--; 201 src--;
@@ -222,29 +218,29 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx,
222 while (n--) 218 while (n--)
223 *dst-- = *src--; 219 *dst-- = *src--;
224 /* Trailing bits */ 220 /* Trailing bits */
225 if (last) 221 if (last != -1UL)
226 *dst = comp(*src, *dst, last); 222 *dst = comp(*src, *dst, last);
227 } 223 }
228 } else { 224 } else {
229 /* Different alignment for source and dest */ 225 /* Different alignment for source and dest */
230 226
231 int const left = -shift & (bits-1); 227 int const left = shift & (bits-1);
232 int const right = shift & (bits-1); 228 int const right = -shift & (bits-1);
233 229
234 if ((unsigned long)dst_idx+1 >= n) { 230 if ((unsigned long)dst_idx+1 >= n) {
235 /* Single destination word */ 231 /* Single destination word */
236 if (last) 232 if (first)
237 first &= last; 233 last &= first;
238 if (shift < 0) { 234 if (shift < 0) {
239 /* Single source word */ 235 /* Single source word */
240 *dst = comp(*src << left, *dst, first); 236 *dst = comp(*src >> right, *dst, last);
241 } else if (1+(unsigned long)src_idx >= n) { 237 } else if (1+(unsigned long)src_idx >= n) {
242 /* Single source word */ 238 /* Single source word */
243 *dst = comp(*src >> right, *dst, first); 239 *dst = comp(*src << left, *dst, last);
244 } else { 240 } else {
245 /* 2 source words */ 241 /* 2 source words */
246 *dst = comp(*src >> right | *(src-1) << left, 242 *dst = comp(*src << left | *(src-1) >> right,
247 *dst, first); 243 *dst, last);
248 } 244 }
249 } else { 245 } else {
250 /* Multiple destination words */ 246 /* Multiple destination words */
@@ -261,14 +257,18 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx,
261 /* Leading bits */ 257 /* Leading bits */
262 if (shift < 0) { 258 if (shift < 0) {
263 /* Single source word */ 259 /* Single source word */
264 *dst = comp(d0 << left, *dst, first); 260 d1 = d0;
261 d0 >>= right;
265 } else { 262 } else {
266 /* 2 source words */ 263 /* 2 source words */
267 d1 = *src--; 264 d1 = *src--;
268 *dst = comp(d0 >> right | d1 << left, *dst, 265 d0 = d0 << left | d1 >> right;
269 first);
270 d0 = d1;
271 } 266 }
267 if (!first)
268 *dst = d0;
269 else
270 *dst = comp(d0, *dst, first);
271 d0 = d1;
272 dst--; 272 dst--;
273 n -= dst_idx+1; 273 n -= dst_idx+1;
274 274
@@ -277,36 +277,36 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx,
277 n /= bits; 277 n /= bits;
278 while (n >= 4) { 278 while (n >= 4) {
279 d1 = *src--; 279 d1 = *src--;
280 *dst-- = d0 >> right | d1 << left; 280 *dst-- = d0 << left | d1 >> right;
281 d0 = d1; 281 d0 = d1;
282 d1 = *src--; 282 d1 = *src--;
283 *dst-- = d0 >> right | d1 << left; 283 *dst-- = d0 << left | d1 >> right;
284 d0 = d1; 284 d0 = d1;
285 d1 = *src--; 285 d1 = *src--;
286 *dst-- = d0 >> right | d1 << left; 286 *dst-- = d0 << left | d1 >> right;
287 d0 = d1; 287 d0 = d1;
288 d1 = *src--; 288 d1 = *src--;
289 *dst-- = d0 >> right | d1 << left; 289 *dst-- = d0 << left | d1 >> right;
290 d0 = d1; 290 d0 = d1;
291 n -= 4; 291 n -= 4;
292 } 292 }
293 while (n--) { 293 while (n--) {
294 d1 = *src--; 294 d1 = *src--;
295 *dst-- = d0 >> right | d1 << left; 295 *dst-- = d0 << left | d1 >> right;
296 d0 = d1; 296 d0 = d1;
297 } 297 }
298 298
299 /* Trailing bits */ 299 /* Trailing bits */
300 if (last) { 300 if (m) {
301 if (m <= left) { 301 if (m <= bits - left) {
302 /* Single source word */ 302 /* Single source word */
303 *dst = comp(d0 >> right, *dst, last); 303 d0 <<= left;
304 } else { 304 } else {
305 /* 2 source words */ 305 /* 2 source words */
306 d1 = *src; 306 d1 = *src;
307 *dst = comp(d0 >> right | d1 << left, 307 d0 = d0 << left | d1 >> right;
308 *dst, last);
309 } 308 }
309 *dst = comp(d0, *dst, last);
310 } 310 }
311 } 311 }
312 } 312 }
@@ -317,9 +317,9 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area)
317 u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy; 317 u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
318 u32 height = area->height, width = area->width; 318 u32 height = area->height, width = area->width;
319 unsigned long const bits_per_line = p->fix.line_length*8u; 319 unsigned long const bits_per_line = p->fix.line_length*8u;
320 unsigned long *dst = NULL, *src = NULL; 320 unsigned long *base = NULL;
321 int bits = BITS_PER_LONG, bytes = bits >> 3; 321 int bits = BITS_PER_LONG, bytes = bits >> 3;
322 int dst_idx = 0, src_idx = 0, rev_copy = 0; 322 unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
323 323
324 if (p->state != FBINFO_STATE_RUNNING) 324 if (p->state != FBINFO_STATE_RUNNING)
325 return; 325 return;
@@ -334,8 +334,7 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area)
334 334
335 /* split the base of the framebuffer into a long-aligned address and 335 /* split the base of the framebuffer into a long-aligned address and
336 the index of the first bit */ 336 the index of the first bit */
337 dst = src = (unsigned long *)((unsigned long)p->screen_base & 337 base = (unsigned long *)((unsigned long)p->screen_base & ~(bytes-1));
338 ~(bytes-1));
339 dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1)); 338 dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1));
340 /* add offset of source and target area */ 339 /* add offset of source and target area */
341 dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel; 340 dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel;
@@ -348,20 +347,14 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area)
348 while (height--) { 347 while (height--) {
349 dst_idx -= bits_per_line; 348 dst_idx -= bits_per_line;
350 src_idx -= bits_per_line; 349 src_idx -= bits_per_line;
351 dst += dst_idx >> (ffs(bits) - 1); 350 bitcpy_rev(p, base + (dst_idx / bits), dst_idx % bits,
352 dst_idx &= (bytes - 1); 351 base + (src_idx / bits), src_idx % bits, bits,
353 src += src_idx >> (ffs(bits) - 1);
354 src_idx &= (bytes - 1);
355 bitcpy_rev(p, dst, dst_idx, src, src_idx, bits,
356 width*p->var.bits_per_pixel); 352 width*p->var.bits_per_pixel);
357 } 353 }
358 } else { 354 } else {
359 while (height--) { 355 while (height--) {
360 dst += dst_idx >> (ffs(bits) - 1); 356 bitcpy(p, base + (dst_idx / bits), dst_idx % bits,
361 dst_idx &= (bytes - 1); 357 base + (src_idx / bits), src_idx % bits, bits,
362 src += src_idx >> (ffs(bits) - 1);
363 src_idx &= (bytes - 1);
364 bitcpy(p, dst, dst_idx, src, src_idx, bits,
365 width*p->var.bits_per_pixel); 358 width*p->var.bits_per_pixel);
366 dst_idx += bits_per_line; 359 dst_idx += bits_per_line;
367 src_idx += bits_per_line; 360 src_idx += bits_per_line;
diff --git a/drivers/video/fbdev/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c
index 2794ba11f332..9bee8744c438 100644
--- a/drivers/video/fbdev/geode/gx1fb_core.c
+++ b/drivers/video/fbdev/geode/gx1fb_core.c
@@ -374,10 +374,8 @@ static int gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
374 release_mem_region(gx1_gx_base() + 0x8300, 0x100); 374 release_mem_region(gx1_gx_base() + 0x8300, 0x100);
375 } 375 }
376 376
377 if (info) { 377 fb_dealloc_cmap(&info->cmap);
378 fb_dealloc_cmap(&info->cmap); 378 framebuffer_release(info);
379 framebuffer_release(info);
380 }
381 379
382 return ret; 380 return ret;
383} 381}
diff --git a/drivers/video/fbdev/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c
index 1790f14bab15..124d7c7e2d14 100644
--- a/drivers/video/fbdev/geode/gxfb_core.c
+++ b/drivers/video/fbdev/geode/gxfb_core.c
@@ -444,10 +444,8 @@ static int gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
444 pci_release_region(pdev, 1); 444 pci_release_region(pdev, 1);
445 } 445 }
446 446
447 if (info) { 447 fb_dealloc_cmap(&info->cmap);
448 fb_dealloc_cmap(&info->cmap); 448 framebuffer_release(info);
449 framebuffer_release(info);
450 }
451 return ret; 449 return ret;
452} 450}
453 451
diff --git a/drivers/video/fbdev/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c
index 9e1d19d673a1..138da6cb6cbc 100644
--- a/drivers/video/fbdev/geode/lxfb_core.c
+++ b/drivers/video/fbdev/geode/lxfb_core.c
@@ -577,10 +577,8 @@ err:
577 pci_release_region(pdev, 3); 577 pci_release_region(pdev, 3);
578 } 578 }
579 579
580 if (info) { 580 fb_dealloc_cmap(&info->cmap);
581 fb_dealloc_cmap(&info->cmap); 581 framebuffer_release(info);
582 framebuffer_release(info);
583 }
584 582
585 return ret; 583 return ret;
586} 584}
diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c
index 5ff9fe2116a4..15d3ccff2965 100644
--- a/drivers/video/fbdev/hgafb.c
+++ b/drivers/video/fbdev/hgafb.c
@@ -417,8 +417,7 @@ static int hgafb_pan_display(struct fb_var_screeninfo *var,
417 struct fb_info *info) 417 struct fb_info *info)
418{ 418{
419 if (var->vmode & FB_VMODE_YWRAP) { 419 if (var->vmode & FB_VMODE_YWRAP) {
420 if (var->yoffset < 0 || 420 if (var->yoffset >= info->var.yres_virtual ||
421 var->yoffset >= info->var.yres_virtual ||
422 var->xoffset) 421 var->xoffset)
423 return -EINVAL; 422 return -EINVAL;
424 } else { 423 } else {
diff --git a/drivers/video/fbdev/mmp/Makefile b/drivers/video/fbdev/mmp/Makefile
index a014cb358bf8..924dd0930cc7 100644
--- a/drivers/video/fbdev/mmp/Makefile
+++ b/drivers/video/fbdev/mmp/Makefile
@@ -1 +1,3 @@
1obj-y += core.o hw/ panel/ fb/ 1obj-$(CONFIG_MMP_DISP) += mmp_disp.o hw/ panel/ fb/
2
3mmp_disp-y += core.o
diff --git a/drivers/video/fbdev/mmp/fb/Kconfig b/drivers/video/fbdev/mmp/fb/Kconfig
index 9b0141f105f5..985e1a7cd254 100644
--- a/drivers/video/fbdev/mmp/fb/Kconfig
+++ b/drivers/video/fbdev/mmp/fb/Kconfig
@@ -1,7 +1,7 @@
1if MMP_DISP 1if MMP_DISP
2 2
3config MMP_FB 3config MMP_FB
4 bool "fb driver for Marvell MMP Display Subsystem" 4 tristate "fb driver for Marvell MMP Display Subsystem"
5 depends on FB 5 depends on FB
6 select FB_CFB_FILLRECT 6 select FB_CFB_FILLRECT
7 select FB_CFB_COPYAREA 7 select FB_CFB_COPYAREA
diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
index 7f9dc9bec309..de9819660ca0 100644
--- a/drivers/video/fbdev/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
@@ -61,7 +61,7 @@ struct ocfb_dev {
61 /* flag indicating whether the regs are little endian accessed */ 61 /* flag indicating whether the regs are little endian accessed */
62 int little_endian; 62 int little_endian;
63 /* Physical and virtual addresses of framebuffer */ 63 /* Physical and virtual addresses of framebuffer */
64 phys_addr_t fb_phys; 64 dma_addr_t fb_phys;
65 void __iomem *fb_virt; 65 void __iomem *fb_virt;
66 u32 pseudo_palette[PALETTE_SIZE]; 66 u32 pseudo_palette[PALETTE_SIZE];
67}; 67};
diff --git a/drivers/video/fbdev/omap2/displays-new/Kconfig b/drivers/video/fbdev/omap2/displays-new/Kconfig
index e6cfc38160d3..574710141a61 100644
--- a/drivers/video/fbdev/omap2/displays-new/Kconfig
+++ b/drivers/video/fbdev/omap2/displays-new/Kconfig
@@ -1,6 +1,12 @@
1menu "OMAP Display Device Drivers (new device model)" 1menu "OMAP Display Device Drivers (new device model)"
2 depends on OMAP2_DSS 2 depends on OMAP2_DSS
3 3
4config DISPLAY_ENCODER_OPA362
5 tristate "OPA362 external analog amplifier"
6 help
7 Driver for OPA362 external analog TV amplifier controlled
8 through a GPIO.
9
4config DISPLAY_ENCODER_TFP410 10config DISPLAY_ENCODER_TFP410
5 tristate "TFP410 DPI to DVI Encoder" 11 tristate "TFP410 DPI to DVI Encoder"
6 help 12 help
diff --git a/drivers/video/fbdev/omap2/displays-new/Makefile b/drivers/video/fbdev/omap2/displays-new/Makefile
index 0323a8a1c682..9aa176bfbf2e 100644
--- a/drivers/video/fbdev/omap2/displays-new/Makefile
+++ b/drivers/video/fbdev/omap2/displays-new/Makefile
@@ -1,3 +1,4 @@
1obj-$(CONFIG_DISPLAY_ENCODER_OPA362) += encoder-opa362.o
1obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o 2obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o
2obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o 3obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o
3obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o 4obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
index 9a2b5ce58545..8511c648a15c 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
@@ -208,7 +208,7 @@ static int tvc_probe_pdata(struct platform_device *pdev)
208 ddata->in = in; 208 ddata->in = in;
209 209
210 ddata->connector_type = pdata->connector_type; 210 ddata->connector_type = pdata->connector_type;
211 ddata->invert_polarity = ddata->invert_polarity; 211 ddata->invert_polarity = pdata->invert_polarity;
212 212
213 dssdev = &ddata->dssdev; 213 dssdev = &ddata->dssdev;
214 dssdev->name = pdata->name; 214 dssdev->name = pdata->name;
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c b/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c
new file mode 100644
index 000000000000..84a6b3367124
--- /dev/null
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c
@@ -0,0 +1,285 @@
1/*
2 * OPA362 analog video amplifier with output/power control
3 *
4 * Copyright (C) 2014 Golden Delicious Computers
5 * Author: H. Nikolaus Schaller <hns@goldelico.com>
6 *
7 * based on encoder-tfp410
8 *
9 * Copyright (C) 2013 Texas Instruments
10 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published by
14 * the Free Software Foundation.
15 */
16
17#include <linux/gpio.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <linux/of_gpio.h>
22
23#include <video/omapdss.h>
24
25struct panel_drv_data {
26 struct omap_dss_device dssdev;
27 struct omap_dss_device *in;
28
29 struct gpio_desc *enable_gpio;
30
31 struct omap_video_timings timings;
32};
33
34#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
35
36static int opa362_connect(struct omap_dss_device *dssdev,
37 struct omap_dss_device *dst)
38{
39 struct panel_drv_data *ddata = to_panel_data(dssdev);
40 struct omap_dss_device *in = ddata->in;
41 int r;
42
43 dev_dbg(dssdev->dev, "connect\n");
44
45 if (omapdss_device_is_connected(dssdev))
46 return -EBUSY;
47
48 r = in->ops.atv->connect(in, dssdev);
49 if (r)
50 return r;
51
52 dst->src = dssdev;
53 dssdev->dst = dst;
54
55 return 0;
56}
57
58static void opa362_disconnect(struct omap_dss_device *dssdev,
59 struct omap_dss_device *dst)
60{
61 struct panel_drv_data *ddata = to_panel_data(dssdev);
62 struct omap_dss_device *in = ddata->in;
63
64 dev_dbg(dssdev->dev, "disconnect\n");
65
66 WARN_ON(!omapdss_device_is_connected(dssdev));
67 if (!omapdss_device_is_connected(dssdev))
68 return;
69
70 WARN_ON(dst != dssdev->dst);
71 if (dst != dssdev->dst)
72 return;
73
74 dst->src = NULL;
75 dssdev->dst = NULL;
76
77 in->ops.atv->disconnect(in, &ddata->dssdev);
78}
79
80static int opa362_enable(struct omap_dss_device *dssdev)
81{
82 struct panel_drv_data *ddata = to_panel_data(dssdev);
83 struct omap_dss_device *in = ddata->in;
84 int r;
85
86 dev_dbg(dssdev->dev, "enable\n");
87
88 if (!omapdss_device_is_connected(dssdev))
89 return -ENODEV;
90
91 if (omapdss_device_is_enabled(dssdev))
92 return 0;
93
94 in->ops.atv->set_timings(in, &ddata->timings);
95
96 r = in->ops.atv->enable(in);
97 if (r)
98 return r;
99
100 if (ddata->enable_gpio)
101 gpiod_set_value_cansleep(ddata->enable_gpio, 1);
102
103 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
104
105 return 0;
106}
107
108static void opa362_disable(struct omap_dss_device *dssdev)
109{
110 struct panel_drv_data *ddata = to_panel_data(dssdev);
111 struct omap_dss_device *in = ddata->in;
112
113 dev_dbg(dssdev->dev, "disable\n");
114
115 if (!omapdss_device_is_enabled(dssdev))
116 return;
117
118 if (ddata->enable_gpio)
119 gpiod_set_value_cansleep(ddata->enable_gpio, 0);
120
121 in->ops.atv->disable(in);
122
123 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
124}
125
126static void opa362_set_timings(struct omap_dss_device *dssdev,
127 struct omap_video_timings *timings)
128{
129 struct panel_drv_data *ddata = to_panel_data(dssdev);
130 struct omap_dss_device *in = ddata->in;
131
132 dev_dbg(dssdev->dev, "set_timings\n");
133
134 ddata->timings = *timings;
135 dssdev->panel.timings = *timings;
136
137 in->ops.atv->set_timings(in, timings);
138}
139
140static void opa362_get_timings(struct omap_dss_device *dssdev,
141 struct omap_video_timings *timings)
142{
143 struct panel_drv_data *ddata = to_panel_data(dssdev);
144
145 dev_dbg(dssdev->dev, "get_timings\n");
146
147 *timings = ddata->timings;
148}
149
150static int opa362_check_timings(struct omap_dss_device *dssdev,
151 struct omap_video_timings *timings)
152{
153 struct panel_drv_data *ddata = to_panel_data(dssdev);
154 struct omap_dss_device *in = ddata->in;
155
156 dev_dbg(dssdev->dev, "check_timings\n");
157
158 return in->ops.atv->check_timings(in, timings);
159}
160
161static void opa362_set_type(struct omap_dss_device *dssdev,
162 enum omap_dss_venc_type type)
163{
164 /* we can only drive a COMPOSITE output */
165 WARN_ON(type != OMAP_DSS_VENC_TYPE_COMPOSITE);
166
167}
168
169static const struct omapdss_atv_ops opa362_atv_ops = {
170 .connect = opa362_connect,
171 .disconnect = opa362_disconnect,
172
173 .enable = opa362_enable,
174 .disable = opa362_disable,
175
176 .check_timings = opa362_check_timings,
177 .set_timings = opa362_set_timings,
178 .get_timings = opa362_get_timings,
179
180 .set_type = opa362_set_type,
181};
182
183static int opa362_probe(struct platform_device *pdev)
184{
185 struct device_node *node = pdev->dev.of_node;
186 struct panel_drv_data *ddata;
187 struct omap_dss_device *dssdev, *in;
188 struct gpio_desc *gpio;
189 int r;
190
191 dev_dbg(&pdev->dev, "probe\n");
192
193 if (node == NULL) {
194 dev_err(&pdev->dev, "Unable to find device tree\n");
195 return -EINVAL;
196 }
197
198 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
199 if (!ddata)
200 return -ENOMEM;
201
202 platform_set_drvdata(pdev, ddata);
203
204 gpio = devm_gpiod_get(&pdev->dev, "enable");
205 if (IS_ERR(gpio)) {
206 if (PTR_ERR(gpio) != -ENOENT)
207 return PTR_ERR(gpio);
208
209 gpio = NULL;
210 } else {
211 gpiod_direction_output(gpio, 0);
212 }
213
214 ddata->enable_gpio = gpio;
215
216 in = omapdss_of_find_source_for_first_ep(node);
217 if (IS_ERR(in)) {
218 dev_err(&pdev->dev, "failed to find video source\n");
219 return PTR_ERR(in);
220 }
221
222 ddata->in = in;
223
224 dssdev = &ddata->dssdev;
225 dssdev->ops.atv = &opa362_atv_ops;
226 dssdev->dev = &pdev->dev;
227 dssdev->type = OMAP_DISPLAY_TYPE_VENC;
228 dssdev->output_type = OMAP_DISPLAY_TYPE_VENC;
229 dssdev->owner = THIS_MODULE;
230
231 r = omapdss_register_output(dssdev);
232 if (r) {
233 dev_err(&pdev->dev, "Failed to register output\n");
234 goto err_reg;
235 }
236
237 return 0;
238err_reg:
239 omap_dss_put_device(ddata->in);
240 return r;
241}
242
243static int __exit opa362_remove(struct platform_device *pdev)
244{
245 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
246 struct omap_dss_device *dssdev = &ddata->dssdev;
247 struct omap_dss_device *in = ddata->in;
248
249 omapdss_unregister_output(&ddata->dssdev);
250
251 WARN_ON(omapdss_device_is_enabled(dssdev));
252 if (omapdss_device_is_enabled(dssdev))
253 opa362_disable(dssdev);
254
255 WARN_ON(omapdss_device_is_connected(dssdev));
256 if (omapdss_device_is_connected(dssdev))
257 opa362_disconnect(dssdev, dssdev->dst);
258
259 omap_dss_put_device(in);
260
261 return 0;
262}
263
264static const struct of_device_id opa362_of_match[] = {
265 { .compatible = "omapdss,ti,opa362", },
266 {},
267};
268MODULE_DEVICE_TABLE(of, opa362_of_match);
269
270static struct platform_driver opa362_driver = {
271 .probe = opa362_probe,
272 .remove = __exit_p(opa362_remove),
273 .driver = {
274 .name = "amplifier-opa362",
275 .owner = THIS_MODULE,
276 .of_match_table = opa362_of_match,
277 .suppress_bind_attrs = true,
278 },
279};
280
281module_platform_driver(opa362_driver);
282
283MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
284MODULE_DESCRIPTION("OPA362 analog video amplifier with output/power control");
285MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index 7f3e11b16c86..990af6baeb0f 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -29,33 +29,10 @@ struct panel_drv_data {
29 int hpd_gpio; 29 int hpd_gpio;
30 30
31 struct omap_video_timings timings; 31 struct omap_video_timings timings;
32
33 struct completion hpd_completion;
34}; 32};
35 33
36#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) 34#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
37 35
38static irqreturn_t tpd_hpd_irq_handler(int irq, void *data)
39{
40 struct panel_drv_data *ddata = data;
41 bool hpd;
42
43 hpd = gpio_get_value_cansleep(ddata->hpd_gpio);
44
45 dev_dbg(ddata->dssdev.dev, "hpd %d\n", hpd);
46
47 if (gpio_is_valid(ddata->ls_oe_gpio)) {
48 if (hpd)
49 gpio_set_value_cansleep(ddata->ls_oe_gpio, 1);
50 else
51 gpio_set_value_cansleep(ddata->ls_oe_gpio, 0);
52 }
53
54 complete_all(&ddata->hpd_completion);
55
56 return IRQ_HANDLED;
57}
58
59static int tpd_connect(struct omap_dss_device *dssdev, 36static int tpd_connect(struct omap_dss_device *dssdev,
60 struct omap_dss_device *dst) 37 struct omap_dss_device *dst)
61{ 38{
@@ -70,23 +47,10 @@ static int tpd_connect(struct omap_dss_device *dssdev,
70 dst->src = dssdev; 47 dst->src = dssdev;
71 dssdev->dst = dst; 48 dssdev->dst = dst;
72 49
73 reinit_completion(&ddata->hpd_completion);
74
75 gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1); 50 gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1);
76 /* DC-DC converter needs at max 300us to get to 90% of 5V */ 51 /* DC-DC converter needs at max 300us to get to 90% of 5V */
77 udelay(300); 52 udelay(300);
78 53
79 /*
80 * If there's a cable connected, wait for the hpd irq to trigger,
81 * which turns on the level shifters.
82 */
83 if (gpio_get_value_cansleep(ddata->hpd_gpio)) {
84 unsigned long to;
85 to = wait_for_completion_timeout(&ddata->hpd_completion,
86 msecs_to_jiffies(250));
87 WARN_ON_ONCE(to == 0);
88 }
89
90 return 0; 54 return 0;
91} 55}
92 56
@@ -179,11 +143,20 @@ static int tpd_read_edid(struct omap_dss_device *dssdev,
179{ 143{
180 struct panel_drv_data *ddata = to_panel_data(dssdev); 144 struct panel_drv_data *ddata = to_panel_data(dssdev);
181 struct omap_dss_device *in = ddata->in; 145 struct omap_dss_device *in = ddata->in;
146 int r;
182 147
183 if (!gpio_get_value_cansleep(ddata->hpd_gpio)) 148 if (!gpio_get_value_cansleep(ddata->hpd_gpio))
184 return -ENODEV; 149 return -ENODEV;
185 150
186 return in->ops.hdmi->read_edid(in, edid, len); 151 if (gpio_is_valid(ddata->ls_oe_gpio))
152 gpio_set_value_cansleep(ddata->ls_oe_gpio, 1);
153
154 r = in->ops.hdmi->read_edid(in, edid, len);
155
156 if (gpio_is_valid(ddata->ls_oe_gpio))
157 gpio_set_value_cansleep(ddata->ls_oe_gpio, 0);
158
159 return r;
187} 160}
188 161
189static bool tpd_detect(struct omap_dss_device *dssdev) 162static bool tpd_detect(struct omap_dss_device *dssdev)
@@ -309,8 +282,6 @@ static int tpd_probe(struct platform_device *pdev)
309 282
310 platform_set_drvdata(pdev, ddata); 283 platform_set_drvdata(pdev, ddata);
311 284
312 init_completion(&ddata->hpd_completion);
313
314 if (dev_get_platdata(&pdev->dev)) { 285 if (dev_get_platdata(&pdev->dev)) {
315 r = tpd_probe_pdata(pdev); 286 r = tpd_probe_pdata(pdev);
316 if (r) 287 if (r)
@@ -340,13 +311,6 @@ static int tpd_probe(struct platform_device *pdev)
340 if (r) 311 if (r)
341 goto err_gpio; 312 goto err_gpio;
342 313
343 r = devm_request_threaded_irq(&pdev->dev, gpio_to_irq(ddata->hpd_gpio),
344 NULL, tpd_hpd_irq_handler,
345 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
346 IRQF_ONESHOT, "hpd", ddata);
347 if (r)
348 goto err_irq;
349
350 dssdev = &ddata->dssdev; 314 dssdev = &ddata->dssdev;
351 dssdev->ops.hdmi = &tpd_hdmi_ops; 315 dssdev->ops.hdmi = &tpd_hdmi_ops;
352 dssdev->dev = &pdev->dev; 316 dssdev->dev = &pdev->dev;
@@ -365,7 +329,6 @@ static int tpd_probe(struct platform_device *pdev)
365 329
366 return 0; 330 return 0;
367err_reg: 331err_reg:
368err_irq:
369err_gpio: 332err_gpio:
370 omap_dss_put_device(ddata->in); 333 omap_dss_put_device(ddata->in);
371 return r; 334 return r;
diff --git a/drivers/video/fbdev/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile
index 2ea9d382354c..b5136d3d4b77 100644
--- a/drivers/video/fbdev/omap2/dss/Makefile
+++ b/drivers/video/fbdev/omap2/dss/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o
2obj-$(CONFIG_OMAP2_DSS) += omapdss.o 2obj-$(CONFIG_OMAP2_DSS) += omapdss.o
3# Core DSS files 3# Core DSS files
4omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ 4omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
5 output.o dss-of.o pll.o 5 output.o dss-of.o pll.o video-pll.o
6# DSS compat layer files 6# DSS compat layer files
7omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ 7omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
8 dispc-compat.o display-sysfs.o 8 dispc-compat.o display-sysfs.o
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 9850d9ef9a9d..31b743c70272 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -36,6 +36,9 @@
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/pm_runtime.h> 37#include <linux/pm_runtime.h>
38#include <linux/sizes.h> 38#include <linux/sizes.h>
39#include <linux/mfd/syscon.h>
40#include <linux/regmap.h>
41#include <linux/of.h>
39 42
40#include <video/omapdss.h> 43#include <video/omapdss.h>
41 44
@@ -117,6 +120,9 @@ static struct {
117 const struct dispc_features *feat; 120 const struct dispc_features *feat;
118 121
119 bool is_enabled; 122 bool is_enabled;
123
124 struct regmap *syscon_pol;
125 u32 syscon_pol_offset;
120} dispc; 126} dispc;
121 127
122enum omap_color_component { 128enum omap_color_component {
@@ -2958,6 +2964,25 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
2958 FLD_VAL(vsync_level, 12, 12); 2964 FLD_VAL(vsync_level, 12, 12);
2959 2965
2960 dispc_write_reg(DISPC_POL_FREQ(channel), l); 2966 dispc_write_reg(DISPC_POL_FREQ(channel), l);
2967
2968 if (dispc.syscon_pol) {
2969 const int shifts[] = {
2970 [OMAP_DSS_CHANNEL_LCD] = 0,
2971 [OMAP_DSS_CHANNEL_LCD2] = 1,
2972 [OMAP_DSS_CHANNEL_LCD3] = 2,
2973 };
2974
2975 u32 mask, val;
2976
2977 mask = (1 << 0) | (1 << 3) | (1 << 6);
2978 val = (rf << 0) | (ipc << 3) | (onoff << 6);
2979
2980 mask <<= 16 + shifts[channel];
2981 val <<= 16 + shifts[channel];
2982
2983 regmap_update_bits(dispc.syscon_pol, dispc.syscon_pol_offset,
2984 mask, val);
2985 }
2961} 2986}
2962 2987
2963/* change name to mode? */ 2988/* change name to mode? */
@@ -3037,10 +3062,16 @@ unsigned long dispc_fclk_rate(void)
3037 break; 3062 break;
3038 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 3063 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
3039 pll = dss_pll_find("dsi0"); 3064 pll = dss_pll_find("dsi0");
3065 if (!pll)
3066 pll = dss_pll_find("video0");
3067
3040 r = pll->cinfo.clkout[0]; 3068 r = pll->cinfo.clkout[0];
3041 break; 3069 break;
3042 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 3070 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
3043 pll = dss_pll_find("dsi1"); 3071 pll = dss_pll_find("dsi1");
3072 if (!pll)
3073 pll = dss_pll_find("video1");
3074
3044 r = pll->cinfo.clkout[0]; 3075 r = pll->cinfo.clkout[0];
3045 break; 3076 break;
3046 default: 3077 default:
@@ -3069,10 +3100,16 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
3069 break; 3100 break;
3070 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 3101 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
3071 pll = dss_pll_find("dsi0"); 3102 pll = dss_pll_find("dsi0");
3103 if (!pll)
3104 pll = dss_pll_find("video0");
3105
3072 r = pll->cinfo.clkout[0]; 3106 r = pll->cinfo.clkout[0];
3073 break; 3107 break;
3074 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 3108 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
3075 pll = dss_pll_find("dsi1"); 3109 pll = dss_pll_find("dsi1");
3110 if (!pll)
3111 pll = dss_pll_find("video1");
3112
3076 r = pll->cinfo.clkout[0]; 3113 r = pll->cinfo.clkout[0];
3077 break; 3114 break;
3078 default: 3115 default:
@@ -3668,6 +3705,7 @@ static int __init dispc_init_features(struct platform_device *pdev)
3668 break; 3705 break;
3669 3706
3670 case OMAPDSS_VER_OMAP5: 3707 case OMAPDSS_VER_OMAP5:
3708 case OMAPDSS_VER_DRA7xx:
3671 src = &omap54xx_dispc_feats; 3709 src = &omap54xx_dispc_feats;
3672 break; 3710 break;
3673 3711
@@ -3728,6 +3766,7 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
3728 u32 rev; 3766 u32 rev;
3729 int r = 0; 3767 int r = 0;
3730 struct resource *dispc_mem; 3768 struct resource *dispc_mem;
3769 struct device_node *np = pdev->dev.of_node;
3731 3770
3732 dispc.pdev = pdev; 3771 dispc.pdev = pdev;
3733 3772
@@ -3754,6 +3793,20 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
3754 return -ENODEV; 3793 return -ENODEV;
3755 } 3794 }
3756 3795
3796 if (np && of_property_read_bool(np, "syscon-pol")) {
3797 dispc.syscon_pol = syscon_regmap_lookup_by_phandle(np, "syscon-pol");
3798 if (IS_ERR(dispc.syscon_pol)) {
3799 dev_err(&pdev->dev, "failed to get syscon-pol regmap\n");
3800 return PTR_ERR(dispc.syscon_pol);
3801 }
3802
3803 if (of_property_read_u32_index(np, "syscon-pol", 1,
3804 &dispc.syscon_pol_offset)) {
3805 dev_err(&pdev->dev, "failed to get syscon-pol offset\n");
3806 return -EINVAL;
3807 }
3808 }
3809
3757 pm_runtime_enable(&pdev->dev); 3810 pm_runtime_enable(&pdev->dev);
3758 3811
3759 r = dispc_runtime_get(); 3812 r = dispc_runtime_get();
@@ -3832,6 +3885,7 @@ static const struct of_device_id dispc_of_match[] = {
3832 { .compatible = "ti,omap3-dispc", }, 3885 { .compatible = "ti,omap3-dispc", },
3833 { .compatible = "ti,omap4-dispc", }, 3886 { .compatible = "ti,omap4-dispc", },
3834 { .compatible = "ti,omap5-dispc", }, 3887 { .compatible = "ti,omap5-dispc", },
3888 { .compatible = "ti,dra7-dispc", },
3835 {}, 3889 {},
3836}; 3890};
3837 3891
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 9a2f8c3b102d..f83e7b030249 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -106,6 +106,17 @@ static struct dss_pll *dpi_get_pll(enum omap_channel channel)
106 return NULL; 106 return NULL;
107 } 107 }
108 108
109 case OMAPDSS_VER_DRA7xx:
110 switch (channel) {
111 case OMAP_DSS_CHANNEL_LCD:
112 case OMAP_DSS_CHANNEL_LCD2:
113 return dss_pll_find("video0");
114 case OMAP_DSS_CHANNEL_LCD3:
115 return dss_pll_find("video1");
116 default:
117 return NULL;
118 }
119
109 default: 120 default:
110 return NULL; 121 return NULL;
111 } 122 }
@@ -590,6 +601,10 @@ static void dpi_init_pll(struct dpi_data *dpi)
590 if (!pll) 601 if (!pll)
591 return; 602 return;
592 603
604 /* On DRA7 we need to set a mux to use the PLL */
605 if (omapdss_get_version() == OMAPDSS_VER_DRA7xx)
606 dss_ctrl_pll_set_control_mux(pll->id, dpi->output.dispc_channel);
607
593 if (dpi_verify_dsi_pll(pll)) { 608 if (dpi_verify_dsi_pll(pll)) {
594 DSSWARN("DSI PLL not operational\n"); 609 DSSWARN("DSI PLL not operational\n");
595 return; 610 return;
@@ -615,6 +630,17 @@ static enum omap_channel dpi_get_channel(int port_num)
615 case OMAPDSS_VER_AM43xx: 630 case OMAPDSS_VER_AM43xx:
616 return OMAP_DSS_CHANNEL_LCD; 631 return OMAP_DSS_CHANNEL_LCD;
617 632
633 case OMAPDSS_VER_DRA7xx:
634 switch (port_num) {
635 case 2:
636 return OMAP_DSS_CHANNEL_LCD3;
637 case 1:
638 return OMAP_DSS_CHANNEL_LCD2;
639 case 0:
640 default:
641 return OMAP_DSS_CHANNEL_LCD;
642 }
643
618 case OMAPDSS_VER_OMAP4430_ES1: 644 case OMAPDSS_VER_OMAP4430_ES1:
619 case OMAPDSS_VER_OMAP4430_ES2: 645 case OMAPDSS_VER_OMAP4430_ES2:
620 case OMAPDSS_VER_OMAP4: 646 case OMAPDSS_VER_OMAP4:
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 3e44c580b1f8..5081f6fb1737 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -5238,6 +5238,7 @@ static int dsi_init_pll_data(struct platform_device *dsidev)
5238 } 5238 }
5239 5239
5240 pll->name = dsi->module_id == 0 ? "dsi0" : "dsi1"; 5240 pll->name = dsi->module_id == 0 ? "dsi0" : "dsi1";
5241 pll->id = dsi->module_id == 0 ? DSS_PLL_DSI1 : DSS_PLL_DSI2;
5241 pll->clkin = clk; 5242 pll->clkin = clk;
5242 pll->base = dsi->pll_base; 5243 pll->base = dsi->pll_base;
5243 5244
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 9987154d50b4..a6d10d4279f3 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -34,7 +34,10 @@
34#include <linux/pm_runtime.h> 34#include <linux/pm_runtime.h>
35#include <linux/gfp.h> 35#include <linux/gfp.h>
36#include <linux/sizes.h> 36#include <linux/sizes.h>
37#include <linux/mfd/syscon.h>
38#include <linux/regmap.h>
37#include <linux/of.h> 39#include <linux/of.h>
40#include <linux/regulator/consumer.h>
38 41
39#include <video/omapdss.h> 42#include <video/omapdss.h>
40 43
@@ -63,14 +66,11 @@ struct dss_reg {
63#define REG_FLD_MOD(idx, val, start, end) \ 66#define REG_FLD_MOD(idx, val, start, end) \
64 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) 67 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
65 68
66static int dss_runtime_get(void);
67static void dss_runtime_put(void);
68
69struct dss_features { 69struct dss_features {
70 u8 fck_div_max; 70 u8 fck_div_max;
71 u8 dss_fck_multiplier; 71 u8 dss_fck_multiplier;
72 const char *parent_clk_name; 72 const char *parent_clk_name;
73 enum omap_display_type *ports; 73 const enum omap_display_type *ports;
74 int num_ports; 74 int num_ports;
75 int (*dpi_select_source)(int port, enum omap_channel channel); 75 int (*dpi_select_source)(int port, enum omap_channel channel);
76}; 76};
@@ -78,6 +78,8 @@ struct dss_features {
78static struct { 78static struct {
79 struct platform_device *pdev; 79 struct platform_device *pdev;
80 void __iomem *base; 80 void __iomem *base;
81 struct regmap *syscon_pll_ctrl;
82 u32 syscon_pll_ctrl_offset;
81 83
82 struct clk *parent_clk; 84 struct clk *parent_clk;
83 struct clk *dss_clk; 85 struct clk *dss_clk;
@@ -95,6 +97,9 @@ static struct {
95 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 97 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
96 98
97 const struct dss_features *feat; 99 const struct dss_features *feat;
100
101 struct dss_pll *video1_pll;
102 struct dss_pll *video2_pll;
98} dss; 103} dss;
99 104
100static const char * const dss_generic_clk_source_names[] = { 105static const char * const dss_generic_clk_source_names[] = {
@@ -158,6 +163,99 @@ static void dss_restore_context(void)
158#undef SR 163#undef SR
159#undef RR 164#undef RR
160 165
166void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
167{
168 unsigned shift;
169 unsigned val;
170
171 if (!dss.syscon_pll_ctrl)
172 return;
173
174 val = !enable;
175
176 switch (pll_id) {
177 case DSS_PLL_VIDEO1:
178 shift = 0;
179 break;
180 case DSS_PLL_VIDEO2:
181 shift = 1;
182 break;
183 case DSS_PLL_HDMI:
184 shift = 2;
185 break;
186 default:
187 DSSERR("illegal DSS PLL ID %d\n", pll_id);
188 return;
189 }
190
191 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
192 1 << shift, val << shift);
193}
194
195void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
196 enum omap_channel channel)
197{
198 unsigned shift, val;
199
200 if (!dss.syscon_pll_ctrl)
201 return;
202
203 switch (channel) {
204 case OMAP_DSS_CHANNEL_LCD:
205 shift = 3;
206
207 switch (pll_id) {
208 case DSS_PLL_VIDEO1:
209 val = 0; break;
210 case DSS_PLL_HDMI:
211 val = 1; break;
212 default:
213 DSSERR("error in PLL mux config for LCD\n");
214 return;
215 }
216
217 break;
218 case OMAP_DSS_CHANNEL_LCD2:
219 shift = 5;
220
221 switch (pll_id) {
222 case DSS_PLL_VIDEO1:
223 val = 0; break;
224 case DSS_PLL_VIDEO2:
225 val = 1; break;
226 case DSS_PLL_HDMI:
227 val = 2; break;
228 default:
229 DSSERR("error in PLL mux config for LCD2\n");
230 return;
231 }
232
233 break;
234 case OMAP_DSS_CHANNEL_LCD3:
235 shift = 7;
236
237 switch (pll_id) {
238 case DSS_PLL_VIDEO1:
239 val = 1; break;
240 case DSS_PLL_VIDEO2:
241 val = 0; break;
242 case DSS_PLL_HDMI:
243 val = 2; break;
244 default:
245 DSSERR("error in PLL mux config for LCD3\n");
246 return;
247 }
248
249 break;
250 default:
251 DSSERR("error in PLL mux config\n");
252 return;
253 }
254
255 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
256 0x3 << shift, val << shift);
257}
258
161void dss_sdi_init(int datapairs) 259void dss_sdi_init(int datapairs)
162{ 260{
163 u32 l; 261 u32 l;
@@ -605,6 +703,26 @@ static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
605 return 0; 703 return 0;
606} 704}
607 705
706static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
707{
708 switch (port) {
709 case 0:
710 return dss_dpi_select_source_omap5(port, channel);
711 case 1:
712 if (channel != OMAP_DSS_CHANNEL_LCD2)
713 return -EINVAL;
714 break;
715 case 2:
716 if (channel != OMAP_DSS_CHANNEL_LCD3)
717 return -EINVAL;
718 break;
719 default:
720 return -EINVAL;
721 }
722
723 return 0;
724}
725
608int dss_dpi_select_source(int port, enum omap_channel channel) 726int dss_dpi_select_source(int port, enum omap_channel channel)
609{ 727{
610 return dss.feat->dpi_select_source(port, channel); 728 return dss.feat->dpi_select_source(port, channel);
@@ -643,7 +761,7 @@ static void dss_put_clocks(void)
643 clk_put(dss.parent_clk); 761 clk_put(dss.parent_clk);
644} 762}
645 763
646static int dss_runtime_get(void) 764int dss_runtime_get(void)
647{ 765{
648 int r; 766 int r;
649 767
@@ -654,7 +772,7 @@ static int dss_runtime_get(void)
654 return r < 0 ? r : 0; 772 return r < 0 ? r : 0;
655} 773}
656 774
657static void dss_runtime_put(void) 775void dss_runtime_put(void)
658{ 776{
659 int r; 777 int r;
660 778
@@ -677,15 +795,21 @@ void dss_debug_dump_clocks(struct seq_file *s)
677#endif 795#endif
678 796
679 797
680static enum omap_display_type omap2plus_ports[] = { 798static const enum omap_display_type omap2plus_ports[] = {
681 OMAP_DISPLAY_TYPE_DPI, 799 OMAP_DISPLAY_TYPE_DPI,
682}; 800};
683 801
684static enum omap_display_type omap34xx_ports[] = { 802static const enum omap_display_type omap34xx_ports[] = {
685 OMAP_DISPLAY_TYPE_DPI, 803 OMAP_DISPLAY_TYPE_DPI,
686 OMAP_DISPLAY_TYPE_SDI, 804 OMAP_DISPLAY_TYPE_SDI,
687}; 805};
688 806
807static const enum omap_display_type dra7xx_ports[] = {
808 OMAP_DISPLAY_TYPE_DPI,
809 OMAP_DISPLAY_TYPE_DPI,
810 OMAP_DISPLAY_TYPE_DPI,
811};
812
689static const struct dss_features omap24xx_dss_feats __initconst = { 813static const struct dss_features omap24xx_dss_feats __initconst = {
690 /* 814 /*
691 * fck div max is really 16, but the divider range has gaps. The range 815 * fck div max is really 16, but the divider range has gaps. The range
@@ -744,6 +868,15 @@ static const struct dss_features am43xx_dss_feats __initconst = {
744 .num_ports = ARRAY_SIZE(omap2plus_ports), 868 .num_ports = ARRAY_SIZE(omap2plus_ports),
745}; 869};
746 870
871static const struct dss_features dra7xx_dss_feats __initconst = {
872 .fck_div_max = 64,
873 .dss_fck_multiplier = 1,
874 .parent_clk_name = "dpll_per_x2_ck",
875 .dpi_select_source = &dss_dpi_select_source_dra7xx,
876 .ports = dra7xx_ports,
877 .num_ports = ARRAY_SIZE(dra7xx_ports),
878};
879
747static int __init dss_init_features(struct platform_device *pdev) 880static int __init dss_init_features(struct platform_device *pdev)
748{ 881{
749 const struct dss_features *src; 882 const struct dss_features *src;
@@ -784,6 +917,10 @@ static int __init dss_init_features(struct platform_device *pdev)
784 src = &am43xx_dss_feats; 917 src = &am43xx_dss_feats;
785 break; 918 break;
786 919
920 case OMAPDSS_VER_DRA7xx:
921 src = &dra7xx_dss_feats;
922 break;
923
787 default: 924 default:
788 return -ENODEV; 925 return -ENODEV;
789 } 926 }
@@ -884,8 +1021,10 @@ static void __exit dss_uninit_ports(struct platform_device *pdev)
884static int __init omap_dsshw_probe(struct platform_device *pdev) 1021static int __init omap_dsshw_probe(struct platform_device *pdev)
885{ 1022{
886 struct resource *dss_mem; 1023 struct resource *dss_mem;
1024 struct device_node *np = pdev->dev.of_node;
887 u32 rev; 1025 u32 rev;
888 int r; 1026 int r;
1027 struct regulator *pll_regulator;
889 1028
890 dss.pdev = pdev; 1029 dss.pdev = pdev;
891 1030
@@ -940,6 +1079,57 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
940 1079
941 dss_init_ports(pdev); 1080 dss_init_ports(pdev);
942 1081
1082 if (np && of_property_read_bool(np, "syscon-pll-ctrl")) {
1083 dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
1084 "syscon-pll-ctrl");
1085 if (IS_ERR(dss.syscon_pll_ctrl)) {
1086 dev_err(&pdev->dev,
1087 "failed to get syscon-pll-ctrl regmap\n");
1088 return PTR_ERR(dss.syscon_pll_ctrl);
1089 }
1090
1091 if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
1092 &dss.syscon_pll_ctrl_offset)) {
1093 dev_err(&pdev->dev,
1094 "failed to get syscon-pll-ctrl offset\n");
1095 return -EINVAL;
1096 }
1097 }
1098
1099 pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video");
1100 if (IS_ERR(pll_regulator)) {
1101 r = PTR_ERR(pll_regulator);
1102
1103 switch (r) {
1104 case -ENOENT:
1105 pll_regulator = NULL;
1106 break;
1107
1108 case -EPROBE_DEFER:
1109 return -EPROBE_DEFER;
1110
1111 default:
1112 DSSERR("can't get DPLL VDDA regulator\n");
1113 return r;
1114 }
1115 }
1116
1117 if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
1118 dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
1119 if (IS_ERR(dss.video1_pll)) {
1120 r = PTR_ERR(dss.video1_pll);
1121 goto err_pll_init;
1122 }
1123 }
1124
1125 if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
1126 dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
1127 if (IS_ERR(dss.video2_pll)) {
1128 r = PTR_ERR(dss.video2_pll);
1129 goto err_pll_init;
1130 }
1131 }
1132
943 rev = dss_read_reg(DSS_REVISION); 1133 rev = dss_read_reg(DSS_REVISION);
944 printk(KERN_INFO "OMAP DSS rev %d.%d\n", 1134 printk(KERN_INFO "OMAP DSS rev %d.%d\n",
945 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 1135 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -950,6 +1140,12 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
950 1140
951 return 0; 1141 return 0;
952 1142
1143err_pll_init:
1144 if (dss.video1_pll)
1145 dss_video_pll_uninit(dss.video1_pll);
1146
1147 if (dss.video2_pll)
1148 dss_video_pll_uninit(dss.video2_pll);
953err_runtime_get: 1149err_runtime_get:
954 pm_runtime_disable(&pdev->dev); 1150 pm_runtime_disable(&pdev->dev);
955err_setup_clocks: 1151err_setup_clocks:
@@ -959,6 +1155,12 @@ err_setup_clocks:
959 1155
960static int __exit omap_dsshw_remove(struct platform_device *pdev) 1156static int __exit omap_dsshw_remove(struct platform_device *pdev)
961{ 1157{
1158 if (dss.video1_pll)
1159 dss_video_pll_uninit(dss.video1_pll);
1160
1161 if (dss.video2_pll)
1162 dss_video_pll_uninit(dss.video2_pll);
1163
962 dss_uninit_ports(pdev); 1164 dss_uninit_ports(pdev);
963 1165
964 pm_runtime_disable(&pdev->dev); 1166 pm_runtime_disable(&pdev->dev);
@@ -1003,6 +1205,7 @@ static const struct of_device_id dss_of_match[] = {
1003 { .compatible = "ti,omap3-dss", }, 1205 { .compatible = "ti,omap3-dss", },
1004 { .compatible = "ti,omap4-dss", }, 1206 { .compatible = "ti,omap4-dss", },
1005 { .compatible = "ti,omap5-dss", }, 1207 { .compatible = "ti,omap5-dss", },
1208 { .compatible = "ti,dra7-dss", },
1006 {}, 1209 {},
1007}; 1210};
1008 1211
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 14fb0c23f4a2..4812eee2622a 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -100,6 +100,14 @@ enum dss_writeback_channel {
100 DSS_WB_LCD3_MGR = 7, 100 DSS_WB_LCD3_MGR = 7,
101}; 101};
102 102
103enum dss_pll_id {
104 DSS_PLL_DSI1,
105 DSS_PLL_DSI2,
106 DSS_PLL_HDMI,
107 DSS_PLL_VIDEO1,
108 DSS_PLL_VIDEO2,
109};
110
103struct dss_pll; 111struct dss_pll;
104 112
105#define DSS_PLL_MAX_HSDIVS 4 113#define DSS_PLL_MAX_HSDIVS 4
@@ -150,6 +158,7 @@ struct dss_pll_hw {
150 158
151struct dss_pll { 159struct dss_pll {
152 const char *name; 160 const char *name;
161 enum dss_pll_id id;
153 162
154 struct clk *clkin; 163 struct clk *clkin;
155 struct regulator *regulator; 164 struct regulator *regulator;
@@ -250,6 +259,9 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
250int dss_init_platform_driver(void) __init; 259int dss_init_platform_driver(void) __init;
251void dss_uninit_platform_driver(void); 260void dss_uninit_platform_driver(void);
252 261
262int dss_runtime_get(void);
263void dss_runtime_put(void);
264
253unsigned long dss_get_dispc_clk_rate(void); 265unsigned long dss_get_dispc_clk_rate(void);
254int dss_dpi_select_source(int port, enum omap_channel channel); 266int dss_dpi_select_source(int port, enum omap_channel channel);
255void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 267void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
@@ -257,6 +269,11 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
257const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 269const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
258void dss_dump_clocks(struct seq_file *s); 270void dss_dump_clocks(struct seq_file *s);
259 271
272/* DSS VIDEO PLL */
273struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
274 struct regulator *regulator);
275void dss_video_pll_uninit(struct dss_pll *pll);
276
260/* dss-of */ 277/* dss-of */
261struct device_node *dss_of_port_get_parent_device(struct device_node *port); 278struct device_node *dss_of_port_get_parent_device(struct device_node *port);
262u32 dss_of_port_get_port_number(struct device_node *port); 279u32 dss_of_port_get_port_number(struct device_node *port);
@@ -265,6 +282,10 @@ u32 dss_of_port_get_port_number(struct device_node *port);
265void dss_debug_dump_clocks(struct seq_file *s); 282void dss_debug_dump_clocks(struct seq_file *s);
266#endif 283#endif
267 284
285void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
286void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
287 enum omap_channel channel);
288
268void dss_sdi_init(int datapairs); 289void dss_sdi_init(int datapairs);
269int dss_sdi_enable(void); 290int dss_sdi_enable(void);
270void dss_sdi_disable(void); 291void dss_sdi_disable(void);
@@ -446,5 +467,6 @@ int dss_pll_write_config_type_a(struct dss_pll *pll,
446 const struct dss_pll_clock_info *cinfo); 467 const struct dss_pll_clock_info *cinfo);
447int dss_pll_write_config_type_b(struct dss_pll *pll, 468int dss_pll_write_config_type_b(struct dss_pll *pll,
448 const struct dss_pll_clock_info *cinfo); 469 const struct dss_pll_clock_info *cinfo);
470int dss_pll_wait_reset_done(struct dss_pll *pll);
449 471
450#endif 472#endif
diff --git a/drivers/video/fbdev/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c
index 0e3da809473c..376270b777f8 100644
--- a/drivers/video/fbdev/omap2/dss/dss_features.c
+++ b/drivers/video/fbdev/omap2/dss/dss_features.c
@@ -223,7 +223,7 @@ static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
223 OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2, 223 OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
224 224
225 /* OMAP_DSS_CHANNEL_DIGIT */ 225 /* OMAP_DSS_CHANNEL_DIGIT */
226 OMAP_DSS_OUTPUT_HDMI | OMAP_DSS_OUTPUT_DPI, 226 OMAP_DSS_OUTPUT_HDMI,
227 227
228 /* OMAP_DSS_CHANNEL_LCD2 */ 228 /* OMAP_DSS_CHANNEL_LCD2 */
229 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 229 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
@@ -943,6 +943,7 @@ void dss_features_init(enum omapdss_version version)
943 break; 943 break;
944 944
945 case OMAPDSS_VER_OMAP5: 945 case OMAPDSS_VER_OMAP5:
946 case OMAPDSS_VER_DRA7xx:
946 omap_current_dss_features = &omap5_dss_features; 947 omap_current_dss_features = &omap5_dss_features;
947 break; 948 break;
948 949
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index 39aae3aa7136..3f0b34a7031a 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -787,6 +787,7 @@ static const struct dev_pm_ops hdmi_pm_ops = {
787 787
788static const struct of_device_id hdmi_of_match[] = { 788static const struct of_device_id hdmi_of_match[] = {
789 { .compatible = "ti,omap5-hdmi", }, 789 { .compatible = "ti,omap5-hdmi", },
790 { .compatible = "ti,dra7-hdmi", },
790 {}, 791 {},
791}; 792};
792 793
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
index bc9e07d2afbe..1f5d19c119ce 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_phy.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
@@ -208,6 +208,7 @@ static int hdmi_phy_init_features(struct platform_device *pdev)
208 break; 208 break;
209 209
210 case OMAPDSS_VER_OMAP5: 210 case OMAPDSS_VER_OMAP5:
211 case OMAPDSS_VER_DRA7xx:
211 src = &omap54xx_phy_feats; 212 src = &omap54xx_phy_feats;
212 break; 213 break;
213 214
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index ac83ef5cfd7d..06e23a7c432c 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -104,6 +104,8 @@ static int hdmi_pll_enable(struct dss_pll *dsspll)
104 struct hdmi_wp_data *wp = pll->wp; 104 struct hdmi_wp_data *wp = pll->wp;
105 u16 r = 0; 105 u16 r = 0;
106 106
107 dss_ctrl_pll_enable(DSS_PLL_HDMI, true);
108
107 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); 109 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
108 if (r) 110 if (r)
109 return r; 111 return r;
@@ -117,6 +119,8 @@ static void hdmi_pll_disable(struct dss_pll *dsspll)
117 struct hdmi_wp_data *wp = pll->wp; 119 struct hdmi_wp_data *wp = pll->wp;
118 120
119 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 121 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
122
123 dss_ctrl_pll_enable(DSS_PLL_HDMI, false);
120} 124}
121 125
122static const struct dss_pll_ops dsi_pll_ops = { 126static const struct dss_pll_ops dsi_pll_ops = {
@@ -185,6 +189,7 @@ static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data
185 } 189 }
186 190
187 pll->name = "hdmi"; 191 pll->name = "hdmi";
192 pll->id = DSS_PLL_HDMI;
188 pll->base = hpll->base; 193 pll->base = hpll->base;
189 pll->clkin = clk; 194 pll->clkin = clk;
190 195
@@ -196,6 +201,7 @@ static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data
196 break; 201 break;
197 202
198 case OMAPDSS_VER_OMAP5: 203 case OMAPDSS_VER_OMAP5:
204 case OMAPDSS_VER_DRA7xx:
199 pll->hw = &dss_omap5_hdmi_pll_hw; 205 pll->hw = &dss_omap5_hdmi_pll_hw;
200 break; 206 break;
201 207
diff --git a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
index 2f0822ee3ff9..42b87f95267c 100644
--- a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
+++ b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
@@ -186,6 +186,7 @@ static const struct of_device_id omapdss_of_match[] __initconst = {
186 { .compatible = "ti,omap3-dss", }, 186 { .compatible = "ti,omap3-dss", },
187 { .compatible = "ti,omap4-dss", }, 187 { .compatible = "ti,omap4-dss", },
188 { .compatible = "ti,omap5-dss", }, 188 { .compatible = "ti,omap5-dss", },
189 { .compatible = "ti,dra7-dss", },
189 {}, 190 {},
190}; 191};
191 192
diff --git a/drivers/video/fbdev/omap2/dss/pll.c b/drivers/video/fbdev/omap2/dss/pll.c
index 335ffac224b9..f974ddcd3b6e 100644
--- a/drivers/video/fbdev/omap2/dss/pll.c
+++ b/drivers/video/fbdev/omap2/dss/pll.c
@@ -222,6 +222,16 @@ static int wait_for_bit_change(void __iomem *reg, int bitnum, int value)
222 return !value; 222 return !value;
223} 223}
224 224
225int dss_pll_wait_reset_done(struct dss_pll *pll)
226{
227 void __iomem *base = pll->base;
228
229 if (wait_for_bit_change(base + PLL_STATUS, 0, 1) != 1)
230 return -ETIMEDOUT;
231 else
232 return 0;
233}
234
225static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask) 235static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask)
226{ 236{
227 int t = 100; 237 int t = 100;
diff --git a/drivers/video/fbdev/omap2/dss/video-pll.c b/drivers/video/fbdev/omap2/dss/video-pll.c
new file mode 100644
index 000000000000..b1ec59e42940
--- /dev/null
+++ b/drivers/video/fbdev/omap2/dss/video-pll.c
@@ -0,0 +1,211 @@
1/*
2* Copyright (C) 2014 Texas Instruments Ltd
3*
4* This program is free software; you can redistribute it and/or modify it
5* under the terms of the GNU General Public License version 2 as published by
6* the Free Software Foundation.
7*
8* You should have received a copy of the GNU General Public License along with
9* this program. If not, see <http://www.gnu.org/licenses/>.
10*/
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18#include <linux/sched.h>
19
20#include <video/omapdss.h>
21
22#include "dss.h"
23#include "dss_features.h"
24
25struct dss_video_pll {
26 struct dss_pll pll;
27
28 struct device *dev;
29
30 void __iomem *clkctrl_base;
31};
32
33#define REG_MOD(reg, val, start, end) \
34 writel_relaxed(FLD_MOD(readl_relaxed(reg), val, start, end), reg)
35
36static void dss_dpll_enable_scp_clk(struct dss_video_pll *vpll)
37{
38 REG_MOD(vpll->clkctrl_base, 1, 14, 14); /* CIO_CLK_ICG */
39}
40
41static void dss_dpll_disable_scp_clk(struct dss_video_pll *vpll)
42{
43 REG_MOD(vpll->clkctrl_base, 0, 14, 14); /* CIO_CLK_ICG */
44}
45
46static void dss_dpll_power_enable(struct dss_video_pll *vpll)
47{
48 REG_MOD(vpll->clkctrl_base, 2, 31, 30); /* PLL_POWER_ON_ALL */
49
50 /*
51 * DRA7x PLL CTRL's PLL_PWR_STATUS seems to always return 0,
52 * so we have to use fixed delay here.
53 */
54 msleep(1);
55}
56
57static void dss_dpll_power_disable(struct dss_video_pll *vpll)
58{
59 REG_MOD(vpll->clkctrl_base, 0, 31, 30); /* PLL_POWER_OFF */
60}
61
62static int dss_video_pll_enable(struct dss_pll *pll)
63{
64 struct dss_video_pll *vpll = container_of(pll, struct dss_video_pll, pll);
65 int r;
66
67 r = dss_runtime_get();
68 if (r)
69 return r;
70
71 dss_ctrl_pll_enable(pll->id, true);
72
73 dss_dpll_enable_scp_clk(vpll);
74
75 r = dss_pll_wait_reset_done(pll);
76 if (r)
77 goto err_reset;
78
79 dss_dpll_power_enable(vpll);
80
81 return 0;
82
83err_reset:
84 dss_dpll_disable_scp_clk(vpll);
85 dss_ctrl_pll_enable(pll->id, false);
86 dss_runtime_put();
87
88 return r;
89}
90
91static void dss_video_pll_disable(struct dss_pll *pll)
92{
93 struct dss_video_pll *vpll = container_of(pll, struct dss_video_pll, pll);
94
95 dss_dpll_power_disable(vpll);
96
97 dss_dpll_disable_scp_clk(vpll);
98
99 dss_ctrl_pll_enable(pll->id, false);
100
101 dss_runtime_put();
102}
103
104static const struct dss_pll_ops dss_pll_ops = {
105 .enable = dss_video_pll_enable,
106 .disable = dss_video_pll_disable,
107 .set_config = dss_pll_write_config_type_a,
108};
109
110static const struct dss_pll_hw dss_dra7_video_pll_hw = {
111 .n_max = (1 << 8) - 1,
112 .m_max = (1 << 12) - 1,
113 .mX_max = (1 << 5) - 1,
114 .fint_min = 500000,
115 .fint_max = 2500000,
116 .clkdco_max = 1800000000,
117
118 .n_msb = 8,
119 .n_lsb = 1,
120 .m_msb = 20,
121 .m_lsb = 9,
122
123 .mX_msb[0] = 25,
124 .mX_lsb[0] = 21,
125 .mX_msb[1] = 30,
126 .mX_lsb[1] = 26,
127
128 .has_refsel = true,
129};
130
131struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
132 struct regulator *regulator)
133{
134 const char * const reg_name[] = { "pll1", "pll2" };
135 const char * const clkctrl_name[] = { "pll1_clkctrl", "pll2_clkctrl" };
136 const char * const clkin_name[] = { "video1_clk", "video2_clk" };
137
138 struct resource *res;
139 struct dss_video_pll *vpll;
140 void __iomem *pll_base, *clkctrl_base;
141 struct clk *clk;
142 struct dss_pll *pll;
143 int r;
144
145 /* PLL CONTROL */
146
147 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, reg_name[id]);
148 if (!res) {
149 dev_err(&pdev->dev,
150 "missing platform resource data for pll%d\n", id);
151 return ERR_PTR(-ENODEV);
152 }
153
154 pll_base = devm_ioremap_resource(&pdev->dev, res);
155 if (IS_ERR(pll_base)) {
156 dev_err(&pdev->dev, "failed to ioremap pll%d reg_name\n", id);
157 return ERR_CAST(pll_base);
158 }
159
160 /* CLOCK CONTROL */
161
162 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
163 clkctrl_name[id]);
164 if (!res) {
165 dev_err(&pdev->dev,
166 "missing platform resource data for pll%d\n", id);
167 return ERR_PTR(-ENODEV);
168 }
169
170 clkctrl_base = devm_ioremap_resource(&pdev->dev, res);
171 if (IS_ERR(clkctrl_base)) {
172 dev_err(&pdev->dev, "failed to ioremap pll%d clkctrl\n", id);
173 return ERR_CAST(clkctrl_base);
174 }
175
176 /* CLKIN */
177
178 clk = devm_clk_get(&pdev->dev, clkin_name[id]);
179 if (IS_ERR(clk)) {
180 DSSERR("can't get video pll clkin\n");
181 return ERR_CAST(clk);
182 }
183
184 vpll = devm_kzalloc(&pdev->dev, sizeof(*vpll), GFP_KERNEL);
185 if (!vpll)
186 return ERR_PTR(-ENOMEM);
187
188 vpll->dev = &pdev->dev;
189 vpll->clkctrl_base = clkctrl_base;
190
191 pll = &vpll->pll;
192
193 pll->name = id == 0 ? "video0" : "video1";
194 pll->id = id == 0 ? DSS_PLL_VIDEO1 : DSS_PLL_VIDEO2;
195 pll->clkin = clk;
196 pll->regulator = regulator;
197 pll->base = pll_base;
198 pll->hw = &dss_dra7_video_pll_hw;
199 pll->ops = &dss_pll_ops;
200
201 r = dss_pll_register(pll);
202 if (r)
203 return ERR_PTR(r);
204
205 return pll;
206}
207
208void dss_video_pll_uninit(struct dss_pll *pll)
209{
210 dss_pll_unregister(pll);
211}
diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
index 146b6f5428db..9ddfdd63b84c 100644
--- a/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
@@ -137,8 +137,11 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
137 goto undo; 137 goto undo;
138 } 138 }
139 139
140 if (ovl->manager) 140 if (ovl->manager) {
141 ovl->manager->apply(ovl->manager); 141 r = ovl->manager->apply(ovl->manager);
142 if (r)
143 goto undo;
144 }
142 145
143 if (pi->enabled) { 146 if (pi->enabled) {
144 r = ovl->enable(ovl); 147 r = ovl->enable(ovl);
diff --git a/drivers/video/fbdev/savage/savagefb.h b/drivers/video/fbdev/savage/savagefb.h
index dcaab9012ca2..8ff4ab1cb69b 100644
--- a/drivers/video/fbdev/savage/savagefb.h
+++ b/drivers/video/fbdev/savage/savagefb.h
@@ -351,32 +351,26 @@ static inline void VGAwSEQ(u8 index, u8 val, struct savagefb_par *par)
351 351
352static inline void VGAenablePalette(struct savagefb_par *par) 352static inline void VGAenablePalette(struct savagefb_par *par)
353{ 353{
354 u8 tmp; 354 vga_in8(0x3da, par);
355
356 tmp = vga_in8(0x3da, par);
357 vga_out8(0x3c0, 0x00, par); 355 vga_out8(0x3c0, 0x00, par);
358 par->paletteEnabled = 1; 356 par->paletteEnabled = 1;
359} 357}
360 358
361static inline void VGAdisablePalette(struct savagefb_par *par) 359static inline void VGAdisablePalette(struct savagefb_par *par)
362{ 360{
363 u8 tmp; 361 vga_in8(0x3da, par);
364
365 tmp = vga_in8(0x3da, par);
366 vga_out8(0x3c0, 0x20, par); 362 vga_out8(0x3c0, 0x20, par);
367 par->paletteEnabled = 0; 363 par->paletteEnabled = 0;
368} 364}
369 365
370static inline void VGAwATTR(u8 index, u8 value, struct savagefb_par *par) 366static inline void VGAwATTR(u8 index, u8 value, struct savagefb_par *par)
371{ 367{
372 u8 tmp;
373
374 if (par->paletteEnabled) 368 if (par->paletteEnabled)
375 index &= ~0x20; 369 index &= ~0x20;
376 else 370 else
377 index |= 0x20; 371 index |= 0x20;
378 372
379 tmp = vga_in8(0x3da, par); 373 vga_in8(0x3da, par);
380 vga_out8(0x3c0, index, par); 374 vga_out8(0x3c0, index, par);
381 vga_out8 (0x3c0, value, par); 375 vga_out8 (0x3c0, value, par);
382} 376}
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index f4daa59f0a80..f7ed6d9016f7 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -122,23 +122,6 @@ static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd)
122 return ret; 122 return ret;
123} 123}
124 124
125static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
126{
127 struct ssd1307fb_array *array;
128 int ret;
129
130 array = ssd1307fb_alloc_array(1, SSD1307FB_DATA);
131 if (!array)
132 return -ENOMEM;
133
134 array->data[0] = data;
135
136 ret = ssd1307fb_write_array(client, array, 1);
137 kfree(array);
138
139 return ret;
140}
141
142static void ssd1307fb_update_display(struct ssd1307fb_par *par) 125static void ssd1307fb_update_display(struct ssd1307fb_par *par)
143{ 126{
144 struct ssd1307fb_array *array; 127 struct ssd1307fb_array *array;
@@ -320,7 +303,10 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
320 303
321 /* Set initial contrast */ 304 /* Set initial contrast */
322 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST); 305 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST);
323 ret = ret & ssd1307fb_write_cmd(par->client, 0x7f); 306 if (ret < 0)
307 return ret;
308
309 ret = ssd1307fb_write_cmd(par->client, 0x7f);
324 if (ret < 0) 310 if (ret < 0)
325 return ret; 311 return ret;
326 312
@@ -336,63 +322,99 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
336 322
337 /* Set multiplex ratio value */ 323 /* Set multiplex ratio value */
338 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_MULTIPLEX_RATIO); 324 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_MULTIPLEX_RATIO);
339 ret = ret & ssd1307fb_write_cmd(par->client, par->height - 1); 325 if (ret < 0)
326 return ret;
327
328 ret = ssd1307fb_write_cmd(par->client, par->height - 1);
340 if (ret < 0) 329 if (ret < 0)
341 return ret; 330 return ret;
342 331
343 /* set display offset value */ 332 /* set display offset value */
344 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_DISPLAY_OFFSET); 333 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_DISPLAY_OFFSET);
334 if (ret < 0)
335 return ret;
336
345 ret = ssd1307fb_write_cmd(par->client, 0x20); 337 ret = ssd1307fb_write_cmd(par->client, 0x20);
346 if (ret < 0) 338 if (ret < 0)
347 return ret; 339 return ret;
348 340
349 /* Set clock frequency */ 341 /* Set clock frequency */
350 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_CLOCK_FREQ); 342 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_CLOCK_FREQ);
351 ret = ret & ssd1307fb_write_cmd(par->client, 0xf0); 343 if (ret < 0)
344 return ret;
345
346 ret = ssd1307fb_write_cmd(par->client, 0xf0);
352 if (ret < 0) 347 if (ret < 0)
353 return ret; 348 return ret;
354 349
355 /* Set precharge period in number of ticks from the internal clock */ 350 /* Set precharge period in number of ticks from the internal clock */
356 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PRECHARGE_PERIOD); 351 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PRECHARGE_PERIOD);
357 ret = ret & ssd1307fb_write_cmd(par->client, 0x22); 352 if (ret < 0)
353 return ret;
354
355 ret = ssd1307fb_write_cmd(par->client, 0x22);
358 if (ret < 0) 356 if (ret < 0)
359 return ret; 357 return ret;
360 358
361 /* Set COM pins configuration */ 359 /* Set COM pins configuration */
362 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COM_PINS_CONFIG); 360 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COM_PINS_CONFIG);
363 ret = ret & ssd1307fb_write_cmd(par->client, 0x22); 361 if (ret < 0)
362 return ret;
363
364 ret = ssd1307fb_write_cmd(par->client, 0x22);
364 if (ret < 0) 365 if (ret < 0)
365 return ret; 366 return ret;
366 367
367 /* Set VCOMH */ 368 /* Set VCOMH */
368 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_VCOMH); 369 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_VCOMH);
369 ret = ret & ssd1307fb_write_cmd(par->client, 0x49); 370 if (ret < 0)
371 return ret;
372
373 ret = ssd1307fb_write_cmd(par->client, 0x49);
370 if (ret < 0) 374 if (ret < 0)
371 return ret; 375 return ret;
372 376
373 /* Turn on the DC-DC Charge Pump */ 377 /* Turn on the DC-DC Charge Pump */
374 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CHARGE_PUMP); 378 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CHARGE_PUMP);
375 ret = ret & ssd1307fb_write_cmd(par->client, 0x14); 379 if (ret < 0)
380 return ret;
381
382 ret = ssd1307fb_write_cmd(par->client, 0x14);
376 if (ret < 0) 383 if (ret < 0)
377 return ret; 384 return ret;
378 385
379 /* Switch to horizontal addressing mode */ 386 /* Switch to horizontal addressing mode */
380 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_ADDRESS_MODE); 387 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_ADDRESS_MODE);
381 ret = ret & ssd1307fb_write_cmd(par->client, 388 if (ret < 0)
382 SSD1307FB_SET_ADDRESS_MODE_HORIZONTAL); 389 return ret;
390
391 ret = ssd1307fb_write_cmd(par->client,
392 SSD1307FB_SET_ADDRESS_MODE_HORIZONTAL);
383 if (ret < 0) 393 if (ret < 0)
384 return ret; 394 return ret;
385 395
386 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE); 396 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE);
387 ret = ret & ssd1307fb_write_cmd(par->client, 0x0); 397 if (ret < 0)
388 ret = ret & ssd1307fb_write_cmd(par->client, par->width - 1); 398 return ret;
399
400 ret = ssd1307fb_write_cmd(par->client, 0x0);
401 if (ret < 0)
402 return ret;
403
404 ret = ssd1307fb_write_cmd(par->client, par->width - 1);
389 if (ret < 0) 405 if (ret < 0)
390 return ret; 406 return ret;
391 407
392 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE); 408 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE);
393 ret = ret & ssd1307fb_write_cmd(par->client, 0x0); 409 if (ret < 0)
394 ret = ret & ssd1307fb_write_cmd(par->client, 410 return ret;
395 par->page_offset + (par->height / 8) - 1); 411
412 ret = ssd1307fb_write_cmd(par->client, 0x0);
413 if (ret < 0)
414 return ret;
415
416 ret = ssd1307fb_write_cmd(par->client,
417 par->page_offset + (par->height / 8) - 1);
396 if (ret < 0) 418 if (ret < 0)
397 return ret; 419 return ret;
398 420
@@ -460,7 +482,7 @@ static int ssd1307fb_probe(struct i2c_client *client,
460 par->width = 96; 482 par->width = 96;
461 483
462 if (of_property_read_u32(node, "solomon,height", &par->height)) 484 if (of_property_read_u32(node, "solomon,height", &par->height))
463 par->width = 16; 485 par->height = 16;
464 486
465 if (of_property_read_u32(node, "solomon,page-offset", &par->page_offset)) 487 if (of_property_read_u32(node, "solomon,page-offset", &par->page_offset))
466 par->page_offset = 1; 488 par->page_offset = 1;
diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c
index ffaf29eeaaba..1a1176bf0906 100644
--- a/drivers/video/fbdev/vt8500lcdfb.c
+++ b/drivers/video/fbdev/vt8500lcdfb.c
@@ -113,10 +113,8 @@ static int vt8500lcd_set_par(struct fb_info *info)
113 } 113 }
114 114
115 for (i = 0; i < 8; i++) { 115 for (i = 0; i < 8; i++) {
116 if (bpp_values[i] == info->var.bits_per_pixel) { 116 if (bpp_values[i] == info->var.bits_per_pixel)
117 reg_bpp = i; 117 reg_bpp = i;
118 continue;
119 }
120 } 118 }
121 119
122 control0 = readl(fbi->regbase) & ~0xf; 120 control0 = readl(fbi->regbase) & ~0xf;
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index b91c466225b9..548c751d2415 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -2,7 +2,7 @@
2 * linux/drivers/video/vgastate.c -- VGA state save/restore 2 * linux/drivers/video/vgastate.c -- VGA state save/restore
3 * 3 *
4 * Copyright 2002 James Simmons 4 * Copyright 2002 James Simmons
5 * 5 *
6 * Copyright history from vga16fb.c: 6 * Copyright history from vga16fb.c:
7 * Copyright 1999 Ben Pfaff and Petr Vandrovec 7 * Copyright 1999 Ben Pfaff and Petr Vandrovec
8 * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm 8 * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
@@ -10,7 +10,7 @@
10 * 10 *
11 * This file is subject to the terms and conditions of the GNU General 11 * This file is subject to the terms and conditions of the GNU General
12 * Public License. See the file COPYING in the main directory of this 12 * Public License. See the file COPYING in the main directory of this
13 * archive for more details. 13 * archive for more details.
14 * 14 *
15 */ 15 */
16#include <linux/module.h> 16#include <linux/module.h>
@@ -29,16 +29,16 @@ struct regstate {
29 __u8 *gfx; 29 __u8 *gfx;
30 __u8 *seq; 30 __u8 *seq;
31 __u8 misc; 31 __u8 misc;
32}; 32};
33 33
34static inline unsigned char vga_rcrtcs(void __iomem *regbase, unsigned short iobase, 34static inline unsigned char vga_rcrtcs(void __iomem *regbase, unsigned short iobase,
35 unsigned char reg) 35 unsigned char reg)
36{ 36{
37 vga_w(regbase, iobase + 0x4, reg); 37 vga_w(regbase, iobase + 0x4, reg);
38 return vga_r(regbase, iobase + 0x5); 38 return vga_r(regbase, iobase + 0x5);
39} 39}
40 40
41static inline void vga_wcrtcs(void __iomem *regbase, unsigned short iobase, 41static inline void vga_wcrtcs(void __iomem *regbase, unsigned short iobase,
42 unsigned char reg, unsigned char val) 42 unsigned char reg, unsigned char val)
43{ 43{
44 vga_w(regbase, iobase + 0x4, reg); 44 vga_w(regbase, iobase + 0x4, reg);
@@ -71,7 +71,7 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
71 gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC); 71 gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC);
72 seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); 72 seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
73 seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); 73 seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
74 74
75 /* blank screen */ 75 /* blank screen */
76 seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); 76 seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
77 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); 77 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -85,7 +85,7 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
85 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2); 85 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2);
86 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); 86 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
87 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); 87 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
88 for (i = 0; i < 4 * 8192; i++) 88 for (i = 0; i < 4 * 8192; i++)
89 saved->vga_font0[i] = vga_r(fbbase, i); 89 saved->vga_font0[i] = vga_r(fbbase, i);
90 } 90 }
91 91
@@ -96,10 +96,10 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
96 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3); 96 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3);
97 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); 97 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
98 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); 98 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
99 for (i = 0; i < state->memsize; i++) 99 for (i = 0; i < state->memsize; i++)
100 saved->vga_font1[i] = vga_r(fbbase, i); 100 saved->vga_font1[i] = vga_r(fbbase, i);
101 } 101 }
102 102
103 /* save font at plane 0/1 */ 103 /* save font at plane 0/1 */
104 if (state->flags & VGA_SAVE_TEXT) { 104 if (state->flags & VGA_SAVE_TEXT) {
105 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1); 105 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1);
@@ -107,7 +107,7 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
107 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0); 107 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0);
108 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); 108 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
109 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); 109 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
110 for (i = 0; i < 8192; i++) 110 for (i = 0; i < 8192; i++)
111 saved->vga_text[i] = vga_r(fbbase, i); 111 saved->vga_text[i] = vga_r(fbbase, i);
112 112
113 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2); 113 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2);
@@ -115,8 +115,8 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
115 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1); 115 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1);
116 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); 116 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
117 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); 117 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
118 for (i = 0; i < 8192; i++) 118 for (i = 0; i < 8192; i++)
119 saved->vga_text[8192+i] = vga_r(fbbase + 2 * 8192, i); 119 saved->vga_text[8192+i] = vga_r(fbbase + 2 * 8192, i);
120 } 120 }
121 121
122 /* restore regs */ 122 /* restore regs */
@@ -151,7 +151,7 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
151 gr8 = vga_rgfx(state->vgabase, VGA_GFX_BIT_MASK); 151 gr8 = vga_rgfx(state->vgabase, VGA_GFX_BIT_MASK);
152 seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); 152 seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
153 seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); 153 seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
154 154
155 /* blank screen */ 155 /* blank screen */
156 seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); 156 seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
157 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); 157 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -163,7 +163,7 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
163 vga_wgfx(state->vgabase, VGA_GFX_BIT_MASK, 0xff); 163 vga_wgfx(state->vgabase, VGA_GFX_BIT_MASK, 0xff);
164 vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, 0x00); 164 vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, 0x00);
165 } 165 }
166 166
167 /* restore font at plane 2 */ 167 /* restore font at plane 2 */
168 if (state->flags & VGA_SAVE_FONT0) { 168 if (state->flags & VGA_SAVE_FONT0) {
169 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x4); 169 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x4);
@@ -171,7 +171,7 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
171 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2); 171 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2);
172 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); 172 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
173 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); 173 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
174 for (i = 0; i < 4 * 8192; i++) 174 for (i = 0; i < 4 * 8192; i++)
175 vga_w(fbbase, i, saved->vga_font0[i]); 175 vga_w(fbbase, i, saved->vga_font0[i]);
176 } 176 }
177 177
@@ -182,10 +182,10 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
182 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3); 182 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3);
183 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); 183 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
184 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); 184 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
185 for (i = 0; i < state->memsize; i++) 185 for (i = 0; i < state->memsize; i++)
186 vga_w(fbbase, i, saved->vga_font1[i]); 186 vga_w(fbbase, i, saved->vga_font1[i]);
187 } 187 }
188 188
189 /* restore font at plane 0/1 */ 189 /* restore font at plane 0/1 */
190 if (state->flags & VGA_SAVE_TEXT) { 190 if (state->flags & VGA_SAVE_TEXT) {
191 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1); 191 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1);
@@ -193,16 +193,16 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
193 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0); 193 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0);
194 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); 194 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
195 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); 195 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
196 for (i = 0; i < 8192; i++) 196 for (i = 0; i < 8192; i++)
197 vga_w(fbbase, i, saved->vga_text[i]); 197 vga_w(fbbase, i, saved->vga_text[i]);
198 198
199 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2); 199 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2);
200 vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); 200 vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
201 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1); 201 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1);
202 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); 202 vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
203 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); 203 vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
204 for (i = 0; i < 8192; i++) 204 for (i = 0; i < 8192; i++)
205 vga_w(fbbase, i, saved->vga_text[8192+i]); 205 vga_w(fbbase, i, saved->vga_text[8192+i]);
206 } 206 }
207 207
208 /* unblank screen */ 208 /* unblank screen */
@@ -222,7 +222,7 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
222 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2); 222 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2);
223 vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4); 223 vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4);
224} 224}
225 225
226static void save_vga_mode(struct vgastate *state) 226static void save_vga_mode(struct vgastate *state)
227{ 227{
228 struct regstate *saved = (struct regstate *) state->vidstate; 228 struct regstate *saved = (struct regstate *) state->vidstate;
@@ -235,10 +235,10 @@ static void save_vga_mode(struct vgastate *state)
235 else 235 else
236 iobase = 0x3b0; 236 iobase = 0x3b0;
237 237
238 for (i = 0; i < state->num_crtc; i++) 238 for (i = 0; i < state->num_crtc; i++)
239 saved->crtc[i] = vga_rcrtcs(state->vgabase, iobase, i); 239 saved->crtc[i] = vga_rcrtcs(state->vgabase, iobase, i);
240 240
241 vga_r(state->vgabase, iobase + 0xa); 241 vga_r(state->vgabase, iobase + 0xa);
242 vga_w(state->vgabase, VGA_ATT_W, 0x00); 242 vga_w(state->vgabase, VGA_ATT_W, 0x00);
243 for (i = 0; i < state->num_attr; i++) { 243 for (i = 0; i < state->num_attr; i++) {
244 vga_r(state->vgabase, iobase + 0xa); 244 vga_r(state->vgabase, iobase + 0xa);
@@ -247,10 +247,10 @@ static void save_vga_mode(struct vgastate *state)
247 vga_r(state->vgabase, iobase + 0xa); 247 vga_r(state->vgabase, iobase + 0xa);
248 vga_w(state->vgabase, VGA_ATT_W, 0x20); 248 vga_w(state->vgabase, VGA_ATT_W, 0x20);
249 249
250 for (i = 0; i < state->num_gfx; i++) 250 for (i = 0; i < state->num_gfx; i++)
251 saved->gfx[i] = vga_rgfx(state->vgabase, i); 251 saved->gfx[i] = vga_rgfx(state->vgabase, i);
252 252
253 for (i = 0; i < state->num_seq; i++) 253 for (i = 0; i < state->num_seq; i++)
254 saved->seq[i] = vga_rseq(state->vgabase, i); 254 saved->seq[i] = vga_rseq(state->vgabase, i);
255} 255}
256 256
@@ -268,26 +268,26 @@ static void restore_vga_mode(struct vgastate *state)
268 iobase = 0x3b0; 268 iobase = 0x3b0;
269 269
270 /* turn off display */ 270 /* turn off display */
271 vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, 271 vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE,
272 saved->seq[VGA_SEQ_CLOCK_MODE] | 0x20); 272 saved->seq[VGA_SEQ_CLOCK_MODE] | 0x20);
273 273
274 /* disable sequencer */ 274 /* disable sequencer */
275 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x01); 275 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x01);
276 276
277 /* enable palette addressing */ 277 /* enable palette addressing */
278 vga_r(state->vgabase, iobase + 0xa); 278 vga_r(state->vgabase, iobase + 0xa);
279 vga_w(state->vgabase, VGA_ATT_W, 0x00); 279 vga_w(state->vgabase, VGA_ATT_W, 0x00);
280 280
281 for (i = 2; i < state->num_seq; i++) 281 for (i = 2; i < state->num_seq; i++)
282 vga_wseq(state->vgabase, i, saved->seq[i]); 282 vga_wseq(state->vgabase, i, saved->seq[i]);
283 283
284 284
285 /* unprotect vga regs */ 285 /* unprotect vga regs */
286 vga_wcrtcs(state->vgabase, iobase, 17, saved->crtc[17] & ~0x80); 286 vga_wcrtcs(state->vgabase, iobase, 17, saved->crtc[17] & ~0x80);
287 for (i = 0; i < state->num_crtc; i++) 287 for (i = 0; i < state->num_crtc; i++)
288 vga_wcrtcs(state->vgabase, iobase, i, saved->crtc[i]); 288 vga_wcrtcs(state->vgabase, iobase, i, saved->crtc[i]);
289 289
290 for (i = 0; i < state->num_gfx; i++) 290 for (i = 0; i < state->num_gfx; i++)
291 vga_wgfx(state->vgabase, i, saved->gfx[i]); 291 vga_wgfx(state->vgabase, i, saved->gfx[i]);
292 292
293 for (i = 0; i < state->num_attr; i++) { 293 for (i = 0; i < state->num_attr; i++) {
@@ -298,7 +298,7 @@ static void restore_vga_mode(struct vgastate *state)
298 /* reenable sequencer */ 298 /* reenable sequencer */
299 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03); 299 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03);
300 /* turn display on */ 300 /* turn display on */
301 vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, 301 vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE,
302 saved->seq[VGA_SEQ_CLOCK_MODE] & ~(1 << 5)); 302 saved->seq[VGA_SEQ_CLOCK_MODE] & ~(1 << 5));
303 303
304 /* disable video/palette source */ 304 /* disable video/palette source */
@@ -312,7 +312,7 @@ static void save_vga_cmap(struct vgastate *state)
312 int i; 312 int i;
313 313
314 vga_w(state->vgabase, VGA_PEL_MSK, 0xff); 314 vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
315 315
316 /* assumes DAC is readable and writable */ 316 /* assumes DAC is readable and writable */
317 vga_w(state->vgabase, VGA_PEL_IR, 0x00); 317 vga_w(state->vgabase, VGA_PEL_IR, 0x00);
318 for (i = 0; i < 768; i++) 318 for (i = 0; i < 768; i++)
@@ -346,7 +346,7 @@ static void vga_cleanup(struct vgastate *state)
346 state->vidstate = NULL; 346 state->vidstate = NULL;
347 } 347 }
348} 348}
349 349
350int save_vga(struct vgastate *state) 350int save_vga(struct vgastate *state)
351{ 351{
352 struct regstate *saved; 352 struct regstate *saved;
@@ -357,7 +357,7 @@ int save_vga(struct vgastate *state)
357 return 1; 357 return 1;
358 358
359 state->vidstate = (void *)saved; 359 state->vidstate = (void *)saved;
360 360
361 if (state->flags & VGA_SAVE_CMAP) { 361 if (state->flags & VGA_SAVE_CMAP) {
362 saved->vga_cmap = vmalloc(768); 362 saved->vga_cmap = vmalloc(768);
363 if (!saved->vga_cmap) { 363 if (!saved->vga_cmap) {
@@ -403,7 +403,7 @@ int save_vga(struct vgastate *state)
403 } 403 }
404 if (!state->memsize) 404 if (!state->memsize)
405 state->memsize = 8 * 8192; 405 state->memsize = 8 * 8192;
406 406
407 if (!state->membase) 407 if (!state->membase)
408 state->membase = 0xA0000; 408 state->membase = 0xA0000;
409 409
@@ -414,7 +414,7 @@ int save_vga(struct vgastate *state)
414 return 1; 414 return 1;
415 } 415 }
416 416
417 /* 417 /*
418 * save only first 32K used by vgacon 418 * save only first 32K used by vgacon
419 */ 419 */
420 if (state->flags & VGA_SAVE_FONT0) { 420 if (state->flags & VGA_SAVE_FONT0) {
@@ -425,7 +425,7 @@ int save_vga(struct vgastate *state)
425 return 1; 425 return 1;
426 } 426 }
427 } 427 }
428 /* 428 /*
429 * largely unused, but if required by the caller 429 * largely unused, but if required by the caller
430 * we'll just save everything. 430 * we'll just save everything.
431 */ 431 */
@@ -448,7 +448,7 @@ int save_vga(struct vgastate *state)
448 return 1; 448 return 1;
449 } 449 }
450 } 450 }
451 451
452 save_vga_text(state, fbbase); 452 save_vga_text(state, fbbase);
453 iounmap(fbbase); 453 iounmap(fbbase);
454 } 454 }