aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/mx3fb.c
diff options
context:
space:
mode:
authorLiu Ying <Ying.Liu@freescale.com>2012-06-10 21:06:49 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2012-06-27 02:59:51 -0400
commit6cd77e00c00c5da3b6f8546dcb6dfac9611ca10b (patch)
tree3ac8a9dd289153b04be7478ea27f5c149482e614 /drivers/video/mx3fb.c
parent0f90fa539dff47e65fe859de2a9089e53231e0da (diff)
mx3fb: support pan display with fb_set_var
Users may call FBIOPUT_VSCREENINFO ioctrl to do pan display. This ioctrl relies on fb_set_var() to do the job. fb_set_var() calls the custom fb_set_par() method and then calls the custom fb_pan_display() method. Before calling the custom fb_pan_display() method, info->var is already updated from the new *var in fb_set_var(). And, the custom fb_pan_display() method checks if xoffset and yoffset in info->var and the new *var are different before doing actual panning, which prevents the panning from happening within fb_set_var() context. This patch caches the current var info locally in mx3fb driver so that pan display with fb_set_var is supported. Signed-off-by: Liu Ying <Ying.Liu@freescale.com> Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Diffstat (limited to 'drivers/video/mx3fb.c')
-rw-r--r--drivers/video/mx3fb.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index eec0d7b748eb..da1d052a18a5 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -269,7 +269,7 @@ struct mx3fb_info {
269 dma_cookie_t cookie; 269 dma_cookie_t cookie;
270 struct scatterlist sg[2]; 270 struct scatterlist sg[2];
271 271
272 u32 sync; /* preserve var->sync flags */ 272 struct fb_var_screeninfo cur_var; /* current var info */
273}; 273};
274 274
275static void mx3fb_dma_done(void *); 275static void mx3fb_dma_done(void *);
@@ -700,7 +700,7 @@ static void mx3fb_dma_done(void *arg)
700 700
701static int __set_par(struct fb_info *fbi, bool lock) 701static int __set_par(struct fb_info *fbi, bool lock)
702{ 702{
703 u32 mem_len; 703 u32 mem_len, cur_xoffset, cur_yoffset;
704 struct ipu_di_signal_cfg sig_cfg; 704 struct ipu_di_signal_cfg sig_cfg;
705 enum ipu_panel mode = IPU_PANEL_TFT; 705 enum ipu_panel mode = IPU_PANEL_TFT;
706 struct mx3fb_info *mx3_fbi = fbi->par; 706 struct mx3fb_info *mx3_fbi = fbi->par;
@@ -780,8 +780,25 @@ static int __set_par(struct fb_info *fbi, bool lock)
780 video->out_height = fbi->var.yres; 780 video->out_height = fbi->var.yres;
781 video->out_stride = fbi->var.xres_virtual; 781 video->out_stride = fbi->var.xres_virtual;
782 782
783 if (mx3_fbi->blank == FB_BLANK_UNBLANK) 783 if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
784 sdc_enable_channel(mx3_fbi); 784 sdc_enable_channel(mx3_fbi);
785 /*
786 * sg[0] points to fb smem_start address
787 * and is actually active in controller.
788 */
789 mx3_fbi->cur_var.xoffset = 0;
790 mx3_fbi->cur_var.yoffset = 0;
791 }
792
793 /*
794 * Preserve xoffset and yoffest in case they are
795 * inactive in controller as fb is blanked.
796 */
797 cur_xoffset = mx3_fbi->cur_var.xoffset;
798 cur_yoffset = mx3_fbi->cur_var.yoffset;
799 mx3_fbi->cur_var = fbi->var;
800 mx3_fbi->cur_var.xoffset = cur_xoffset;
801 mx3_fbi->cur_var.yoffset = cur_yoffset;
785 802
786 return 0; 803 return 0;
787} 804}
@@ -901,8 +918,8 @@ static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
901 var->grayscale = 0; 918 var->grayscale = 0;
902 919
903 /* Preserve sync flags */ 920 /* Preserve sync flags */
904 var->sync |= mx3_fbi->sync; 921 var->sync |= mx3_fbi->cur_var.sync;
905 mx3_fbi->sync |= var->sync; 922 mx3_fbi->cur_var.sync |= var->sync;
906 923
907 return 0; 924 return 0;
908} 925}
@@ -1043,8 +1060,8 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1043 return -EINVAL; 1060 return -EINVAL;
1044 } 1061 }
1045 1062
1046 if (fbi->var.xoffset == var->xoffset && 1063 if (mx3_fbi->cur_var.xoffset == var->xoffset &&
1047 fbi->var.yoffset == var->yoffset) 1064 mx3_fbi->cur_var.yoffset == var->yoffset)
1048 return 0; /* No change, do nothing */ 1065 return 0; /* No change, do nothing */
1049 1066
1050 y_bottom = var->yoffset; 1067 y_bottom = var->yoffset;
@@ -1127,6 +1144,8 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1127 else 1144 else
1128 fbi->var.vmode &= ~FB_VMODE_YWRAP; 1145 fbi->var.vmode &= ~FB_VMODE_YWRAP;
1129 1146
1147 mx3_fbi->cur_var = fbi->var;
1148
1130 mutex_unlock(&mx3_fbi->mutex); 1149 mutex_unlock(&mx3_fbi->mutex);
1131 1150
1132 dev_dbg(fbi->device, "Update complete\n"); 1151 dev_dbg(fbi->device, "Update complete\n");