aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/mx3fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/mx3fb.c')
-rw-r--r--drivers/video/mx3fb.c55
1 files changed, 47 insertions, 8 deletions
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index eec0d7b748eb..c89f8a8d36d2 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 *);
@@ -698,9 +698,29 @@ static void mx3fb_dma_done(void *arg)
698 complete(&mx3_fbi->flip_cmpl); 698 complete(&mx3_fbi->flip_cmpl);
699} 699}
700 700
701static bool mx3fb_must_set_par(struct fb_info *fbi)
702{
703 struct mx3fb_info *mx3_fbi = fbi->par;
704 struct fb_var_screeninfo old_var = mx3_fbi->cur_var;
705 struct fb_var_screeninfo new_var = fbi->var;
706
707 if ((fbi->var.activate & FB_ACTIVATE_FORCE) &&
708 (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
709 return true;
710
711 /*
712 * Ignore xoffset and yoffset update,
713 * because pan display handles this case.
714 */
715 old_var.xoffset = new_var.xoffset;
716 old_var.yoffset = new_var.yoffset;
717
718 return !!memcmp(&old_var, &new_var, sizeof(struct fb_var_screeninfo));
719}
720
701static int __set_par(struct fb_info *fbi, bool lock) 721static int __set_par(struct fb_info *fbi, bool lock)
702{ 722{
703 u32 mem_len; 723 u32 mem_len, cur_xoffset, cur_yoffset;
704 struct ipu_di_signal_cfg sig_cfg; 724 struct ipu_di_signal_cfg sig_cfg;
705 enum ipu_panel mode = IPU_PANEL_TFT; 725 enum ipu_panel mode = IPU_PANEL_TFT;
706 struct mx3fb_info *mx3_fbi = fbi->par; 726 struct mx3fb_info *mx3_fbi = fbi->par;
@@ -780,8 +800,25 @@ static int __set_par(struct fb_info *fbi, bool lock)
780 video->out_height = fbi->var.yres; 800 video->out_height = fbi->var.yres;
781 video->out_stride = fbi->var.xres_virtual; 801 video->out_stride = fbi->var.xres_virtual;
782 802
783 if (mx3_fbi->blank == FB_BLANK_UNBLANK) 803 if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
784 sdc_enable_channel(mx3_fbi); 804 sdc_enable_channel(mx3_fbi);
805 /*
806 * sg[0] points to fb smem_start address
807 * and is actually active in controller.
808 */
809 mx3_fbi->cur_var.xoffset = 0;
810 mx3_fbi->cur_var.yoffset = 0;
811 }
812
813 /*
814 * Preserve xoffset and yoffest in case they are
815 * inactive in controller as fb is blanked.
816 */
817 cur_xoffset = mx3_fbi->cur_var.xoffset;
818 cur_yoffset = mx3_fbi->cur_var.yoffset;
819 mx3_fbi->cur_var = fbi->var;
820 mx3_fbi->cur_var.xoffset = cur_xoffset;
821 mx3_fbi->cur_var.yoffset = cur_yoffset;
785 822
786 return 0; 823 return 0;
787} 824}
@@ -802,7 +839,7 @@ static int mx3fb_set_par(struct fb_info *fbi)
802 839
803 mutex_lock(&mx3_fbi->mutex); 840 mutex_lock(&mx3_fbi->mutex);
804 841
805 ret = __set_par(fbi, true); 842 ret = mx3fb_must_set_par(fbi) ? __set_par(fbi, true) : 0;
806 843
807 mutex_unlock(&mx3_fbi->mutex); 844 mutex_unlock(&mx3_fbi->mutex);
808 845
@@ -901,8 +938,8 @@ static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
901 var->grayscale = 0; 938 var->grayscale = 0;
902 939
903 /* Preserve sync flags */ 940 /* Preserve sync flags */
904 var->sync |= mx3_fbi->sync; 941 var->sync |= mx3_fbi->cur_var.sync;
905 mx3_fbi->sync |= var->sync; 942 mx3_fbi->cur_var.sync |= var->sync;
906 943
907 return 0; 944 return 0;
908} 945}
@@ -1043,8 +1080,8 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1043 return -EINVAL; 1080 return -EINVAL;
1044 } 1081 }
1045 1082
1046 if (fbi->var.xoffset == var->xoffset && 1083 if (mx3_fbi->cur_var.xoffset == var->xoffset &&
1047 fbi->var.yoffset == var->yoffset) 1084 mx3_fbi->cur_var.yoffset == var->yoffset)
1048 return 0; /* No change, do nothing */ 1085 return 0; /* No change, do nothing */
1049 1086
1050 y_bottom = var->yoffset; 1087 y_bottom = var->yoffset;
@@ -1127,6 +1164,8 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1127 else 1164 else
1128 fbi->var.vmode &= ~FB_VMODE_YWRAP; 1165 fbi->var.vmode &= ~FB_VMODE_YWRAP;
1129 1166
1167 mx3_fbi->cur_var = fbi->var;
1168
1130 mutex_unlock(&mx3_fbi->mutex); 1169 mutex_unlock(&mx3_fbi->mutex);
1131 1170
1132 dev_dbg(fbi->device, "Update complete\n"); 1171 dev_dbg(fbi->device, "Update complete\n");