diff options
author | Rodrigo Vivi <rodrigo.vivi@openbossa.org> | 2009-09-22 19:46:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 10:39:49 -0400 |
commit | 2f21a62f16136f369788795a98aa5c313261f07b (patch) | |
tree | 1974092ab93bee721536018d7890d77e268af7cd /drivers/video/omap/blizzard.c | |
parent | 8fea8844a72f95ef22b108f5dc5c4237019771dd (diff) |
omapfb: add support for rotation on the Blizzard LCD ctrl
The LCD controller (EPSON S1D13744) supports rotation (0, 90, 180 and 270
degrees) on hardware just setting the bits 0 and 1 of 0x28 register (LCD
Panel Configuration Register). Now it is possible to use this caps only
setting the angle degree on var rotate of fb_var_screeninfo using the
FBIOPUT_VSCREENINFO ioctl.
Fixed-by: Siarhei Siamashka <siarhei.siamashka@nokia.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@openbossa.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Imre Deak <imre.deak@nokia.com>
Acked-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/omap/blizzard.c')
-rw-r--r-- | drivers/video/omap/blizzard.c | 91 |
1 files changed, 86 insertions, 5 deletions
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c index 9dfcf39d3367..d5e59556f9e2 100644 --- a/drivers/video/omap/blizzard.c +++ b/drivers/video/omap/blizzard.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #define BLIZZARD_CLK_SRC 0x0e | 44 | #define BLIZZARD_CLK_SRC 0x0e |
45 | #define BLIZZARD_MEM_BANK0_ACTIVATE 0x10 | 45 | #define BLIZZARD_MEM_BANK0_ACTIVATE 0x10 |
46 | #define BLIZZARD_MEM_BANK0_STATUS 0x14 | 46 | #define BLIZZARD_MEM_BANK0_STATUS 0x14 |
47 | #define BLIZZARD_PANEL_CONFIGURATION 0x28 | ||
47 | #define BLIZZARD_HDISP 0x2a | 48 | #define BLIZZARD_HDISP 0x2a |
48 | #define BLIZZARD_HNDP 0x2c | 49 | #define BLIZZARD_HNDP 0x2c |
49 | #define BLIZZARD_VDISP0 0x2e | 50 | #define BLIZZARD_VDISP0 0x2e |
@@ -162,6 +163,10 @@ struct blizzard_struct { | |||
162 | int vid_scaled; | 163 | int vid_scaled; |
163 | int last_color_mode; | 164 | int last_color_mode; |
164 | int zoom_on; | 165 | int zoom_on; |
166 | int zoom_area_gx1; | ||
167 | int zoom_area_gx2; | ||
168 | int zoom_area_gy1; | ||
169 | int zoom_area_gy2; | ||
165 | int screen_width; | 170 | int screen_width; |
166 | int screen_height; | 171 | int screen_height; |
167 | unsigned te_connected:1; | 172 | unsigned te_connected:1; |
@@ -513,6 +518,13 @@ static int do_full_screen_update(struct blizzard_request *req) | |||
513 | return REQ_PENDING; | 518 | return REQ_PENDING; |
514 | } | 519 | } |
515 | 520 | ||
521 | static int check_1d_intersect(int a1, int a2, int b1, int b2) | ||
522 | { | ||
523 | if (a2 <= b1 || b2 <= a1) | ||
524 | return 0; | ||
525 | return 1; | ||
526 | } | ||
527 | |||
516 | /* Setup all planes with an overlapping area with the update window. */ | 528 | /* Setup all planes with an overlapping area with the update window. */ |
517 | static int do_partial_update(struct blizzard_request *req, int plane, | 529 | static int do_partial_update(struct blizzard_request *req, int plane, |
518 | int x, int y, int w, int h, | 530 | int x, int y, int w, int h, |
@@ -525,6 +537,7 @@ static int do_partial_update(struct blizzard_request *req, int plane, | |||
525 | int color_mode; | 537 | int color_mode; |
526 | int flags; | 538 | int flags; |
527 | int zoom_off; | 539 | int zoom_off; |
540 | int have_zoom_for_this_update = 0; | ||
528 | 541 | ||
529 | /* Global coordinates, relative to pixel 0,0 of the LCD */ | 542 | /* Global coordinates, relative to pixel 0,0 of the LCD */ |
530 | gx1 = x + blizzard.plane[plane].pos_x; | 543 | gx1 = x + blizzard.plane[plane].pos_x; |
@@ -544,10 +557,6 @@ static int do_partial_update(struct blizzard_request *req, int plane, | |||
544 | gx2_out = gx1_out + w_out; | 557 | gx2_out = gx1_out + w_out; |
545 | gy2_out = gy1_out + h_out; | 558 | gy2_out = gy1_out + h_out; |
546 | } | 559 | } |
547 | zoom_off = blizzard.zoom_on && gx1 == 0 && gy1 == 0 && | ||
548 | w == blizzard.screen_width && h == blizzard.screen_height; | ||
549 | blizzard.zoom_on = (!zoom_off && blizzard.zoom_on) || | ||
550 | (w < w_out || h < h_out); | ||
551 | 560 | ||
552 | for (i = 0; i < OMAPFB_PLANE_NUM; i++) { | 561 | for (i = 0; i < OMAPFB_PLANE_NUM; i++) { |
553 | struct plane_info *p = &blizzard.plane[i]; | 562 | struct plane_info *p = &blizzard.plane[i]; |
@@ -653,8 +662,49 @@ static int do_partial_update(struct blizzard_request *req, int plane, | |||
653 | else | 662 | else |
654 | disable_tearsync(); | 663 | disable_tearsync(); |
655 | 664 | ||
665 | if ((gx2_out - gx1_out) != (gx2 - gx1) || | ||
666 | (gy2_out - gy1_out) != (gy2 - gy1)) | ||
667 | have_zoom_for_this_update = 1; | ||
668 | |||
669 | /* 'background' type of screen update (as opposed to 'destructive') | ||
670 | can be used to disable scaling if scaling is active */ | ||
671 | zoom_off = blizzard.zoom_on && !have_zoom_for_this_update && | ||
672 | (gx1_out == 0) && (gx2_out == blizzard.screen_width) && | ||
673 | (gy1_out == 0) && (gy2_out == blizzard.screen_height) && | ||
674 | (gx1 == 0) && (gy1 == 0); | ||
675 | |||
676 | if (blizzard.zoom_on && !have_zoom_for_this_update && !zoom_off && | ||
677 | check_1d_intersect(blizzard.zoom_area_gx1, blizzard.zoom_area_gx2, | ||
678 | gx1_out, gx2_out) && | ||
679 | check_1d_intersect(blizzard.zoom_area_gy1, blizzard.zoom_area_gy2, | ||
680 | gy1_out, gy2_out)) { | ||
681 | /* Previous screen update was using scaling, current update | ||
682 | * is not using it. Additionally, current screen update is | ||
683 | * going to overlap with the scaled area. Scaling needs to be | ||
684 | * disabled in order to avoid 'magnifying glass' effect. | ||
685 | * Dummy setup of background window can be used for this. | ||
686 | */ | ||
687 | set_window_regs(0, 0, blizzard.screen_width, | ||
688 | blizzard.screen_height, | ||
689 | 0, 0, blizzard.screen_width, | ||
690 | blizzard.screen_height, | ||
691 | BLIZZARD_COLOR_RGB565, 1, flags); | ||
692 | blizzard.zoom_on = 0; | ||
693 | } | ||
694 | |||
695 | /* remember scaling settings if we have scaled update */ | ||
696 | if (have_zoom_for_this_update) { | ||
697 | blizzard.zoom_on = 1; | ||
698 | blizzard.zoom_area_gx1 = gx1_out; | ||
699 | blizzard.zoom_area_gx2 = gx2_out; | ||
700 | blizzard.zoom_area_gy1 = gy1_out; | ||
701 | blizzard.zoom_area_gy2 = gy2_out; | ||
702 | } | ||
703 | |||
656 | set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out, | 704 | set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out, |
657 | color_mode, zoom_off, flags); | 705 | color_mode, zoom_off, flags); |
706 | if (zoom_off) | ||
707 | blizzard.zoom_on = 0; | ||
658 | 708 | ||
659 | blizzard.extif->set_bits_per_cycle(16); | 709 | blizzard.extif->set_bits_per_cycle(16); |
660 | /* set_window_regs has left the register index at the right | 710 | /* set_window_regs has left the register index at the right |
@@ -908,6 +958,35 @@ static int blizzard_set_scale(int plane, int orig_w, int orig_h, | |||
908 | return 0; | 958 | return 0; |
909 | } | 959 | } |
910 | 960 | ||
961 | static int blizzard_set_rotate(int angle) | ||
962 | { | ||
963 | u32 l; | ||
964 | |||
965 | l = blizzard_read_reg(BLIZZARD_PANEL_CONFIGURATION); | ||
966 | l &= ~0x03; | ||
967 | |||
968 | switch (angle) { | ||
969 | case 0: | ||
970 | l = l | 0x00; | ||
971 | break; | ||
972 | case 90: | ||
973 | l = l | 0x03; | ||
974 | break; | ||
975 | case 180: | ||
976 | l = l | 0x02; | ||
977 | break; | ||
978 | case 270: | ||
979 | l = l | 0x01; | ||
980 | break; | ||
981 | default: | ||
982 | return -EINVAL; | ||
983 | } | ||
984 | |||
985 | blizzard_write_reg(BLIZZARD_PANEL_CONFIGURATION, l); | ||
986 | |||
987 | return 0; | ||
988 | } | ||
989 | |||
911 | static int blizzard_enable_plane(int plane, int enable) | 990 | static int blizzard_enable_plane(int plane, int enable) |
912 | { | 991 | { |
913 | if (enable) | 992 | if (enable) |
@@ -1285,7 +1364,8 @@ static void blizzard_get_caps(int plane, struct omapfb_caps *caps) | |||
1285 | caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE | | 1364 | caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE | |
1286 | OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE | | 1365 | OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE | |
1287 | OMAPFB_CAPS_WINDOW_SCALE | | 1366 | OMAPFB_CAPS_WINDOW_SCALE | |
1288 | OMAPFB_CAPS_WINDOW_OVERLAY; | 1367 | OMAPFB_CAPS_WINDOW_OVERLAY | |
1368 | OMAPFB_CAPS_WINDOW_ROTATE; | ||
1289 | if (blizzard.te_connected) | 1369 | if (blizzard.te_connected) |
1290 | caps->ctrl |= OMAPFB_CAPS_TEARSYNC; | 1370 | caps->ctrl |= OMAPFB_CAPS_TEARSYNC; |
1291 | caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) | | 1371 | caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) | |
@@ -1560,6 +1640,7 @@ struct lcd_ctrl blizzard_ctrl = { | |||
1560 | .setup_plane = blizzard_setup_plane, | 1640 | .setup_plane = blizzard_setup_plane, |
1561 | .set_scale = blizzard_set_scale, | 1641 | .set_scale = blizzard_set_scale, |
1562 | .enable_plane = blizzard_enable_plane, | 1642 | .enable_plane = blizzard_enable_plane, |
1643 | .set_rotate = blizzard_set_rotate, | ||
1563 | .update_window = blizzard_update_window_async, | 1644 | .update_window = blizzard_update_window_async, |
1564 | .sync = blizzard_sync, | 1645 | .sync = blizzard_sync, |
1565 | .suspend = blizzard_suspend, | 1646 | .suspend = blizzard_suspend, |