diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 12:24:30 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 12:24:30 -0500 |
commit | e0c8453769fcaec654cd5870e84c63175658c842 (patch) | |
tree | e5f114f236689a8db8f44bcecb5c1f1e14462932 /drivers/video | |
parent | a323ae93a74f669d890926187c68c711895e3454 (diff) | |
parent | d6c2152b3efd73be265f426b5a1bb50ec436d999 (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')
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 | ||
78 | config DUMMY_CONSOLE_COLUMNS | 78 | config 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 | ||
86 | config DUMMY_CONSOLE_ROWS | 88 | config 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 | ||
94 | config FRAMEBUFFER_CONSOLE | 98 | config 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 | ||
32 | static const char *dummycon_startup(void) | 29 | static 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 | ||
147 | static int fbcon_set_origin(struct vc_data *); | 147 | static int fbcon_set_origin(struct vc_data *); |
148 | 148 | ||
149 | #define CURSOR_DRAW_DELAY (1) | ||
150 | |||
151 | static int vbl_cursor_cnt; | ||
152 | static int fbcon_cursor_noblink; | 149 | static 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 | ||
1335 | static int scrollback_phys_max = 0; | 1331 | static 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 | ||
1531 | config FB_VIA | 1531 | config 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 | ||
3951 | static const struct dmi_system_id atyfb_reboot_ids[] = { | 3951 | static 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 | }; |
3963 | static bool registered_notifier = false; | ||
3963 | 3964 | ||
3964 | static int __init atyfb_init(void) | 3965 | static 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 | ||
3991 | static void __exit atyfb_exit(void) | 3994 | static 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 | ||
498 | static int get_std_timing(unsigned char *block, struct fb_videomode *mode, | 498 | static 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 | ||
542 | static int get_dst_timing(unsigned char *block, | 557 | static 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 | */ |
604 | static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) | 619 | static 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 | }; |
472 | EXPORT_SYMBOL(vesa_modes); | 499 | EXPORT_SYMBOL(vesa_modes); |
500 | |||
501 | const 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 | }; | ||
583 | EXPORT_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 | ||
27 | static void | 27 | static void |
28 | bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx, | 28 | bitcpy(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 | ||
168 | static void | 169 | static void |
169 | bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx, | 170 | bitcpy_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 @@ | |||
1 | obj-y += core.o hw/ panel/ fb/ | 1 | obj-$(CONFIG_MMP_DISP) += mmp_disp.o hw/ panel/ fb/ |
2 | |||
3 | mmp_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 @@ | |||
1 | if MMP_DISP | 1 | if MMP_DISP |
2 | 2 | ||
3 | config MMP_FB | 3 | config 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 @@ | |||
1 | menu "OMAP Display Device Drivers (new device model)" | 1 | menu "OMAP Display Device Drivers (new device model)" |
2 | depends on OMAP2_DSS | 2 | depends on OMAP2_DSS |
3 | 3 | ||
4 | config 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 | |||
4 | config DISPLAY_ENCODER_TFP410 | 10 | config 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 @@ | |||
1 | obj-$(CONFIG_DISPLAY_ENCODER_OPA362) += encoder-opa362.o | ||
1 | obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o | 2 | obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o |
2 | obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o | 3 | obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o |
3 | obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o | 4 | obj-$(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 | |||
25 | struct 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 | |||
36 | static 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 | |||
58 | static 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 | |||
80 | static 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 | |||
108 | static 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 | |||
126 | static 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 | |||
140 | static 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 | |||
150 | static 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 | |||
161 | static 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 | |||
169 | static 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 | |||
183 | static 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; | ||
238 | err_reg: | ||
239 | omap_dss_put_device(ddata->in); | ||
240 | return r; | ||
241 | } | ||
242 | |||
243 | static 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 | |||
264 | static const struct of_device_id opa362_of_match[] = { | ||
265 | { .compatible = "omapdss,ti,opa362", }, | ||
266 | {}, | ||
267 | }; | ||
268 | MODULE_DEVICE_TABLE(of, opa362_of_match); | ||
269 | |||
270 | static 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 | |||
281 | module_platform_driver(opa362_driver); | ||
282 | |||
283 | MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>"); | ||
284 | MODULE_DESCRIPTION("OPA362 analog video amplifier with output/power control"); | ||
285 | MODULE_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 | ||
38 | static 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 | |||
59 | static int tpd_connect(struct omap_dss_device *dssdev, | 36 | static 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 | ||
189 | static bool tpd_detect(struct omap_dss_device *dssdev) | 162 | static 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; |
367 | err_reg: | 331 | err_reg: |
368 | err_irq: | ||
369 | err_gpio: | 332 | err_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 | |||
2 | obj-$(CONFIG_OMAP2_DSS) += omapdss.o | 2 | obj-$(CONFIG_OMAP2_DSS) += omapdss.o |
3 | # Core DSS files | 3 | # Core DSS files |
4 | omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ | 4 | omapdss-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 |
7 | omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ | 7 | omapdss-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 | ||
122 | enum omap_color_component { | 128 | enum 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 | ||
66 | static int dss_runtime_get(void); | ||
67 | static void dss_runtime_put(void); | ||
68 | |||
69 | struct dss_features { | 69 | struct 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 { | |||
78 | static struct { | 78 | static 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 | ||
100 | static const char * const dss_generic_clk_source_names[] = { | 105 | static 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 | ||
166 | void 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 | |||
195 | void 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 | |||
161 | void dss_sdi_init(int datapairs) | 259 | void 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 | ||
706 | static 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 | |||
608 | int dss_dpi_select_source(int port, enum omap_channel channel) | 726 | int 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 | ||
646 | static int dss_runtime_get(void) | 764 | int 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 | ||
657 | static void dss_runtime_put(void) | 775 | void 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 | ||
680 | static enum omap_display_type omap2plus_ports[] = { | 798 | static const enum omap_display_type omap2plus_ports[] = { |
681 | OMAP_DISPLAY_TYPE_DPI, | 799 | OMAP_DISPLAY_TYPE_DPI, |
682 | }; | 800 | }; |
683 | 801 | ||
684 | static enum omap_display_type omap34xx_ports[] = { | 802 | static 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 | ||
807 | static const enum omap_display_type dra7xx_ports[] = { | ||
808 | OMAP_DISPLAY_TYPE_DPI, | ||
809 | OMAP_DISPLAY_TYPE_DPI, | ||
810 | OMAP_DISPLAY_TYPE_DPI, | ||
811 | }; | ||
812 | |||
689 | static const struct dss_features omap24xx_dss_feats __initconst = { | 813 | static 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 | ||
871 | static 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 | |||
747 | static int __init dss_init_features(struct platform_device *pdev) | 880 | static 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) | |||
884 | static int __init omap_dsshw_probe(struct platform_device *pdev) | 1021 | static 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 | ||
1143 | err_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); | ||
953 | err_runtime_get: | 1149 | err_runtime_get: |
954 | pm_runtime_disable(&pdev->dev); | 1150 | pm_runtime_disable(&pdev->dev); |
955 | err_setup_clocks: | 1151 | err_setup_clocks: |
@@ -959,6 +1155,12 @@ err_setup_clocks: | |||
959 | 1155 | ||
960 | static int __exit omap_dsshw_remove(struct platform_device *pdev) | 1156 | static 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 | ||
103 | enum 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 | |||
103 | struct dss_pll; | 111 | struct 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 | ||
151 | struct dss_pll { | 159 | struct 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); | |||
250 | int dss_init_platform_driver(void) __init; | 259 | int dss_init_platform_driver(void) __init; |
251 | void dss_uninit_platform_driver(void); | 260 | void dss_uninit_platform_driver(void); |
252 | 261 | ||
262 | int dss_runtime_get(void); | ||
263 | void dss_runtime_put(void); | ||
264 | |||
253 | unsigned long dss_get_dispc_clk_rate(void); | 265 | unsigned long dss_get_dispc_clk_rate(void); |
254 | int dss_dpi_select_source(int port, enum omap_channel channel); | 266 | int dss_dpi_select_source(int port, enum omap_channel channel); |
255 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); | 267 | void 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); | |||
257 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); | 269 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); |
258 | void dss_dump_clocks(struct seq_file *s); | 270 | void dss_dump_clocks(struct seq_file *s); |
259 | 271 | ||
272 | /* DSS VIDEO PLL */ | ||
273 | struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id, | ||
274 | struct regulator *regulator); | ||
275 | void dss_video_pll_uninit(struct dss_pll *pll); | ||
276 | |||
260 | /* dss-of */ | 277 | /* dss-of */ |
261 | struct device_node *dss_of_port_get_parent_device(struct device_node *port); | 278 | struct device_node *dss_of_port_get_parent_device(struct device_node *port); |
262 | u32 dss_of_port_get_port_number(struct device_node *port); | 279 | u32 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); | |||
265 | void dss_debug_dump_clocks(struct seq_file *s); | 282 | void dss_debug_dump_clocks(struct seq_file *s); |
266 | #endif | 283 | #endif |
267 | 284 | ||
285 | void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable); | ||
286 | void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id, | ||
287 | enum omap_channel channel); | ||
288 | |||
268 | void dss_sdi_init(int datapairs); | 289 | void dss_sdi_init(int datapairs); |
269 | int dss_sdi_enable(void); | 290 | int dss_sdi_enable(void); |
270 | void dss_sdi_disable(void); | 291 | void 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); |
447 | int dss_pll_write_config_type_b(struct dss_pll *pll, | 468 | int 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); |
470 | int 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 | ||
788 | static const struct of_device_id hdmi_of_match[] = { | 788 | static 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 | ||
122 | static const struct dss_pll_ops dsi_pll_ops = { | 126 | static 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 | ||
225 | int 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 | |||
225 | static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask) | 235 | static 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 | |||
25 | struct 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 | |||
36 | static 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 | |||
41 | static 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 | |||
46 | static 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 | |||
57 | static 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 | |||
62 | static 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 | |||
83 | err_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 | |||
91 | static 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 | |||
104 | static 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 | |||
110 | static 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 | |||
131 | struct 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 | |||
208 | void 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 | ||
352 | static inline void VGAenablePalette(struct savagefb_par *par) | 352 | static 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 | ||
361 | static inline void VGAdisablePalette(struct savagefb_par *par) | 359 | static 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 | ||
370 | static inline void VGAwATTR(u8 index, u8 value, struct savagefb_par *par) | 366 | static 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 | ||
125 | static 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 | |||
142 | static void ssd1307fb_update_display(struct ssd1307fb_par *par) | 125 | static 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 | ||
34 | static inline unsigned char vga_rcrtcs(void __iomem *regbase, unsigned short iobase, | 34 | static 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 | ||
41 | static inline void vga_wcrtcs(void __iomem *regbase, unsigned short iobase, | 41 | static 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 | ||
226 | static void save_vga_mode(struct vgastate *state) | 226 | static 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 | ||
350 | int save_vga(struct vgastate *state) | 350 | int 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 | } |