summaryrefslogtreecommitdiffstats
path: root/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-compulab-3.14.28/0035-video-mxc-IPUv3-fb-restore-sync-bits.patch
blob: 45712e584a88b47eebf4fbcc3c868054bda5a627 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
From db8c584359449958872973912001bd845438c487 Mon Sep 17 00:00:00 2001
From: Dmitry Lifshitz <lifshitz@compulab.co.il>
Date: Thu, 12 Feb 2015 16:59:53 +0200
Subject: [PATCH 35/59] video: mxc: IPUv3 fb: restore sync bits

Freescale framebuffer driver uses some driver-specific
proprietary bits in the sync field (like pixel clock polarity).

Xorg driver discards unknown sync bits in the fb_var_screeninfo
structure. As the results of dropping the proprietary sync bits
some displays shows various artifacts.

Fix the bug by hacking mxcfb_set_par() callback.

Before applying new var parameters, try to find a match in the mode
list, skipping proprietary sync bits (FB_MXC_SYNC_MASK).

If the entry is found, copy its FB_MXC_SYNC_MASK bits.

Signed-off-by: Dmitry Lifshitz <lifshitz@compulab.co.il>
Signed-off-by: Valentin Raevsky <valentin@compulab.co.il>
---
 drivers/video/mxc/mxc_ipuv3_fb.c |   38 ++++++++++++++++++++++++++++++++++++++
 include/linux/mxcfb.h            |   11 +++++++++++
 2 files changed, 49 insertions(+)

diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index 1fbfc9d..d24241a 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -428,6 +428,28 @@ static bool mxcfb_need_to_set_par(struct fb_info *fbi)
 			sizeof(struct fb_var_screeninfo));
 }
 
+static struct fb_videomode *mxc_match_mode(const struct fb_var_screeninfo *var,
+					  struct list_head *head)
+{
+	struct list_head *pos;
+	struct fb_modelist *modelist;
+	struct fb_videomode *m, mode;
+
+	fb_var_to_videomode(&mode, var);
+	list_for_each(pos, head) {
+		modelist = list_entry(pos, struct fb_modelist, list);
+		m = &modelist->mode;
+
+		mode.sync &= ~FB_MXC_SYNC_MASK;
+		mode.sync |= m->sync & FB_MXC_SYNC_MASK;
+
+		if (fb_mode_is_equal(m, &mode))
+			return m;
+	}
+
+	return NULL;
+}
+
 /*
  * Set framebuffer parameters and change the operating mode.
  *
@@ -583,6 +605,7 @@ static int mxcfb_set_par(struct fb_info *fbi)
 
 	if (!mxc_fbi->overlay) {
 		uint32_t out_pixel_fmt;
+		struct fb_videomode *sync_mode;
 
 		memset(&sig_cfg, 0, sizeof(sig_cfg));
 		if (fbi->var.vmode & FB_VMODE_INTERLACED)
@@ -596,6 +619,21 @@ static int mxcfb_set_par(struct fb_info *fbi)
 			sig_cfg.Hsync_pol = true;
 		if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
 			sig_cfg.Vsync_pol = true;
+
+		/*
+		 * Try to find  matching all parameters, except
+		 * FB_MXC_SYNC_MASK bits in the .sync field.
+		 */
+		sync_mode = mxc_match_mode(&fbi->var, &fbi->modelist);
+		/*
+		 * If entry exists in the mode list and FB_MXC_SYNC_MASK
+		 * bits are empty in the fbi->var.sync (most probably cleared
+		 * by the user space application) then copy it from the found
+		 * mode list entry.
+		 */
+		if (sync_mode && !(fbi->var.sync & FB_MXC_SYNC_MASK))
+			fbi->var.sync = sync_mode->sync;
+
 		if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL))
 			sig_cfg.clk_pol = true;
 		if (fbi->var.sync & FB_SYNC_DATA_INVERT)
diff --git a/include/linux/mxcfb.h b/include/linux/mxcfb.h
index 67db5ee..e63aa2c 100644
--- a/include/linux/mxcfb.h
+++ b/include/linux/mxcfb.h
@@ -23,6 +23,17 @@
 
 #include <uapi/linux/mxcfb.h>
 
+#define FB_SYNC_OE_LOW_ACT	0x80000000
+#define FB_SYNC_CLK_LAT_FALL	0x40000000
+#define FB_SYNC_DATA_INVERT	0x20000000
+#define FB_SYNC_CLK_IDLE_EN	0x10000000
+#define FB_SYNC_SHARP_MODE	0x08000000
+#define FB_SYNC_SWAP_RGB	0x04000000
+
+#define FB_MXC_SYNC_MASK	(FB_SYNC_OE_LOW_ACT | FB_SYNC_CLK_LAT_FALL | \
+				 FB_SYNC_DATA_INVERT | FB_SYNC_CLK_IDLE_EN | \
+				 FB_SYNC_SHARP_MODE | FB_SYNC_SWAP_RGB)
+
 extern struct fb_videomode mxcfb_modedb[];
 extern int mxcfb_modedb_sz;
 
-- 
1.7.9.5