]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - queue-4.4/fbdev-sm712fb-fix-crashes-and-garbled-display-during-dpms-modesetting.patch
4.4-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.4 / fbdev-sm712fb-fix-crashes-and-garbled-display-during-dpms-modesetting.patch
CommitLineData
53722911
GKH
1From f627caf55b8e735dcec8fa6538e9668632b55276 Mon Sep 17 00:00:00 2001
2From: Yifeng Li <tomli@tomli.me>
3Date: Mon, 1 Apr 2019 17:46:59 +0200
4Subject: fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting
5
6From: Yifeng Li <tomli@tomli.me>
7
8commit f627caf55b8e735dcec8fa6538e9668632b55276 upstream.
9
10On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), blanking the display
11or starting the X server will crash and freeze the system, or garble the
12display.
13
14Experiments showed this problem can mostly be solved by adjusting the
15order of register writes. Also, sm712fb failed to consider the difference
16of clock frequency when unblanking the display, and programs the clock for
17SM712 to SM720.
18
19Fix them by adjusting the order of register writes, and adding an
20additional check for SM720 for programming the clock frequency.
21
22Signed-off-by: Yifeng Li <tomli@tomli.me>
23Tested-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
24Cc: Teddy Wang <teddy.wang@siliconmotion.com>
25Cc: <stable@vger.kernel.org> # v4.4+
26Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
27Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28
29---
30 drivers/video/fbdev/sm712fb.c | 64 ++++++++++++++++++++++++------------------
31 1 file changed, 38 insertions(+), 26 deletions(-)
32
33--- a/drivers/video/fbdev/sm712fb.c
34+++ b/drivers/video/fbdev/sm712fb.c
35@@ -886,67 +886,79 @@ static inline unsigned int chan_to_field
36
37 static int smtc_blank(int blank_mode, struct fb_info *info)
38 {
39+ struct smtcfb_info *sfb = info->par;
40+
41 /* clear DPMS setting */
42 switch (blank_mode) {
43 case FB_BLANK_UNBLANK:
44 /* Screen On: HSync: On, VSync : On */
45+
46+ switch (sfb->chip_id) {
47+ case 0x710:
48+ case 0x712:
49+ smtc_seqw(0x6a, 0x16);
50+ smtc_seqw(0x6b, 0x02);
51+ case 0x720:
52+ smtc_seqw(0x6a, 0x0d);
53+ smtc_seqw(0x6b, 0x02);
54+ break;
55+ }
56+
57+ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
58 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
59- smtc_seqw(0x6a, 0x16);
60- smtc_seqw(0x6b, 0x02);
61 smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
62 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
63- smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
64- smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
65 smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
66+ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
67 break;
68 case FB_BLANK_NORMAL:
69 /* Screen Off: HSync: On, VSync : On Soft blank */
70+ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
71+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
72+ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
73 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
74+ smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
75 smtc_seqw(0x6a, 0x16);
76 smtc_seqw(0x6b, 0x02);
77- smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
78- smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
79- smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
80- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
81 break;
82 case FB_BLANK_VSYNC_SUSPEND:
83 /* Screen On: HSync: On, VSync : Off */
84+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
85+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
86+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
87 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
88- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
89- smtc_seqw(0x6a, 0x0c);
90- smtc_seqw(0x6b, 0x02);
91 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
92+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
93 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
94- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
95- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
96- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
97 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
98+ smtc_seqw(0x6a, 0x0c);
99+ smtc_seqw(0x6b, 0x02);
100 break;
101 case FB_BLANK_HSYNC_SUSPEND:
102 /* Screen On: HSync: Off, VSync : On */
103+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
104+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
105+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
106 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
107- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
108- smtc_seqw(0x6a, 0x0c);
109- smtc_seqw(0x6b, 0x02);
110 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
111+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
112 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
113- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
114- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
115- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
116 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
117+ smtc_seqw(0x6a, 0x0c);
118+ smtc_seqw(0x6b, 0x02);
119 break;
120 case FB_BLANK_POWERDOWN:
121 /* Screen On: HSync: Off, VSync : Off */
122+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
123+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
124+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
125 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
126- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
127- smtc_seqw(0x6a, 0x0c);
128- smtc_seqw(0x6b, 0x02);
129 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
130+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
131 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
132- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
133- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
134- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
135 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
136+ smtc_seqw(0x6a, 0x0c);
137+ smtc_seqw(0x6b, 0x02);
138 break;
139 default:
140 return -EINVAL;