]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.4/fbdev-sm712fb-fix-crashes-and-garbled-display-during-dpms-modesetting.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.4 / fbdev-sm712fb-fix-crashes-and-garbled-display-during-dpms-modesetting.patch
1 From f627caf55b8e735dcec8fa6538e9668632b55276 Mon Sep 17 00:00:00 2001
2 From: Yifeng Li <tomli@tomli.me>
3 Date: Mon, 1 Apr 2019 17:46:59 +0200
4 Subject: fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting
5
6 From: Yifeng Li <tomli@tomli.me>
7
8 commit f627caf55b8e735dcec8fa6538e9668632b55276 upstream.
9
10 On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), blanking the display
11 or starting the X server will crash and freeze the system, or garble the
12 display.
13
14 Experiments showed this problem can mostly be solved by adjusting the
15 order of register writes. Also, sm712fb failed to consider the difference
16 of clock frequency when unblanking the display, and programs the clock for
17 SM712 to SM720.
18
19 Fix them by adjusting the order of register writes, and adding an
20 additional check for SM720 for programming the clock frequency.
21
22 Signed-off-by: Yifeng Li <tomli@tomli.me>
23 Tested-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
24 Cc: Teddy Wang <teddy.wang@siliconmotion.com>
25 Cc: <stable@vger.kernel.org> # v4.4+
26 Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
27 Signed-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;