1 | /* |
2 | * Silicon Motion SM7XX frame buffer device |
3 | * |
4 | * Copyright (C) 2006 Silicon Motion Technology Corp. |
5 | * Authors: Ge Wang, gewang@siliconmotion.com |
6 | * Boyod boyod.yang@siliconmotion.com.cn |
7 | * |
8 | * Copyright (C) 2009 Lemote, Inc. |
9 | * Author: Wu Zhangjin, wuzhangjin@gmail.com |
10 | * |
11 | * Copyright (C) 2011 Igalia, S.L. |
12 | * Author: Javier M. Mellid <jmunhoz@igalia.com> |
13 | * |
14 | * This file is subject to the terms and conditions of the GNU General Public |
15 | * License. See the file COPYING in the main directory of this archive for |
16 | * more details. |
17 | * |
18 | * Framebuffer driver for Silicon Motion SM710, SM712, SM721 and SM722 chips |
19 | */ |
20 | |
21 | #include <linux/aperture.h> |
22 | #include <linux/io.h> |
23 | #include <linux/fb.h> |
24 | #include <linux/pci.h> |
25 | #include <linux/init.h> |
26 | #include <linux/slab.h> |
27 | #include <linux/uaccess.h> |
28 | #include <linux/module.h> |
29 | #include <linux/console.h> |
30 | |
31 | #include <linux/pm.h> |
32 | |
33 | #include "sm712.h" |
34 | |
35 | struct smtcfb_screen_info { |
36 | u16 lfb_width; |
37 | u16 lfb_height; |
38 | u16 lfb_depth; |
39 | }; |
40 | |
41 | /* |
42 | * Private structure |
43 | */ |
44 | struct smtcfb_info { |
45 | struct pci_dev *pdev; |
46 | struct fb_info *fb; |
47 | u16 chip_id; |
48 | u8 chip_rev_id; |
49 | |
50 | void __iomem *lfb; /* linear frame buffer */ |
51 | void __iomem *dp_regs; /* drawing processor control regs */ |
52 | void __iomem *vp_regs; /* video processor control regs */ |
53 | void __iomem *cp_regs; /* capture processor control regs */ |
54 | void __iomem *mmio; /* memory map IO port */ |
55 | |
56 | u_int width; |
57 | u_int height; |
58 | u_int hz; |
59 | |
60 | u32 colreg[17]; |
61 | }; |
62 | |
63 | void __iomem *smtc_regbaseaddress; /* Memory Map IO starting address */ |
64 | |
65 | static const struct fb_var_screeninfo smtcfb_var = { |
66 | .xres = 1024, |
67 | .yres = 600, |
68 | .xres_virtual = 1024, |
69 | .yres_virtual = 600, |
70 | .bits_per_pixel = 16, |
71 | .red = {16, 8, 0}, |
72 | .green = {8, 8, 0}, |
73 | .blue = {0, 8, 0}, |
74 | .activate = FB_ACTIVATE_NOW, |
75 | .height = -1, |
76 | .width = -1, |
77 | .vmode = FB_VMODE_NONINTERLACED, |
78 | .nonstd = 0, |
79 | .accel_flags = FB_ACCELF_TEXT, |
80 | }; |
81 | |
82 | static struct fb_fix_screeninfo smtcfb_fix = { |
83 | .id = "smXXXfb" , |
84 | .type = FB_TYPE_PACKED_PIXELS, |
85 | .visual = FB_VISUAL_TRUECOLOR, |
86 | .line_length = 800 * 3, |
87 | .accel = FB_ACCEL_SMI_LYNX, |
88 | .type_aux = 0, |
89 | .xpanstep = 0, |
90 | .ypanstep = 0, |
91 | .ywrapstep = 0, |
92 | }; |
93 | |
94 | struct vesa_mode { |
95 | char index[6]; |
96 | u16 lfb_width; |
97 | u16 lfb_height; |
98 | u16 lfb_depth; |
99 | }; |
100 | |
101 | static const struct vesa_mode vesa_mode_table[] = { |
102 | {"0x301" , 640, 480, 8}, |
103 | {"0x303" , 800, 600, 8}, |
104 | {"0x305" , 1024, 768, 8}, |
105 | {"0x307" , 1280, 1024, 8}, |
106 | |
107 | {"0x311" , 640, 480, 16}, |
108 | {"0x314" , 800, 600, 16}, |
109 | {"0x317" , 1024, 768, 16}, |
110 | {"0x31A" , 1280, 1024, 16}, |
111 | |
112 | {"0x312" , 640, 480, 24}, |
113 | {"0x315" , 800, 600, 24}, |
114 | {"0x318" , 1024, 768, 24}, |
115 | {"0x31B" , 1280, 1024, 24}, |
116 | }; |
117 | |
118 | /********************************************************************** |
119 | SM712 Mode table. |
120 | **********************************************************************/ |
121 | static const struct modeinit vgamode[] = { |
122 | { |
123 | /* mode#0: 640 x 480 16Bpp 60Hz */ |
124 | 640, 480, 16, 60, |
125 | /* Init_MISC */ |
126 | 0xE3, |
127 | { /* Init_SR0_SR4 */ |
128 | 0x03, 0x01, 0x0F, 0x00, 0x0E, |
129 | }, |
130 | { /* Init_SR10_SR24 */ |
131 | 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, |
132 | 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
133 | 0xC4, 0x30, 0x02, 0x01, 0x01, |
134 | }, |
135 | { /* Init_SR30_SR75 */ |
136 | 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, |
137 | 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, |
138 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
139 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, |
140 | 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, |
141 | 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, |
142 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
143 | 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, |
144 | 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, |
145 | }, |
146 | { /* Init_SR80_SR93 */ |
147 | 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, |
148 | 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, |
149 | 0x00, 0x00, 0x00, 0x00, |
150 | }, |
151 | { /* Init_SRA0_SRAF */ |
152 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, |
153 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, |
154 | }, |
155 | { /* Init_GR00_GR08 */ |
156 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
157 | 0xFF, |
158 | }, |
159 | { /* Init_AR00_AR14 */ |
160 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
161 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
162 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
163 | }, |
164 | { /* Init_CR00_CR18 */ |
165 | 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, |
166 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
167 | 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, |
168 | 0xFF, |
169 | }, |
170 | { /* Init_CR30_CR4D */ |
171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, |
172 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, |
173 | 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, |
174 | 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, |
175 | }, |
176 | { /* Init_CR90_CRA7 */ |
177 | 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, |
178 | 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, |
179 | 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, |
180 | }, |
181 | }, |
182 | { |
183 | /* mode#1: 640 x 480 24Bpp 60Hz */ |
184 | 640, 480, 24, 60, |
185 | /* Init_MISC */ |
186 | 0xE3, |
187 | { /* Init_SR0_SR4 */ |
188 | 0x03, 0x01, 0x0F, 0x00, 0x0E, |
189 | }, |
190 | { /* Init_SR10_SR24 */ |
191 | 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, |
192 | 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
193 | 0xC4, 0x30, 0x02, 0x01, 0x01, |
194 | }, |
195 | { /* Init_SR30_SR75 */ |
196 | 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, |
197 | 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, |
198 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
199 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, |
200 | 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, |
201 | 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, |
202 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
203 | 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, |
204 | 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, |
205 | }, |
206 | { /* Init_SR80_SR93 */ |
207 | 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, |
208 | 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, |
209 | 0x00, 0x00, 0x00, 0x00, |
210 | }, |
211 | { /* Init_SRA0_SRAF */ |
212 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, |
213 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, |
214 | }, |
215 | { /* Init_GR00_GR08 */ |
216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
217 | 0xFF, |
218 | }, |
219 | { /* Init_AR00_AR14 */ |
220 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
221 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
222 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
223 | }, |
224 | { /* Init_CR00_CR18 */ |
225 | 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, |
226 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
227 | 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, |
228 | 0xFF, |
229 | }, |
230 | { /* Init_CR30_CR4D */ |
231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, |
232 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, |
233 | 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, |
234 | 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, |
235 | }, |
236 | { /* Init_CR90_CRA7 */ |
237 | 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, |
238 | 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, |
239 | 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, |
240 | }, |
241 | }, |
242 | { |
243 | /* mode#0: 640 x 480 32Bpp 60Hz */ |
244 | 640, 480, 32, 60, |
245 | /* Init_MISC */ |
246 | 0xE3, |
247 | { /* Init_SR0_SR4 */ |
248 | 0x03, 0x01, 0x0F, 0x00, 0x0E, |
249 | }, |
250 | { /* Init_SR10_SR24 */ |
251 | 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, |
252 | 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
253 | 0xC4, 0x30, 0x02, 0x01, 0x01, |
254 | }, |
255 | { /* Init_SR30_SR75 */ |
256 | 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, |
257 | 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, |
258 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
259 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, |
260 | 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, |
261 | 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, |
262 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
263 | 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, |
264 | 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, |
265 | }, |
266 | { /* Init_SR80_SR93 */ |
267 | 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, |
268 | 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, |
269 | 0x00, 0x00, 0x00, 0x00, |
270 | }, |
271 | { /* Init_SRA0_SRAF */ |
272 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, |
273 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, |
274 | }, |
275 | { /* Init_GR00_GR08 */ |
276 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
277 | 0xFF, |
278 | }, |
279 | { /* Init_AR00_AR14 */ |
280 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
281 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
282 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
283 | }, |
284 | { /* Init_CR00_CR18 */ |
285 | 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, |
286 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
287 | 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, |
288 | 0xFF, |
289 | }, |
290 | { /* Init_CR30_CR4D */ |
291 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, |
292 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, |
293 | 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, |
294 | 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, |
295 | }, |
296 | { /* Init_CR90_CRA7 */ |
297 | 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, |
298 | 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, |
299 | 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, |
300 | }, |
301 | }, |
302 | |
303 | { /* mode#2: 800 x 600 16Bpp 60Hz */ |
304 | 800, 600, 16, 60, |
305 | /* Init_MISC */ |
306 | 0x2B, |
307 | { /* Init_SR0_SR4 */ |
308 | 0x03, 0x01, 0x0F, 0x03, 0x0E, |
309 | }, |
310 | { /* Init_SR10_SR24 */ |
311 | 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, |
312 | 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
313 | 0xC4, 0x30, 0x02, 0x01, 0x01, |
314 | }, |
315 | { /* Init_SR30_SR75 */ |
316 | 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, |
317 | 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, |
318 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, |
319 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, |
320 | 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, |
321 | 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, |
322 | 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
323 | 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, |
324 | 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, |
325 | }, |
326 | { /* Init_SR80_SR93 */ |
327 | 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, |
328 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, |
329 | 0x00, 0x00, 0x00, 0x00, |
330 | }, |
331 | { /* Init_SRA0_SRAF */ |
332 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, |
333 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, |
334 | }, |
335 | { /* Init_GR00_GR08 */ |
336 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
337 | 0xFF, |
338 | }, |
339 | { /* Init_AR00_AR14 */ |
340 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
341 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
342 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
343 | }, |
344 | { /* Init_CR00_CR18 */ |
345 | 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, |
346 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
347 | 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, |
348 | 0xFF, |
349 | }, |
350 | { /* Init_CR30_CR4D */ |
351 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, |
352 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, |
353 | 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, |
354 | 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, |
355 | }, |
356 | { /* Init_CR90_CRA7 */ |
357 | 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, |
358 | 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, |
359 | 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, |
360 | }, |
361 | }, |
362 | { /* mode#3: 800 x 600 24Bpp 60Hz */ |
363 | 800, 600, 24, 60, |
364 | 0x2B, |
365 | { /* Init_SR0_SR4 */ |
366 | 0x03, 0x01, 0x0F, 0x03, 0x0E, |
367 | }, |
368 | { /* Init_SR10_SR24 */ |
369 | 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, |
370 | 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
371 | 0xC4, 0x30, 0x02, 0x01, 0x01, |
372 | }, |
373 | { /* Init_SR30_SR75 */ |
374 | 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36, |
375 | 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF, |
376 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
377 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36, |
378 | 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, |
379 | 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36, |
380 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
381 | 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, |
382 | 0x02, 0x45, 0x30, 0x30, 0x40, 0x20, |
383 | }, |
384 | { /* Init_SR80_SR93 */ |
385 | 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36, |
386 | 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36, |
387 | 0x00, 0x00, 0x00, 0x00, |
388 | }, |
389 | { /* Init_SRA0_SRAF */ |
390 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, |
391 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, |
392 | }, |
393 | { /* Init_GR00_GR08 */ |
394 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
395 | 0xFF, |
396 | }, |
397 | { /* Init_AR00_AR14 */ |
398 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
399 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
400 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
401 | }, |
402 | { /* Init_CR00_CR18 */ |
403 | 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, |
404 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
405 | 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, |
406 | 0xFF, |
407 | }, |
408 | { /* Init_CR30_CR4D */ |
409 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, |
410 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, |
411 | 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, |
412 | 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, |
413 | }, |
414 | { /* Init_CR90_CRA7 */ |
415 | 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, |
416 | 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, |
417 | 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, |
418 | }, |
419 | }, |
420 | { /* mode#7: 800 x 600 32Bpp 60Hz */ |
421 | 800, 600, 32, 60, |
422 | /* Init_MISC */ |
423 | 0x2B, |
424 | { /* Init_SR0_SR4 */ |
425 | 0x03, 0x01, 0x0F, 0x03, 0x0E, |
426 | }, |
427 | { /* Init_SR10_SR24 */ |
428 | 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, |
429 | 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
430 | 0xC4, 0x30, 0x02, 0x01, 0x01, |
431 | }, |
432 | { /* Init_SR30_SR75 */ |
433 | 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, |
434 | 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, |
435 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, |
436 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, |
437 | 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, |
438 | 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, |
439 | 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
440 | 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, |
441 | 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, |
442 | }, |
443 | { /* Init_SR80_SR93 */ |
444 | 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, |
445 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, |
446 | 0x00, 0x00, 0x00, 0x00, |
447 | }, |
448 | { /* Init_SRA0_SRAF */ |
449 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, |
450 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, |
451 | }, |
452 | { /* Init_GR00_GR08 */ |
453 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
454 | 0xFF, |
455 | }, |
456 | { /* Init_AR00_AR14 */ |
457 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
458 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
459 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
460 | }, |
461 | { /* Init_CR00_CR18 */ |
462 | 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, |
463 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
464 | 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, |
465 | 0xFF, |
466 | }, |
467 | { /* Init_CR30_CR4D */ |
468 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, |
469 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, |
470 | 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, |
471 | 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, |
472 | }, |
473 | { /* Init_CR90_CRA7 */ |
474 | 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, |
475 | 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, |
476 | 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, |
477 | }, |
478 | }, |
479 | /* We use 1024x768 table to light 1024x600 panel for lemote */ |
480 | { /* mode#4: 1024 x 600 16Bpp 60Hz */ |
481 | 1024, 600, 16, 60, |
482 | /* Init_MISC */ |
483 | 0xEB, |
484 | { /* Init_SR0_SR4 */ |
485 | 0x03, 0x01, 0x0F, 0x00, 0x0E, |
486 | }, |
487 | { /* Init_SR10_SR24 */ |
488 | 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20, |
489 | 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
490 | 0xC4, 0x30, 0x02, 0x00, 0x01, |
491 | }, |
492 | { /* Init_SR30_SR75 */ |
493 | 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22, |
494 | 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF, |
495 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
496 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22, |
497 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, |
498 | 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22, |
499 | 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
500 | 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02, |
501 | 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20, |
502 | }, |
503 | { /* Init_SR80_SR93 */ |
504 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, |
505 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, |
506 | 0x00, 0x00, 0x00, 0x00, |
507 | }, |
508 | { /* Init_SRA0_SRAF */ |
509 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, |
510 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, |
511 | }, |
512 | { /* Init_GR00_GR08 */ |
513 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
514 | 0xFF, |
515 | }, |
516 | { /* Init_AR00_AR14 */ |
517 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
518 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
519 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
520 | }, |
521 | { /* Init_CR00_CR18 */ |
522 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, |
523 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
524 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, |
525 | 0xFF, |
526 | }, |
527 | { /* Init_CR30_CR4D */ |
528 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, |
529 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, |
530 | 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00, |
531 | 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57, |
532 | }, |
533 | { /* Init_CR90_CRA7 */ |
534 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, |
535 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, |
536 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, |
537 | }, |
538 | }, |
539 | { /* 1024 x 768 16Bpp 60Hz */ |
540 | 1024, 768, 16, 60, |
541 | /* Init_MISC */ |
542 | 0xEB, |
543 | { /* Init_SR0_SR4 */ |
544 | 0x03, 0x01, 0x0F, 0x03, 0x0E, |
545 | }, |
546 | { /* Init_SR10_SR24 */ |
547 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, |
548 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
549 | 0xC4, 0x30, 0x02, 0x01, 0x01, |
550 | }, |
551 | { /* Init_SR30_SR75 */ |
552 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, |
553 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, |
554 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
555 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, |
556 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, |
557 | 0x0F, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, |
558 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
559 | 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, |
560 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, |
561 | }, |
562 | { /* Init_SR80_SR93 */ |
563 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, |
564 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, |
565 | 0x00, 0x00, 0x00, 0x00, |
566 | }, |
567 | { /* Init_SRA0_SRAF */ |
568 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, |
569 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, |
570 | }, |
571 | { /* Init_GR00_GR08 */ |
572 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
573 | 0xFF, |
574 | }, |
575 | { /* Init_AR00_AR14 */ |
576 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
577 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
578 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
579 | }, |
580 | { /* Init_CR00_CR18 */ |
581 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, |
582 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
583 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, |
584 | 0xFF, |
585 | }, |
586 | { /* Init_CR30_CR4D */ |
587 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, |
588 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, |
589 | 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, |
590 | 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, |
591 | }, |
592 | { /* Init_CR90_CRA7 */ |
593 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, |
594 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, |
595 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, |
596 | }, |
597 | }, |
598 | { /* mode#5: 1024 x 768 24Bpp 60Hz */ |
599 | 1024, 768, 24, 60, |
600 | /* Init_MISC */ |
601 | 0xEB, |
602 | { /* Init_SR0_SR4 */ |
603 | 0x03, 0x01, 0x0F, 0x03, 0x0E, |
604 | }, |
605 | { /* Init_SR10_SR24 */ |
606 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, |
607 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
608 | 0xC4, 0x30, 0x02, 0x01, 0x01, |
609 | }, |
610 | { /* Init_SR30_SR75 */ |
611 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, |
612 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, |
613 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
614 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, |
615 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, |
616 | 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, |
617 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
618 | 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, |
619 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, |
620 | }, |
621 | { /* Init_SR80_SR93 */ |
622 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, |
623 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, |
624 | 0x00, 0x00, 0x00, 0x00, |
625 | }, |
626 | { /* Init_SRA0_SRAF */ |
627 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, |
628 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, |
629 | }, |
630 | { /* Init_GR00_GR08 */ |
631 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
632 | 0xFF, |
633 | }, |
634 | { /* Init_AR00_AR14 */ |
635 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
636 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
637 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
638 | }, |
639 | { /* Init_CR00_CR18 */ |
640 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, |
641 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
642 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, |
643 | 0xFF, |
644 | }, |
645 | { /* Init_CR30_CR4D */ |
646 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, |
647 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, |
648 | 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, |
649 | 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, |
650 | }, |
651 | { /* Init_CR90_CRA7 */ |
652 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, |
653 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, |
654 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, |
655 | }, |
656 | }, |
657 | { /* mode#4: 1024 x 768 32Bpp 60Hz */ |
658 | 1024, 768, 32, 60, |
659 | /* Init_MISC */ |
660 | 0xEB, |
661 | { /* Init_SR0_SR4 */ |
662 | 0x03, 0x01, 0x0F, 0x03, 0x0E, |
663 | }, |
664 | { /* Init_SR10_SR24 */ |
665 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, |
666 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
667 | 0xC4, 0x32, 0x02, 0x01, 0x01, |
668 | }, |
669 | { /* Init_SR30_SR75 */ |
670 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, |
671 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, |
672 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
673 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, |
674 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, |
675 | 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, |
676 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
677 | 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, |
678 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, |
679 | }, |
680 | { /* Init_SR80_SR93 */ |
681 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, |
682 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, |
683 | 0x00, 0x00, 0x00, 0x00, |
684 | }, |
685 | { /* Init_SRA0_SRAF */ |
686 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, |
687 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, |
688 | }, |
689 | { /* Init_GR00_GR08 */ |
690 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
691 | 0xFF, |
692 | }, |
693 | { /* Init_AR00_AR14 */ |
694 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
695 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
696 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
697 | }, |
698 | { /* Init_CR00_CR18 */ |
699 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, |
700 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
701 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, |
702 | 0xFF, |
703 | }, |
704 | { /* Init_CR30_CR4D */ |
705 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, |
706 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, |
707 | 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, |
708 | 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, |
709 | }, |
710 | { /* Init_CR90_CRA7 */ |
711 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, |
712 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, |
713 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, |
714 | }, |
715 | }, |
716 | { /* mode#6: 320 x 240 16Bpp 60Hz */ |
717 | 320, 240, 16, 60, |
718 | /* Init_MISC */ |
719 | 0xEB, |
720 | { /* Init_SR0_SR4 */ |
721 | 0x03, 0x01, 0x0F, 0x03, 0x0E, |
722 | }, |
723 | { /* Init_SR10_SR24 */ |
724 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, |
725 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
726 | 0xC4, 0x32, 0x02, 0x01, 0x01, |
727 | }, |
728 | { /* Init_SR30_SR75 */ |
729 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, |
730 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, |
731 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
732 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, |
733 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, |
734 | 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, |
735 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
736 | 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, |
737 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, |
738 | }, |
739 | { /* Init_SR80_SR93 */ |
740 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, |
741 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, |
742 | 0x00, 0x00, 0x00, 0x00, |
743 | }, |
744 | { /* Init_SRA0_SRAF */ |
745 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, |
746 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, |
747 | }, |
748 | { /* Init_GR00_GR08 */ |
749 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
750 | 0xFF, |
751 | }, |
752 | { /* Init_AR00_AR14 */ |
753 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
754 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
755 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
756 | }, |
757 | { /* Init_CR00_CR18 */ |
758 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, |
759 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
760 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, |
761 | 0xFF, |
762 | }, |
763 | { /* Init_CR30_CR4D */ |
764 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, |
765 | 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, |
766 | 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, |
767 | 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, |
768 | }, |
769 | { /* Init_CR90_CRA7 */ |
770 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, |
771 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, |
772 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, |
773 | }, |
774 | }, |
775 | |
776 | { /* mode#8: 320 x 240 32Bpp 60Hz */ |
777 | 320, 240, 32, 60, |
778 | /* Init_MISC */ |
779 | 0xEB, |
780 | { /* Init_SR0_SR4 */ |
781 | 0x03, 0x01, 0x0F, 0x03, 0x0E, |
782 | }, |
783 | { /* Init_SR10_SR24 */ |
784 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, |
785 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
786 | 0xC4, 0x32, 0x02, 0x01, 0x01, |
787 | }, |
788 | { /* Init_SR30_SR75 */ |
789 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, |
790 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, |
791 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, |
792 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, |
793 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, |
794 | 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, |
795 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, |
796 | 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, |
797 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, |
798 | }, |
799 | { /* Init_SR80_SR93 */ |
800 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, |
801 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, |
802 | 0x00, 0x00, 0x00, 0x00, |
803 | }, |
804 | { /* Init_SRA0_SRAF */ |
805 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, |
806 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, |
807 | }, |
808 | { /* Init_GR00_GR08 */ |
809 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, |
810 | 0xFF, |
811 | }, |
812 | { /* Init_AR00_AR14 */ |
813 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
814 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
815 | 0x41, 0x00, 0x0F, 0x00, 0x00, |
816 | }, |
817 | { /* Init_CR00_CR18 */ |
818 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, |
819 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
820 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, |
821 | 0xFF, |
822 | }, |
823 | { /* Init_CR30_CR4D */ |
824 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, |
825 | 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, |
826 | 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, |
827 | 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, |
828 | }, |
829 | { /* Init_CR90_CRA7 */ |
830 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, |
831 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, |
832 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, |
833 | }, |
834 | }, |
835 | }; |
836 | |
837 | static struct smtcfb_screen_info smtc_scr_info; |
838 | |
839 | static char *mode_option; |
840 | |
841 | /* process command line options, get vga parameter */ |
842 | static void __init sm7xx_vga_setup(char *options) |
843 | { |
844 | int i; |
845 | |
846 | if (!options || !*options) |
847 | return; |
848 | |
849 | smtc_scr_info.lfb_width = 0; |
850 | smtc_scr_info.lfb_height = 0; |
851 | smtc_scr_info.lfb_depth = 0; |
852 | |
853 | pr_debug("%s = %s\n" , __func__, options); |
854 | |
855 | for (i = 0; i < ARRAY_SIZE(vesa_mode_table); i++) { |
856 | if (strstr(options, vesa_mode_table[i].index)) { |
857 | smtc_scr_info.lfb_width = vesa_mode_table[i].lfb_width; |
858 | smtc_scr_info.lfb_height = |
859 | vesa_mode_table[i].lfb_height; |
860 | smtc_scr_info.lfb_depth = vesa_mode_table[i].lfb_depth; |
861 | return; |
862 | } |
863 | } |
864 | } |
865 | |
866 | static void sm712_setpalette(int regno, unsigned int red, unsigned int green, |
867 | unsigned int blue, struct fb_info *info) |
868 | { |
869 | /* set bit 5:4 = 01 (write LCD RAM only) */ |
870 | smtc_seqw(reg: 0x66, val: (smtc_seqr(reg: 0x66) & 0xC3) | 0x10); |
871 | |
872 | smtc_mmiowb(regno, dac_reg); |
873 | smtc_mmiowb(red >> 10, dac_val); |
874 | smtc_mmiowb(green >> 10, dac_val); |
875 | smtc_mmiowb(blue >> 10, dac_val); |
876 | } |
877 | |
878 | /* chan_to_field |
879 | * |
880 | * convert a colour value into a field position |
881 | * |
882 | * from pxafb.c |
883 | */ |
884 | |
885 | static inline unsigned int chan_to_field(unsigned int chan, |
886 | struct fb_bitfield *bf) |
887 | { |
888 | chan &= 0xffff; |
889 | chan >>= 16 - bf->length; |
890 | return chan << bf->offset; |
891 | } |
892 | |
893 | static int smtc_blank(int blank_mode, struct fb_info *info) |
894 | { |
895 | struct smtcfb_info *sfb = info->par; |
896 | |
897 | /* clear DPMS setting */ |
898 | switch (blank_mode) { |
899 | case FB_BLANK_UNBLANK: |
900 | /* Screen On: HSync: On, VSync : On */ |
901 | |
902 | switch (sfb->chip_id) { |
903 | case 0x710: |
904 | case 0x712: |
905 | smtc_seqw(reg: 0x6a, val: 0x16); |
906 | smtc_seqw(reg: 0x6b, val: 0x02); |
907 | break; |
908 | case 0x720: |
909 | smtc_seqw(reg: 0x6a, val: 0x0d); |
910 | smtc_seqw(reg: 0x6b, val: 0x02); |
911 | break; |
912 | } |
913 | |
914 | smtc_seqw(reg: 0x23, val: (smtc_seqr(reg: 0x23) & (~0xc0))); |
915 | smtc_seqw(reg: 0x01, val: (smtc_seqr(reg: 0x01) & (~0x20))); |
916 | smtc_seqw(reg: 0x21, val: (smtc_seqr(reg: 0x21) & 0x77)); |
917 | smtc_seqw(reg: 0x22, val: (smtc_seqr(reg: 0x22) & (~0x30))); |
918 | smtc_seqw(reg: 0x31, val: (smtc_seqr(reg: 0x31) | 0x03)); |
919 | smtc_seqw(reg: 0x24, val: (smtc_seqr(reg: 0x24) | 0x01)); |
920 | break; |
921 | case FB_BLANK_NORMAL: |
922 | /* Screen Off: HSync: On, VSync : On Soft blank */ |
923 | smtc_seqw(reg: 0x24, val: (smtc_seqr(reg: 0x24) | 0x01)); |
924 | smtc_seqw(reg: 0x31, val: ((smtc_seqr(reg: 0x31) & (~0x07)) | 0x00)); |
925 | smtc_seqw(reg: 0x23, val: (smtc_seqr(reg: 0x23) & (~0xc0))); |
926 | smtc_seqw(reg: 0x01, val: (smtc_seqr(reg: 0x01) & (~0x20))); |
927 | smtc_seqw(reg: 0x22, val: (smtc_seqr(reg: 0x22) & (~0x30))); |
928 | smtc_seqw(reg: 0x6a, val: 0x16); |
929 | smtc_seqw(reg: 0x6b, val: 0x02); |
930 | break; |
931 | case FB_BLANK_VSYNC_SUSPEND: |
932 | /* Screen On: HSync: On, VSync : Off */ |
933 | smtc_seqw(reg: 0x24, val: (smtc_seqr(reg: 0x24) & (~0x01))); |
934 | smtc_seqw(reg: 0x31, val: ((smtc_seqr(reg: 0x31) & (~0x07)) | 0x00)); |
935 | smtc_seqw(reg: 0x23, val: ((smtc_seqr(reg: 0x23) & (~0xc0)) | 0x20)); |
936 | smtc_seqw(reg: 0x01, val: (smtc_seqr(reg: 0x01) | 0x20)); |
937 | smtc_seqw(reg: 0x21, val: (smtc_seqr(reg: 0x21) | 0x88)); |
938 | smtc_seqw(reg: 0x20, val: (smtc_seqr(reg: 0x20) & (~0xB0))); |
939 | smtc_seqw(reg: 0x22, val: ((smtc_seqr(reg: 0x22) & (~0x30)) | 0x20)); |
940 | smtc_seqw(reg: 0x34, val: (smtc_seqr(reg: 0x34) | 0x80)); |
941 | smtc_seqw(reg: 0x6a, val: 0x0c); |
942 | smtc_seqw(reg: 0x6b, val: 0x02); |
943 | break; |
944 | case FB_BLANK_HSYNC_SUSPEND: |
945 | /* Screen On: HSync: Off, VSync : On */ |
946 | smtc_seqw(reg: 0x24, val: (smtc_seqr(reg: 0x24) & (~0x01))); |
947 | smtc_seqw(reg: 0x31, val: ((smtc_seqr(reg: 0x31) & (~0x07)) | 0x00)); |
948 | smtc_seqw(reg: 0x23, val: ((smtc_seqr(reg: 0x23) & (~0xc0)) | 0xD8)); |
949 | smtc_seqw(reg: 0x01, val: (smtc_seqr(reg: 0x01) | 0x20)); |
950 | smtc_seqw(reg: 0x21, val: (smtc_seqr(reg: 0x21) | 0x88)); |
951 | smtc_seqw(reg: 0x20, val: (smtc_seqr(reg: 0x20) & (~0xB0))); |
952 | smtc_seqw(reg: 0x22, val: ((smtc_seqr(reg: 0x22) & (~0x30)) | 0x10)); |
953 | smtc_seqw(reg: 0x34, val: (smtc_seqr(reg: 0x34) | 0x80)); |
954 | smtc_seqw(reg: 0x6a, val: 0x0c); |
955 | smtc_seqw(reg: 0x6b, val: 0x02); |
956 | break; |
957 | case FB_BLANK_POWERDOWN: |
958 | /* Screen On: HSync: Off, VSync : Off */ |
959 | smtc_seqw(reg: 0x24, val: (smtc_seqr(reg: 0x24) & (~0x01))); |
960 | smtc_seqw(reg: 0x31, val: ((smtc_seqr(reg: 0x31) & (~0x07)) | 0x00)); |
961 | smtc_seqw(reg: 0x23, val: ((smtc_seqr(reg: 0x23) & (~0xc0)) | 0xD8)); |
962 | smtc_seqw(reg: 0x01, val: (smtc_seqr(reg: 0x01) | 0x20)); |
963 | smtc_seqw(reg: 0x21, val: (smtc_seqr(reg: 0x21) | 0x88)); |
964 | smtc_seqw(reg: 0x20, val: (smtc_seqr(reg: 0x20) & (~0xB0))); |
965 | smtc_seqw(reg: 0x22, val: ((smtc_seqr(reg: 0x22) & (~0x30)) | 0x30)); |
966 | smtc_seqw(reg: 0x34, val: (smtc_seqr(reg: 0x34) | 0x80)); |
967 | smtc_seqw(reg: 0x6a, val: 0x0c); |
968 | smtc_seqw(reg: 0x6b, val: 0x02); |
969 | break; |
970 | default: |
971 | return -EINVAL; |
972 | } |
973 | |
974 | return 0; |
975 | } |
976 | |
977 | static int smtc_setcolreg(unsigned int regno, unsigned int red, |
978 | unsigned int green, unsigned int blue, |
979 | unsigned int trans, struct fb_info *info) |
980 | { |
981 | struct smtcfb_info *sfb; |
982 | u32 val; |
983 | |
984 | sfb = info->par; |
985 | |
986 | if (regno > 255) |
987 | return 1; |
988 | |
989 | switch (sfb->fb->fix.visual) { |
990 | case FB_VISUAL_DIRECTCOLOR: |
991 | case FB_VISUAL_TRUECOLOR: |
992 | /* |
993 | * 16/32 bit true-colour, use pseudo-palette for 16 base color |
994 | */ |
995 | if (regno >= 16) |
996 | break; |
997 | if (sfb->fb->var.bits_per_pixel == 16) { |
998 | u32 *pal = sfb->fb->pseudo_palette; |
999 | |
1000 | val = chan_to_field(chan: red, bf: &sfb->fb->var.red); |
1001 | val |= chan_to_field(chan: green, bf: &sfb->fb->var.green); |
1002 | val |= chan_to_field(chan: blue, bf: &sfb->fb->var.blue); |
1003 | pal[regno] = pal_rgb(red, green, blue, val); |
1004 | } else { |
1005 | u32 *pal = sfb->fb->pseudo_palette; |
1006 | |
1007 | val = chan_to_field(chan: red, bf: &sfb->fb->var.red); |
1008 | val |= chan_to_field(chan: green, bf: &sfb->fb->var.green); |
1009 | val |= chan_to_field(chan: blue, bf: &sfb->fb->var.blue); |
1010 | pal[regno] = big_swap(val); |
1011 | } |
1012 | break; |
1013 | |
1014 | case FB_VISUAL_PSEUDOCOLOR: |
1015 | /* color depth 8 bit */ |
1016 | sm712_setpalette(regno, red, green, blue, info); |
1017 | break; |
1018 | |
1019 | default: |
1020 | return 1; /* unknown type */ |
1021 | } |
1022 | |
1023 | return 0; |
1024 | } |
1025 | |
1026 | static ssize_t smtcfb_read(struct fb_info *info, char __user *buf, |
1027 | size_t count, loff_t *ppos) |
1028 | { |
1029 | unsigned long p = *ppos; |
1030 | |
1031 | u32 *buffer, *dst; |
1032 | u32 __iomem *src; |
1033 | int c, i, cnt = 0, err = 0; |
1034 | unsigned long total_size; |
1035 | |
1036 | if (!info->screen_base) |
1037 | return -ENODEV; |
1038 | |
1039 | total_size = info->screen_size; |
1040 | |
1041 | if (total_size == 0) |
1042 | total_size = info->fix.smem_len; |
1043 | |
1044 | if (p >= total_size) |
1045 | return 0; |
1046 | |
1047 | if (count >= total_size) |
1048 | count = total_size; |
1049 | |
1050 | if (count + p > total_size) |
1051 | count = total_size - p; |
1052 | |
1053 | buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); |
1054 | if (!buffer) |
1055 | return -ENOMEM; |
1056 | |
1057 | src = (u32 __iomem *)(info->screen_base + p); |
1058 | |
1059 | if (info->fbops->fb_sync) |
1060 | info->fbops->fb_sync(info); |
1061 | |
1062 | while (count) { |
1063 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; |
1064 | dst = buffer; |
1065 | for (i = (c + 3) >> 2; i--;) { |
1066 | u32 val; |
1067 | |
1068 | val = fb_readl(addr: src); |
1069 | *dst = big_swap(val); |
1070 | src++; |
1071 | dst++; |
1072 | } |
1073 | |
1074 | if (copy_to_user(to: buf, from: buffer, n: c)) { |
1075 | err = -EFAULT; |
1076 | break; |
1077 | } |
1078 | *ppos += c; |
1079 | buf += c; |
1080 | cnt += c; |
1081 | count -= c; |
1082 | } |
1083 | |
1084 | kfree(objp: buffer); |
1085 | |
1086 | return (err) ? err : cnt; |
1087 | } |
1088 | |
1089 | static ssize_t smtcfb_write(struct fb_info *info, const char __user *buf, |
1090 | size_t count, loff_t *ppos) |
1091 | { |
1092 | unsigned long p = *ppos; |
1093 | |
1094 | u32 *buffer, *src; |
1095 | u32 __iomem *dst; |
1096 | int c, i, cnt = 0, err = 0; |
1097 | unsigned long total_size; |
1098 | |
1099 | if (!info->screen_base) |
1100 | return -ENODEV; |
1101 | |
1102 | total_size = info->screen_size; |
1103 | |
1104 | if (total_size == 0) |
1105 | total_size = info->fix.smem_len; |
1106 | |
1107 | if (p > total_size) |
1108 | return -EFBIG; |
1109 | |
1110 | if (count > total_size) { |
1111 | err = -EFBIG; |
1112 | count = total_size; |
1113 | } |
1114 | |
1115 | if (count + p > total_size) { |
1116 | if (!err) |
1117 | err = -ENOSPC; |
1118 | |
1119 | count = total_size - p; |
1120 | } |
1121 | |
1122 | buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); |
1123 | if (!buffer) |
1124 | return -ENOMEM; |
1125 | |
1126 | dst = (u32 __iomem *)(info->screen_base + p); |
1127 | |
1128 | if (info->fbops->fb_sync) |
1129 | info->fbops->fb_sync(info); |
1130 | |
1131 | while (count) { |
1132 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; |
1133 | src = buffer; |
1134 | |
1135 | if (copy_from_user(to: src, from: buf, n: c)) { |
1136 | err = -EFAULT; |
1137 | break; |
1138 | } |
1139 | |
1140 | for (i = (c + 3) >> 2; i--;) { |
1141 | fb_writel(big_swap(*src), addr: dst); |
1142 | dst++; |
1143 | src++; |
1144 | } |
1145 | |
1146 | *ppos += c; |
1147 | buf += c; |
1148 | cnt += c; |
1149 | count -= c; |
1150 | } |
1151 | |
1152 | kfree(objp: buffer); |
1153 | |
1154 | return (cnt) ? cnt : err; |
1155 | } |
1156 | |
1157 | static void sm7xx_set_timing(struct smtcfb_info *sfb) |
1158 | { |
1159 | int i = 0, j = 0; |
1160 | u32 m_nscreenstride; |
1161 | |
1162 | dev_dbg(&sfb->pdev->dev, |
1163 | "sfb->width=%d sfb->height=%d sfb->fb->var.bits_per_pixel=%d sfb->hz=%d\n" , |
1164 | sfb->width, sfb->height, sfb->fb->var.bits_per_pixel, sfb->hz); |
1165 | |
1166 | for (j = 0; j < ARRAY_SIZE(vgamode); j++) { |
1167 | if (vgamode[j].mmsizex != sfb->width || |
1168 | vgamode[j].mmsizey != sfb->height || |
1169 | vgamode[j].bpp != sfb->fb->var.bits_per_pixel || |
1170 | vgamode[j].hz != sfb->hz) |
1171 | continue; |
1172 | |
1173 | dev_dbg(&sfb->pdev->dev, |
1174 | "vgamode[j].mmsizex=%d vgamode[j].mmSizeY=%d vgamode[j].bpp=%d vgamode[j].hz=%d\n" , |
1175 | vgamode[j].mmsizex, vgamode[j].mmsizey, |
1176 | vgamode[j].bpp, vgamode[j].hz); |
1177 | |
1178 | dev_dbg(&sfb->pdev->dev, "vgamode index=%d\n" , j); |
1179 | |
1180 | smtc_mmiowb(0x0, 0x3c6); |
1181 | |
1182 | smtc_seqw(reg: 0, val: 0x1); |
1183 | |
1184 | smtc_mmiowb(vgamode[j].init_misc, 0x3c2); |
1185 | |
1186 | /* init SEQ register SR00 - SR04 */ |
1187 | for (i = 0; i < SIZE_SR00_SR04; i++) |
1188 | smtc_seqw(reg: i, val: vgamode[j].init_sr00_sr04[i]); |
1189 | |
1190 | /* init SEQ register SR10 - SR24 */ |
1191 | for (i = 0; i < SIZE_SR10_SR24; i++) |
1192 | smtc_seqw(reg: i + 0x10, val: vgamode[j].init_sr10_sr24[i]); |
1193 | |
1194 | /* init SEQ register SR30 - SR75 */ |
1195 | for (i = 0; i < SIZE_SR30_SR75; i++) |
1196 | if ((i + 0x30) != 0x30 && (i + 0x30) != 0x62 && |
1197 | (i + 0x30) != 0x6a && (i + 0x30) != 0x6b && |
1198 | (i + 0x30) != 0x70 && (i + 0x30) != 0x71 && |
1199 | (i + 0x30) != 0x74 && (i + 0x30) != 0x75) |
1200 | smtc_seqw(reg: i + 0x30, |
1201 | val: vgamode[j].init_sr30_sr75[i]); |
1202 | |
1203 | /* init SEQ register SR80 - SR93 */ |
1204 | for (i = 0; i < SIZE_SR80_SR93; i++) |
1205 | smtc_seqw(reg: i + 0x80, val: vgamode[j].init_sr80_sr93[i]); |
1206 | |
1207 | /* init SEQ register SRA0 - SRAF */ |
1208 | for (i = 0; i < SIZE_SRA0_SRAF; i++) |
1209 | smtc_seqw(reg: i + 0xa0, val: vgamode[j].init_sra0_sraf[i]); |
1210 | |
1211 | /* init Graphic register GR00 - GR08 */ |
1212 | for (i = 0; i < SIZE_GR00_GR08; i++) |
1213 | smtc_grphw(reg: i, val: vgamode[j].init_gr00_gr08[i]); |
1214 | |
1215 | /* init Attribute register AR00 - AR14 */ |
1216 | for (i = 0; i < SIZE_AR00_AR14; i++) |
1217 | smtc_attrw(reg: i, val: vgamode[j].init_ar00_ar14[i]); |
1218 | |
1219 | /* init CRTC register CR00 - CR18 */ |
1220 | for (i = 0; i < SIZE_CR00_CR18; i++) |
1221 | smtc_crtcw(reg: i, val: vgamode[j].init_cr00_cr18[i]); |
1222 | |
1223 | /* init CRTC register CR30 - CR4D */ |
1224 | for (i = 0; i < SIZE_CR30_CR4D; i++) { |
1225 | if ((i + 0x30) >= 0x3B && (i + 0x30) <= 0x3F) |
1226 | /* side-effect, don't write to CR3B-CR3F */ |
1227 | continue; |
1228 | smtc_crtcw(reg: i + 0x30, val: vgamode[j].init_cr30_cr4d[i]); |
1229 | } |
1230 | |
1231 | /* init CRTC register CR90 - CRA7 */ |
1232 | for (i = 0; i < SIZE_CR90_CRA7; i++) |
1233 | smtc_crtcw(reg: i + 0x90, val: vgamode[j].init_cr90_cra7[i]); |
1234 | } |
1235 | smtc_mmiowb(0x67, 0x3c2); |
1236 | |
1237 | /* set VPR registers */ |
1238 | writel(val: 0x0, addr: sfb->vp_regs + 0x0C); |
1239 | writel(val: 0x0, addr: sfb->vp_regs + 0x40); |
1240 | |
1241 | /* set data width */ |
1242 | m_nscreenstride = (sfb->width * sfb->fb->var.bits_per_pixel) / 64; |
1243 | switch (sfb->fb->var.bits_per_pixel) { |
1244 | case 8: |
1245 | writel(val: 0x0, addr: sfb->vp_regs + 0x0); |
1246 | break; |
1247 | case 16: |
1248 | writel(val: 0x00020000, addr: sfb->vp_regs + 0x0); |
1249 | break; |
1250 | case 24: |
1251 | writel(val: 0x00040000, addr: sfb->vp_regs + 0x0); |
1252 | break; |
1253 | case 32: |
1254 | writel(val: 0x00030000, addr: sfb->vp_regs + 0x0); |
1255 | break; |
1256 | } |
1257 | writel(val: (u32)(((m_nscreenstride + 2) << 16) | m_nscreenstride), |
1258 | addr: sfb->vp_regs + 0x10); |
1259 | } |
1260 | |
1261 | static void smtc_set_timing(struct smtcfb_info *sfb) |
1262 | { |
1263 | switch (sfb->chip_id) { |
1264 | case 0x710: |
1265 | case 0x712: |
1266 | case 0x720: |
1267 | sm7xx_set_timing(sfb); |
1268 | break; |
1269 | } |
1270 | } |
1271 | |
1272 | static void smtcfb_setmode(struct smtcfb_info *sfb) |
1273 | { |
1274 | switch (sfb->fb->var.bits_per_pixel) { |
1275 | case 32: |
1276 | sfb->fb->fix.visual = FB_VISUAL_TRUECOLOR; |
1277 | sfb->fb->fix.line_length = sfb->fb->var.xres * 4; |
1278 | sfb->fb->var.red.length = 8; |
1279 | sfb->fb->var.green.length = 8; |
1280 | sfb->fb->var.blue.length = 8; |
1281 | sfb->fb->var.red.offset = 16; |
1282 | sfb->fb->var.green.offset = 8; |
1283 | sfb->fb->var.blue.offset = 0; |
1284 | break; |
1285 | case 24: |
1286 | sfb->fb->fix.visual = FB_VISUAL_TRUECOLOR; |
1287 | sfb->fb->fix.line_length = sfb->fb->var.xres * 3; |
1288 | sfb->fb->var.red.length = 8; |
1289 | sfb->fb->var.green.length = 8; |
1290 | sfb->fb->var.blue.length = 8; |
1291 | sfb->fb->var.red.offset = 16; |
1292 | sfb->fb->var.green.offset = 8; |
1293 | sfb->fb->var.blue.offset = 0; |
1294 | break; |
1295 | case 8: |
1296 | sfb->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR; |
1297 | sfb->fb->fix.line_length = sfb->fb->var.xres; |
1298 | sfb->fb->var.red.length = 3; |
1299 | sfb->fb->var.green.length = 3; |
1300 | sfb->fb->var.blue.length = 2; |
1301 | sfb->fb->var.red.offset = 5; |
1302 | sfb->fb->var.green.offset = 2; |
1303 | sfb->fb->var.blue.offset = 0; |
1304 | break; |
1305 | case 16: |
1306 | default: |
1307 | sfb->fb->fix.visual = FB_VISUAL_TRUECOLOR; |
1308 | sfb->fb->fix.line_length = sfb->fb->var.xres * 2; |
1309 | sfb->fb->var.red.length = 5; |
1310 | sfb->fb->var.green.length = 6; |
1311 | sfb->fb->var.blue.length = 5; |
1312 | sfb->fb->var.red.offset = 11; |
1313 | sfb->fb->var.green.offset = 5; |
1314 | sfb->fb->var.blue.offset = 0; |
1315 | break; |
1316 | } |
1317 | |
1318 | sfb->width = sfb->fb->var.xres; |
1319 | sfb->height = sfb->fb->var.yres; |
1320 | sfb->hz = 60; |
1321 | smtc_set_timing(sfb); |
1322 | } |
1323 | |
1324 | static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
1325 | { |
1326 | /* sanity checks */ |
1327 | if (var->xres_virtual < var->xres) |
1328 | var->xres_virtual = var->xres; |
1329 | |
1330 | if (var->yres_virtual < var->yres) |
1331 | var->yres_virtual = var->yres; |
1332 | |
1333 | /* set valid default bpp */ |
1334 | if ((var->bits_per_pixel != 8) && (var->bits_per_pixel != 16) && |
1335 | (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32)) |
1336 | var->bits_per_pixel = 16; |
1337 | |
1338 | return 0; |
1339 | } |
1340 | |
1341 | static int smtc_set_par(struct fb_info *info) |
1342 | { |
1343 | smtcfb_setmode(sfb: info->par); |
1344 | |
1345 | return 0; |
1346 | } |
1347 | |
1348 | static const struct fb_ops smtcfb_ops = { |
1349 | .owner = THIS_MODULE, |
1350 | .fb_check_var = smtc_check_var, |
1351 | .fb_set_par = smtc_set_par, |
1352 | .fb_setcolreg = smtc_setcolreg, |
1353 | .fb_blank = smtc_blank, |
1354 | __FB_DEFAULT_IOMEM_OPS_DRAW, |
1355 | .fb_read = smtcfb_read, |
1356 | .fb_write = smtcfb_write, |
1357 | __FB_DEFAULT_IOMEM_OPS_MMAP, |
1358 | }; |
1359 | |
1360 | /* |
1361 | * Unmap in the memory mapped IO registers |
1362 | */ |
1363 | |
1364 | static void smtc_unmap_mmio(struct smtcfb_info *sfb) |
1365 | { |
1366 | if (sfb && smtc_regbaseaddress) |
1367 | smtc_regbaseaddress = NULL; |
1368 | } |
1369 | |
1370 | /* |
1371 | * Map in the screen memory |
1372 | */ |
1373 | |
1374 | static int smtc_map_smem(struct smtcfb_info *sfb, |
1375 | struct pci_dev *pdev, u_long smem_len) |
1376 | { |
1377 | sfb->fb->fix.smem_start = pci_resource_start(pdev, 0); |
1378 | |
1379 | if (sfb->chip_id == 0x720) |
1380 | /* on SM720, the framebuffer starts at the 1 MB offset */ |
1381 | sfb->fb->fix.smem_start += 0x00200000; |
1382 | |
1383 | /* XXX: is it safe for SM720 on Big-Endian? */ |
1384 | if (sfb->fb->var.bits_per_pixel == 32) |
1385 | sfb->fb->fix.smem_start += big_addr; |
1386 | |
1387 | sfb->fb->fix.smem_len = smem_len; |
1388 | |
1389 | sfb->fb->screen_base = sfb->lfb; |
1390 | |
1391 | if (!sfb->fb->screen_base) { |
1392 | dev_err(&pdev->dev, |
1393 | "%s: unable to map screen memory\n" , sfb->fb->fix.id); |
1394 | return -ENOMEM; |
1395 | } |
1396 | |
1397 | return 0; |
1398 | } |
1399 | |
1400 | /* |
1401 | * Unmap in the screen memory |
1402 | * |
1403 | */ |
1404 | static void smtc_unmap_smem(struct smtcfb_info *sfb) |
1405 | { |
1406 | if (sfb && sfb->fb->screen_base) { |
1407 | if (sfb->chip_id == 0x720) |
1408 | sfb->fb->screen_base -= 0x00200000; |
1409 | iounmap(addr: sfb->fb->screen_base); |
1410 | sfb->fb->screen_base = NULL; |
1411 | } |
1412 | } |
1413 | |
1414 | /* |
1415 | * We need to wake up the device and make sure its in linear memory mode. |
1416 | */ |
1417 | static inline void sm7xx_init_hw(void) |
1418 | { |
1419 | outb_p(value: 0x18, port: 0x3c4); |
1420 | outb_p(value: 0x11, port: 0x3c5); |
1421 | } |
1422 | |
1423 | static u_long sm7xx_vram_probe(struct smtcfb_info *sfb) |
1424 | { |
1425 | u8 vram; |
1426 | |
1427 | switch (sfb->chip_id) { |
1428 | case 0x710: |
1429 | case 0x712: |
1430 | /* |
1431 | * Assume SM712 graphics chip has 4MB VRAM. |
1432 | * |
1433 | * FIXME: SM712 can have 2MB VRAM, which is used on earlier |
1434 | * laptops, such as IBM Thinkpad 240X. This driver would |
1435 | * probably crash on those machines. If anyone gets one of |
1436 | * those and is willing to help, run "git blame" and send me |
1437 | * an E-mail. |
1438 | */ |
1439 | return 0x00400000; |
1440 | case 0x720: |
1441 | outb_p(value: 0x76, port: 0x3c4); |
1442 | vram = inb_p(port: 0x3c5) >> 6; |
1443 | |
1444 | if (vram == 0x00) |
1445 | return 0x00800000; /* 8 MB */ |
1446 | else if (vram == 0x01) |
1447 | return 0x01000000; /* 16 MB */ |
1448 | else if (vram == 0x02) |
1449 | return 0x00400000; /* illegal, fallback to 4 MB */ |
1450 | else if (vram == 0x03) |
1451 | return 0x00400000; /* 4 MB */ |
1452 | } |
1453 | return 0; /* unknown hardware */ |
1454 | } |
1455 | |
1456 | static void sm7xx_resolution_probe(struct smtcfb_info *sfb) |
1457 | { |
1458 | /* get mode parameter from smtc_scr_info */ |
1459 | if (smtc_scr_info.lfb_width != 0) { |
1460 | sfb->fb->var.xres = smtc_scr_info.lfb_width; |
1461 | sfb->fb->var.yres = smtc_scr_info.lfb_height; |
1462 | sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth; |
1463 | goto final; |
1464 | } |
1465 | |
1466 | /* |
1467 | * No parameter, default resolution is 1024x768-16. |
1468 | * |
1469 | * FIXME: earlier laptops, such as IBM Thinkpad 240X, has a 800x600 |
1470 | * panel, also see the comments about Thinkpad 240X above. |
1471 | */ |
1472 | sfb->fb->var.xres = SCREEN_X_RES; |
1473 | sfb->fb->var.yres = SCREEN_Y_RES_PC; |
1474 | sfb->fb->var.bits_per_pixel = SCREEN_BPP; |
1475 | |
1476 | #ifdef CONFIG_MIPS |
1477 | /* |
1478 | * Loongson MIPS netbooks use 1024x600 LCD panels, which is the original |
1479 | * target platform of this driver, but nearly all old x86 laptops have |
1480 | * 1024x768. Lighting 768 panels using 600's timings would partially |
1481 | * garble the display, so we don't want that. But it's not possible to |
1482 | * distinguish them reliably. |
1483 | * |
1484 | * So we change the default to 768, but keep 600 as-is on MIPS. |
1485 | */ |
1486 | sfb->fb->var.yres = SCREEN_Y_RES_NETBOOK; |
1487 | #endif |
1488 | |
1489 | final: |
1490 | big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth); |
1491 | } |
1492 | |
1493 | static int smtcfb_pci_probe(struct pci_dev *pdev, |
1494 | const struct pci_device_id *ent) |
1495 | { |
1496 | struct smtcfb_info *sfb; |
1497 | struct fb_info *info; |
1498 | u_long smem_size; |
1499 | int err; |
1500 | unsigned long mmio_base; |
1501 | |
1502 | dev_info(&pdev->dev, "Silicon Motion display driver.\n" ); |
1503 | |
1504 | err = aperture_remove_conflicting_pci_devices(pdev, name: "smtcfb" ); |
1505 | if (err) |
1506 | return err; |
1507 | |
1508 | err = pci_enable_device(dev: pdev); /* enable SMTC chip */ |
1509 | if (err) |
1510 | return err; |
1511 | |
1512 | err = pci_request_region(pdev, 0, "sm7xxfb" ); |
1513 | if (err < 0) { |
1514 | dev_err(&pdev->dev, "cannot reserve framebuffer region\n" ); |
1515 | goto failed_regions; |
1516 | } |
1517 | |
1518 | sprintf(buf: smtcfb_fix.id, fmt: "sm%Xfb" , ent->device); |
1519 | |
1520 | info = framebuffer_alloc(size: sizeof(*sfb), dev: &pdev->dev); |
1521 | if (!info) { |
1522 | err = -ENOMEM; |
1523 | goto failed_free; |
1524 | } |
1525 | |
1526 | sfb = info->par; |
1527 | sfb->fb = info; |
1528 | sfb->chip_id = ent->device; |
1529 | sfb->pdev = pdev; |
1530 | info->fbops = &smtcfb_ops; |
1531 | info->fix = smtcfb_fix; |
1532 | info->var = smtcfb_var; |
1533 | info->pseudo_palette = sfb->colreg; |
1534 | info->par = sfb; |
1535 | |
1536 | pci_set_drvdata(pdev, data: sfb); |
1537 | |
1538 | sm7xx_init_hw(); |
1539 | |
1540 | /* Map address and memory detection */ |
1541 | mmio_base = pci_resource_start(pdev, 0); |
1542 | pci_read_config_byte(dev: pdev, PCI_REVISION_ID, val: &sfb->chip_rev_id); |
1543 | |
1544 | smem_size = sm7xx_vram_probe(sfb); |
1545 | dev_info(&pdev->dev, "%lu MiB of VRAM detected.\n" , |
1546 | smem_size / 1048576); |
1547 | |
1548 | switch (sfb->chip_id) { |
1549 | case 0x710: |
1550 | case 0x712: |
1551 | sfb->fb->fix.mmio_start = mmio_base + 0x00400000; |
1552 | sfb->fb->fix.mmio_len = 0x00400000; |
1553 | sfb->lfb = ioremap(offset: mmio_base, mmio_addr); |
1554 | if (!sfb->lfb) { |
1555 | dev_err(&pdev->dev, |
1556 | "%s: unable to map memory mapped IO!\n" , |
1557 | sfb->fb->fix.id); |
1558 | err = -ENOMEM; |
1559 | goto failed_fb; |
1560 | } |
1561 | |
1562 | sfb->mmio = (smtc_regbaseaddress = |
1563 | sfb->lfb + 0x00700000); |
1564 | sfb->dp_regs = sfb->lfb + 0x00408000; |
1565 | sfb->vp_regs = sfb->lfb + 0x0040c000; |
1566 | if (sfb->fb->var.bits_per_pixel == 32) { |
1567 | sfb->lfb += big_addr; |
1568 | dev_info(&pdev->dev, "sfb->lfb=%p\n" , sfb->lfb); |
1569 | } |
1570 | |
1571 | /* set MCLK = 14.31818 * (0x16 / 0x2) */ |
1572 | smtc_seqw(reg: 0x6a, val: 0x16); |
1573 | smtc_seqw(reg: 0x6b, val: 0x02); |
1574 | smtc_seqw(reg: 0x62, val: 0x3e); |
1575 | /* enable PCI burst */ |
1576 | smtc_seqw(reg: 0x17, val: 0x20); |
1577 | /* enable word swap */ |
1578 | if (sfb->fb->var.bits_per_pixel == 32) |
1579 | seqw17(); |
1580 | break; |
1581 | case 0x720: |
1582 | sfb->fb->fix.mmio_start = mmio_base; |
1583 | sfb->fb->fix.mmio_len = 0x00200000; |
1584 | sfb->dp_regs = ioremap(offset: mmio_base, size: 0x00200000 + smem_size); |
1585 | if (!sfb->dp_regs) { |
1586 | dev_err(&pdev->dev, |
1587 | "%s: unable to map memory mapped IO!\n" , |
1588 | sfb->fb->fix.id); |
1589 | err = -ENOMEM; |
1590 | goto failed_fb; |
1591 | } |
1592 | |
1593 | sfb->lfb = sfb->dp_regs + 0x00200000; |
1594 | sfb->mmio = (smtc_regbaseaddress = |
1595 | sfb->dp_regs + 0x000c0000); |
1596 | sfb->vp_regs = sfb->dp_regs + 0x800; |
1597 | |
1598 | smtc_seqw(reg: 0x62, val: 0xff); |
1599 | smtc_seqw(reg: 0x6a, val: 0x0d); |
1600 | smtc_seqw(reg: 0x6b, val: 0x02); |
1601 | break; |
1602 | default: |
1603 | dev_err(&pdev->dev, |
1604 | "No valid Silicon Motion display chip was detected!\n" ); |
1605 | err = -ENODEV; |
1606 | goto failed_fb; |
1607 | } |
1608 | |
1609 | /* probe and decide resolution */ |
1610 | sm7xx_resolution_probe(sfb); |
1611 | |
1612 | /* can support 32 bpp */ |
1613 | if (sfb->fb->var.bits_per_pixel == 15) |
1614 | sfb->fb->var.bits_per_pixel = 16; |
1615 | |
1616 | sfb->fb->var.xres_virtual = sfb->fb->var.xres; |
1617 | sfb->fb->var.yres_virtual = sfb->fb->var.yres; |
1618 | err = smtc_map_smem(sfb, pdev, smem_len: smem_size); |
1619 | if (err) |
1620 | goto failed; |
1621 | |
1622 | /* |
1623 | * The screen would be temporarily garbled when sm712fb takes over |
1624 | * vesafb or VGA text mode. Zero the framebuffer. |
1625 | */ |
1626 | memset_io(sfb->lfb, 0, sfb->fb->fix.smem_len); |
1627 | |
1628 | err = register_framebuffer(fb_info: info); |
1629 | if (err < 0) |
1630 | goto failed; |
1631 | |
1632 | dev_info(&pdev->dev, |
1633 | "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.\n" , |
1634 | sfb->chip_id, sfb->chip_rev_id, sfb->fb->var.xres, |
1635 | sfb->fb->var.yres, sfb->fb->var.bits_per_pixel); |
1636 | |
1637 | return 0; |
1638 | |
1639 | failed: |
1640 | dev_err(&pdev->dev, "Silicon Motion, Inc. primary display init fail.\n" ); |
1641 | |
1642 | smtc_unmap_smem(sfb); |
1643 | smtc_unmap_mmio(sfb); |
1644 | failed_fb: |
1645 | framebuffer_release(info); |
1646 | |
1647 | failed_free: |
1648 | pci_release_region(pdev, 0); |
1649 | |
1650 | failed_regions: |
1651 | pci_disable_device(dev: pdev); |
1652 | |
1653 | return err; |
1654 | } |
1655 | |
1656 | /* |
1657 | * 0x710 (LynxEM) |
1658 | * 0x712 (LynxEM+) |
1659 | * 0x720 (Lynx3DM, Lynx3DM+) |
1660 | */ |
1661 | static const struct pci_device_id smtcfb_pci_table[] = { |
1662 | { PCI_DEVICE(0x126f, 0x710), }, |
1663 | { PCI_DEVICE(0x126f, 0x712), }, |
1664 | { PCI_DEVICE(0x126f, 0x720), }, |
1665 | {0,} |
1666 | }; |
1667 | |
1668 | MODULE_DEVICE_TABLE(pci, smtcfb_pci_table); |
1669 | |
1670 | static void smtcfb_pci_remove(struct pci_dev *pdev) |
1671 | { |
1672 | struct smtcfb_info *sfb; |
1673 | |
1674 | sfb = pci_get_drvdata(pdev); |
1675 | smtc_unmap_smem(sfb); |
1676 | smtc_unmap_mmio(sfb); |
1677 | unregister_framebuffer(fb_info: sfb->fb); |
1678 | framebuffer_release(info: sfb->fb); |
1679 | pci_release_region(pdev, 0); |
1680 | pci_disable_device(dev: pdev); |
1681 | } |
1682 | |
1683 | static int __maybe_unused smtcfb_pci_suspend(struct device *device) |
1684 | { |
1685 | struct smtcfb_info *sfb = dev_get_drvdata(dev: device); |
1686 | |
1687 | |
1688 | /* set the hw in sleep mode use external clock and self memory refresh |
1689 | * so that we can turn off internal PLLs later on |
1690 | */ |
1691 | smtc_seqw(reg: 0x20, val: (smtc_seqr(reg: 0x20) | 0xc0)); |
1692 | smtc_seqw(reg: 0x69, val: (smtc_seqr(reg: 0x69) & 0xf7)); |
1693 | |
1694 | console_lock(); |
1695 | fb_set_suspend(info: sfb->fb, state: 1); |
1696 | console_unlock(); |
1697 | |
1698 | /* additionally turn off all function blocks including internal PLLs */ |
1699 | smtc_seqw(reg: 0x21, val: 0xff); |
1700 | |
1701 | return 0; |
1702 | } |
1703 | |
1704 | static int __maybe_unused smtcfb_pci_resume(struct device *device) |
1705 | { |
1706 | struct smtcfb_info *sfb = dev_get_drvdata(dev: device); |
1707 | |
1708 | |
1709 | /* reinit hardware */ |
1710 | sm7xx_init_hw(); |
1711 | switch (sfb->chip_id) { |
1712 | case 0x710: |
1713 | case 0x712: |
1714 | /* set MCLK = 14.31818 * (0x16 / 0x2) */ |
1715 | smtc_seqw(reg: 0x6a, val: 0x16); |
1716 | smtc_seqw(reg: 0x6b, val: 0x02); |
1717 | smtc_seqw(reg: 0x62, val: 0x3e); |
1718 | /* enable PCI burst */ |
1719 | smtc_seqw(reg: 0x17, val: 0x20); |
1720 | if (sfb->fb->var.bits_per_pixel == 32) |
1721 | seqw17(); |
1722 | break; |
1723 | case 0x720: |
1724 | smtc_seqw(reg: 0x62, val: 0xff); |
1725 | smtc_seqw(reg: 0x6a, val: 0x0d); |
1726 | smtc_seqw(reg: 0x6b, val: 0x02); |
1727 | break; |
1728 | } |
1729 | |
1730 | smtc_seqw(reg: 0x34, val: (smtc_seqr(reg: 0x34) | 0xc0)); |
1731 | smtc_seqw(reg: 0x33, val: ((smtc_seqr(reg: 0x33) | 0x08) & 0xfb)); |
1732 | |
1733 | smtcfb_setmode(sfb); |
1734 | |
1735 | console_lock(); |
1736 | fb_set_suspend(info: sfb->fb, state: 0); |
1737 | console_unlock(); |
1738 | |
1739 | return 0; |
1740 | } |
1741 | |
1742 | static SIMPLE_DEV_PM_OPS(sm7xx_pm_ops, smtcfb_pci_suspend, smtcfb_pci_resume); |
1743 | |
1744 | static struct pci_driver smtcfb_driver = { |
1745 | .name = "smtcfb" , |
1746 | .id_table = smtcfb_pci_table, |
1747 | .probe = smtcfb_pci_probe, |
1748 | .remove = smtcfb_pci_remove, |
1749 | .driver.pm = &sm7xx_pm_ops, |
1750 | }; |
1751 | |
1752 | static int __init sm712fb_init(void) |
1753 | { |
1754 | char *option = NULL; |
1755 | |
1756 | if (fb_modesetting_disabled(drvname: "sm712fb" )) |
1757 | return -ENODEV; |
1758 | |
1759 | if (fb_get_options(name: "sm712fb" , option: &option)) |
1760 | return -ENODEV; |
1761 | if (option && *option) |
1762 | mode_option = option; |
1763 | sm7xx_vga_setup(options: mode_option); |
1764 | |
1765 | return pci_register_driver(&smtcfb_driver); |
1766 | } |
1767 | |
1768 | module_init(sm712fb_init); |
1769 | |
1770 | static void __exit sm712fb_exit(void) |
1771 | { |
1772 | pci_unregister_driver(dev: &smtcfb_driver); |
1773 | } |
1774 | |
1775 | module_exit(sm712fb_exit); |
1776 | |
1777 | MODULE_AUTHOR("Siliconmotion " ); |
1778 | MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards" ); |
1779 | MODULE_LICENSE("GPL" ); |
1780 | |