]>
Commit | Line | Data |
---|---|---|
12eb90f1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
3c8a63e2 SG |
2 | /* |
3 | * smscufx.c -- Framebuffer driver for SMSC UFX USB controller | |
4 | * | |
90b24cfb | 5 | * Copyright (C) 2011 Steve Glendinning <steve.glendinning@shawell.net> |
3c8a63e2 SG |
6 | * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it> |
7 | * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com> | |
8 | * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com> | |
9 | * | |
3c8a63e2 SG |
10 | * Based on udlfb, with work from Florian Echtler, Henrik Bjerregaard Pedersen, |
11 | * and others. | |
12 | * | |
13 | * Works well with Bernie Thompson's X DAMAGE patch to xf86-video-fbdev | |
14 | * available from http://git.plugable.com | |
15 | * | |
16 | * Layout is based on skeletonfb by James Simmons and Geert Uytterhoeven, | |
17 | * usb-skeleton by GregKH. | |
18 | */ | |
19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
21 | ||
22 | #include <linux/module.h> | |
23 | #include <linux/kernel.h> | |
24 | #include <linux/init.h> | |
25 | #include <linux/usb.h> | |
26 | #include <linux/uaccess.h> | |
27 | #include <linux/mm.h> | |
28 | #include <linux/fb.h> | |
29 | #include <linux/vmalloc.h> | |
30 | #include <linux/slab.h> | |
31 | #include <linux/delay.h> | |
32 | #include "edid.h" | |
33 | ||
34 | #define check_warn(status, fmt, args...) \ | |
35 | ({ if (status < 0) pr_warn(fmt, ##args); }) | |
36 | ||
37 | #define check_warn_return(status, fmt, args...) \ | |
38 | ({ if (status < 0) { pr_warn(fmt, ##args); return status; } }) | |
39 | ||
40 | #define check_warn_goto_error(status, fmt, args...) \ | |
41 | ({ if (status < 0) { pr_warn(fmt, ##args); goto error; } }) | |
42 | ||
43 | #define all_bits_set(x, bits) (((x) & (bits)) == (bits)) | |
44 | ||
45 | #define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0 | |
46 | #define USB_VENDOR_REQUEST_READ_REGISTER 0xA1 | |
47 | ||
48 | /* | |
49 | * TODO: Propose standard fb.h ioctl for reporting damage, | |
50 | * using _IOWR() and one of the existing area structs from fb.h | |
51 | * Consider these ioctls deprecated, but they're still used by the | |
52 | * DisplayLink X server as yet - need both to be modified in tandem | |
53 | * when new ioctl(s) are ready. | |
54 | */ | |
55 | #define UFX_IOCTL_RETURN_EDID (0xAD) | |
56 | #define UFX_IOCTL_REPORT_DAMAGE (0xAA) | |
57 | ||
58 | /* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */ | |
59 | #define BULK_SIZE (512) | |
60 | #define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE) | |
61 | #define WRITES_IN_FLIGHT (4) | |
62 | ||
63 | #define GET_URB_TIMEOUT (HZ) | |
64 | #define FREE_URB_TIMEOUT (HZ*2) | |
65 | ||
66 | #define BPP 2 | |
67 | ||
68 | #define UFX_DEFIO_WRITE_DELAY 5 /* fb_deferred_io.delay in jiffies */ | |
69 | #define UFX_DEFIO_WRITE_DISABLE (HZ*60) /* "disable" with long delay */ | |
70 | ||
71 | struct dloarea { | |
72 | int x, y; | |
73 | int w, h; | |
74 | }; | |
75 | ||
76 | struct urb_node { | |
77 | struct list_head entry; | |
78 | struct ufx_data *dev; | |
79 | struct delayed_work release_urb_work; | |
80 | struct urb *urb; | |
81 | }; | |
82 | ||
83 | struct urb_list { | |
84 | struct list_head list; | |
85 | spinlock_t lock; | |
86 | struct semaphore limit_sem; | |
87 | int available; | |
88 | int count; | |
89 | size_t size; | |
90 | }; | |
91 | ||
92 | struct ufx_data { | |
93 | struct usb_device *udev; | |
94 | struct device *gdev; /* &udev->dev */ | |
95 | struct fb_info *info; | |
96 | struct urb_list urbs; | |
97 | struct kref kref; | |
98 | int fb_count; | |
99 | bool virtualized; /* true when physical usb device not present */ | |
100 | struct delayed_work free_framebuffer_work; | |
101 | atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */ | |
102 | atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ | |
261e7676 | 103 | u8 *edid; /* null until we read edid from hw or get from sysfs */ |
3c8a63e2 SG |
104 | size_t edid_size; |
105 | u32 pseudo_palette[256]; | |
106 | }; | |
107 | ||
108 | static struct fb_fix_screeninfo ufx_fix = { | |
109 | .id = "smscufx", | |
110 | .type = FB_TYPE_PACKED_PIXELS, | |
111 | .visual = FB_VISUAL_TRUECOLOR, | |
112 | .xpanstep = 0, | |
113 | .ypanstep = 0, | |
114 | .ywrapstep = 0, | |
115 | .accel = FB_ACCEL_NONE, | |
116 | }; | |
117 | ||
118 | static const u32 smscufx_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST | | |
119 | FBINFO_VIRTFB | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT | | |
120 | FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR; | |
121 | ||
8290d78e | 122 | static const struct usb_device_id id_table[] = { |
3c8a63e2 SG |
123 | {USB_DEVICE(0x0424, 0x9d00),}, |
124 | {USB_DEVICE(0x0424, 0x9d01),}, | |
125 | {}, | |
126 | }; | |
127 | MODULE_DEVICE_TABLE(usb, id_table); | |
128 | ||
129 | /* module options */ | |
90ab5ee9 RR |
130 | static bool console; /* Optionally allow fbcon to consume first framebuffer */ |
131 | static bool fb_defio = true; /* Optionally enable fb_defio mmap support */ | |
3c8a63e2 SG |
132 | |
133 | /* ufx keeps a list of urbs for efficient bulk transfers */ | |
134 | static void ufx_urb_completion(struct urb *urb); | |
135 | static struct urb *ufx_get_urb(struct ufx_data *dev); | |
136 | static int ufx_submit_urb(struct ufx_data *dev, struct urb * urb, size_t len); | |
137 | static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size); | |
138 | static void ufx_free_urb_list(struct ufx_data *dev); | |
139 | ||
140 | /* reads a control register */ | |
141 | static int ufx_reg_read(struct ufx_data *dev, u32 index, u32 *data) | |
142 | { | |
143 | u32 *buf = kmalloc(4, GFP_KERNEL); | |
144 | int ret; | |
145 | ||
146 | BUG_ON(!dev); | |
147 | ||
148 | if (!buf) | |
149 | return -ENOMEM; | |
150 | ||
151 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), | |
152 | USB_VENDOR_REQUEST_READ_REGISTER, | |
153 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
154 | 00, index, buf, 4, USB_CTRL_GET_TIMEOUT); | |
155 | ||
156 | le32_to_cpus(buf); | |
157 | *data = *buf; | |
158 | kfree(buf); | |
159 | ||
160 | if (unlikely(ret < 0)) | |
161 | pr_warn("Failed to read register index 0x%08x\n", index); | |
162 | ||
163 | return ret; | |
164 | } | |
165 | ||
166 | /* writes a control register */ | |
167 | static int ufx_reg_write(struct ufx_data *dev, u32 index, u32 data) | |
168 | { | |
169 | u32 *buf = kmalloc(4, GFP_KERNEL); | |
170 | int ret; | |
171 | ||
172 | BUG_ON(!dev); | |
173 | ||
174 | if (!buf) | |
175 | return -ENOMEM; | |
176 | ||
177 | *buf = data; | |
178 | cpu_to_le32s(buf); | |
179 | ||
180 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | |
181 | USB_VENDOR_REQUEST_WRITE_REGISTER, | |
182 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
183 | 00, index, buf, 4, USB_CTRL_SET_TIMEOUT); | |
184 | ||
185 | kfree(buf); | |
186 | ||
187 | if (unlikely(ret < 0)) | |
188 | pr_warn("Failed to write register index 0x%08x with value " | |
189 | "0x%08x\n", index, data); | |
190 | ||
191 | return ret; | |
192 | } | |
193 | ||
194 | static int ufx_reg_clear_and_set_bits(struct ufx_data *dev, u32 index, | |
195 | u32 bits_to_clear, u32 bits_to_set) | |
196 | { | |
197 | u32 data; | |
198 | int status = ufx_reg_read(dev, index, &data); | |
199 | check_warn_return(status, "ufx_reg_clear_and_set_bits error reading " | |
200 | "0x%x", index); | |
201 | ||
202 | data &= (~bits_to_clear); | |
203 | data |= bits_to_set; | |
204 | ||
205 | status = ufx_reg_write(dev, index, data); | |
206 | check_warn_return(status, "ufx_reg_clear_and_set_bits error writing " | |
207 | "0x%x", index); | |
208 | ||
209 | return 0; | |
210 | } | |
211 | ||
212 | static int ufx_reg_set_bits(struct ufx_data *dev, u32 index, u32 bits) | |
213 | { | |
214 | return ufx_reg_clear_and_set_bits(dev, index, 0, bits); | |
215 | } | |
216 | ||
217 | static int ufx_reg_clear_bits(struct ufx_data *dev, u32 index, u32 bits) | |
218 | { | |
219 | return ufx_reg_clear_and_set_bits(dev, index, bits, 0); | |
220 | } | |
221 | ||
222 | static int ufx_lite_reset(struct ufx_data *dev) | |
223 | { | |
224 | int status; | |
225 | u32 value; | |
226 | ||
227 | status = ufx_reg_write(dev, 0x3008, 0x00000001); | |
228 | check_warn_return(status, "ufx_lite_reset error writing 0x3008"); | |
229 | ||
230 | status = ufx_reg_read(dev, 0x3008, &value); | |
231 | check_warn_return(status, "ufx_lite_reset error reading 0x3008"); | |
232 | ||
233 | return (value == 0) ? 0 : -EIO; | |
234 | } | |
235 | ||
236 | /* If display is unblanked, then blank it */ | |
237 | static int ufx_blank(struct ufx_data *dev, bool wait) | |
238 | { | |
239 | u32 dc_ctrl, dc_sts; | |
240 | int i; | |
241 | ||
242 | int status = ufx_reg_read(dev, 0x2004, &dc_sts); | |
243 | check_warn_return(status, "ufx_blank error reading 0x2004"); | |
244 | ||
245 | status = ufx_reg_read(dev, 0x2000, &dc_ctrl); | |
246 | check_warn_return(status, "ufx_blank error reading 0x2000"); | |
247 | ||
248 | /* return success if display is already blanked */ | |
249 | if ((dc_sts & 0x00000100) || (dc_ctrl & 0x00000100)) | |
250 | return 0; | |
251 | ||
252 | /* request the DC to blank the display */ | |
253 | dc_ctrl |= 0x00000100; | |
254 | status = ufx_reg_write(dev, 0x2000, dc_ctrl); | |
255 | check_warn_return(status, "ufx_blank error writing 0x2000"); | |
256 | ||
257 | /* return success immediately if we don't have to wait */ | |
258 | if (!wait) | |
259 | return 0; | |
260 | ||
261 | for (i = 0; i < 250; i++) { | |
262 | status = ufx_reg_read(dev, 0x2004, &dc_sts); | |
263 | check_warn_return(status, "ufx_blank error reading 0x2004"); | |
264 | ||
265 | if (dc_sts & 0x00000100) | |
266 | return 0; | |
267 | } | |
268 | ||
269 | /* timed out waiting for display to blank */ | |
270 | return -EIO; | |
271 | } | |
272 | ||
273 | /* If display is blanked, then unblank it */ | |
274 | static int ufx_unblank(struct ufx_data *dev, bool wait) | |
275 | { | |
276 | u32 dc_ctrl, dc_sts; | |
277 | int i; | |
278 | ||
279 | int status = ufx_reg_read(dev, 0x2004, &dc_sts); | |
280 | check_warn_return(status, "ufx_unblank error reading 0x2004"); | |
281 | ||
282 | status = ufx_reg_read(dev, 0x2000, &dc_ctrl); | |
283 | check_warn_return(status, "ufx_unblank error reading 0x2000"); | |
284 | ||
285 | /* return success if display is already unblanked */ | |
286 | if (((dc_sts & 0x00000100) == 0) || ((dc_ctrl & 0x00000100) == 0)) | |
287 | return 0; | |
288 | ||
289 | /* request the DC to unblank the display */ | |
290 | dc_ctrl &= ~0x00000100; | |
291 | status = ufx_reg_write(dev, 0x2000, dc_ctrl); | |
292 | check_warn_return(status, "ufx_unblank error writing 0x2000"); | |
293 | ||
294 | /* return success immediately if we don't have to wait */ | |
295 | if (!wait) | |
296 | return 0; | |
297 | ||
298 | for (i = 0; i < 250; i++) { | |
299 | status = ufx_reg_read(dev, 0x2004, &dc_sts); | |
300 | check_warn_return(status, "ufx_unblank error reading 0x2004"); | |
301 | ||
302 | if ((dc_sts & 0x00000100) == 0) | |
303 | return 0; | |
304 | } | |
305 | ||
306 | /* timed out waiting for display to unblank */ | |
307 | return -EIO; | |
308 | } | |
309 | ||
310 | /* If display is enabled, then disable it */ | |
311 | static int ufx_disable(struct ufx_data *dev, bool wait) | |
312 | { | |
313 | u32 dc_ctrl, dc_sts; | |
314 | int i; | |
315 | ||
316 | int status = ufx_reg_read(dev, 0x2004, &dc_sts); | |
317 | check_warn_return(status, "ufx_disable error reading 0x2004"); | |
318 | ||
319 | status = ufx_reg_read(dev, 0x2000, &dc_ctrl); | |
320 | check_warn_return(status, "ufx_disable error reading 0x2000"); | |
321 | ||
322 | /* return success if display is already disabled */ | |
323 | if (((dc_sts & 0x00000001) == 0) || ((dc_ctrl & 0x00000001) == 0)) | |
324 | return 0; | |
325 | ||
326 | /* request the DC to disable the display */ | |
327 | dc_ctrl &= ~(0x00000001); | |
328 | status = ufx_reg_write(dev, 0x2000, dc_ctrl); | |
329 | check_warn_return(status, "ufx_disable error writing 0x2000"); | |
330 | ||
331 | /* return success immediately if we don't have to wait */ | |
332 | if (!wait) | |
333 | return 0; | |
334 | ||
335 | for (i = 0; i < 250; i++) { | |
336 | status = ufx_reg_read(dev, 0x2004, &dc_sts); | |
337 | check_warn_return(status, "ufx_disable error reading 0x2004"); | |
338 | ||
339 | if ((dc_sts & 0x00000001) == 0) | |
340 | return 0; | |
341 | } | |
342 | ||
343 | /* timed out waiting for display to disable */ | |
344 | return -EIO; | |
345 | } | |
346 | ||
347 | /* If display is disabled, then enable it */ | |
348 | static int ufx_enable(struct ufx_data *dev, bool wait) | |
349 | { | |
350 | u32 dc_ctrl, dc_sts; | |
351 | int i; | |
352 | ||
353 | int status = ufx_reg_read(dev, 0x2004, &dc_sts); | |
354 | check_warn_return(status, "ufx_enable error reading 0x2004"); | |
355 | ||
356 | status = ufx_reg_read(dev, 0x2000, &dc_ctrl); | |
357 | check_warn_return(status, "ufx_enable error reading 0x2000"); | |
358 | ||
359 | /* return success if display is already enabled */ | |
360 | if ((dc_sts & 0x00000001) || (dc_ctrl & 0x00000001)) | |
361 | return 0; | |
362 | ||
363 | /* request the DC to enable the display */ | |
364 | dc_ctrl |= 0x00000001; | |
365 | status = ufx_reg_write(dev, 0x2000, dc_ctrl); | |
366 | check_warn_return(status, "ufx_enable error writing 0x2000"); | |
367 | ||
368 | /* return success immediately if we don't have to wait */ | |
369 | if (!wait) | |
370 | return 0; | |
371 | ||
372 | for (i = 0; i < 250; i++) { | |
373 | status = ufx_reg_read(dev, 0x2004, &dc_sts); | |
374 | check_warn_return(status, "ufx_enable error reading 0x2004"); | |
375 | ||
376 | if (dc_sts & 0x00000001) | |
377 | return 0; | |
378 | } | |
379 | ||
380 | /* timed out waiting for display to enable */ | |
381 | return -EIO; | |
382 | } | |
383 | ||
384 | static int ufx_config_sys_clk(struct ufx_data *dev) | |
385 | { | |
386 | int status = ufx_reg_write(dev, 0x700C, 0x8000000F); | |
387 | check_warn_return(status, "error writing 0x700C"); | |
388 | ||
389 | status = ufx_reg_write(dev, 0x7014, 0x0010024F); | |
390 | check_warn_return(status, "error writing 0x7014"); | |
391 | ||
392 | status = ufx_reg_write(dev, 0x7010, 0x00000000); | |
393 | check_warn_return(status, "error writing 0x7010"); | |
394 | ||
395 | status = ufx_reg_clear_bits(dev, 0x700C, 0x0000000A); | |
396 | check_warn_return(status, "error clearing PLL1 bypass in 0x700C"); | |
397 | msleep(1); | |
398 | ||
399 | status = ufx_reg_clear_bits(dev, 0x700C, 0x80000000); | |
400 | check_warn_return(status, "error clearing output gate in 0x700C"); | |
401 | ||
402 | return 0; | |
403 | } | |
404 | ||
405 | static int ufx_config_ddr2(struct ufx_data *dev) | |
406 | { | |
407 | int status, i = 0; | |
408 | u32 tmp; | |
409 | ||
410 | status = ufx_reg_write(dev, 0x0004, 0x001F0F77); | |
411 | check_warn_return(status, "error writing 0x0004"); | |
412 | ||
413 | status = ufx_reg_write(dev, 0x0008, 0xFFF00000); | |
414 | check_warn_return(status, "error writing 0x0008"); | |
415 | ||
416 | status = ufx_reg_write(dev, 0x000C, 0x0FFF2222); | |
417 | check_warn_return(status, "error writing 0x000C"); | |
418 | ||
419 | status = ufx_reg_write(dev, 0x0010, 0x00030814); | |
420 | check_warn_return(status, "error writing 0x0010"); | |
421 | ||
422 | status = ufx_reg_write(dev, 0x0014, 0x00500019); | |
423 | check_warn_return(status, "error writing 0x0014"); | |
424 | ||
425 | status = ufx_reg_write(dev, 0x0018, 0x020D0F15); | |
426 | check_warn_return(status, "error writing 0x0018"); | |
427 | ||
428 | status = ufx_reg_write(dev, 0x001C, 0x02532305); | |
429 | check_warn_return(status, "error writing 0x001C"); | |
430 | ||
431 | status = ufx_reg_write(dev, 0x0020, 0x0B030905); | |
432 | check_warn_return(status, "error writing 0x0020"); | |
433 | ||
434 | status = ufx_reg_write(dev, 0x0024, 0x00000827); | |
435 | check_warn_return(status, "error writing 0x0024"); | |
436 | ||
437 | status = ufx_reg_write(dev, 0x0028, 0x00000000); | |
438 | check_warn_return(status, "error writing 0x0028"); | |
439 | ||
440 | status = ufx_reg_write(dev, 0x002C, 0x00000042); | |
441 | check_warn_return(status, "error writing 0x002C"); | |
442 | ||
443 | status = ufx_reg_write(dev, 0x0030, 0x09520000); | |
444 | check_warn_return(status, "error writing 0x0030"); | |
445 | ||
446 | status = ufx_reg_write(dev, 0x0034, 0x02223314); | |
447 | check_warn_return(status, "error writing 0x0034"); | |
448 | ||
449 | status = ufx_reg_write(dev, 0x0038, 0x00430043); | |
450 | check_warn_return(status, "error writing 0x0038"); | |
451 | ||
452 | status = ufx_reg_write(dev, 0x003C, 0xF00F000F); | |
453 | check_warn_return(status, "error writing 0x003C"); | |
454 | ||
455 | status = ufx_reg_write(dev, 0x0040, 0xF380F00F); | |
456 | check_warn_return(status, "error writing 0x0040"); | |
457 | ||
458 | status = ufx_reg_write(dev, 0x0044, 0xF00F0496); | |
459 | check_warn_return(status, "error writing 0x0044"); | |
460 | ||
461 | status = ufx_reg_write(dev, 0x0048, 0x03080406); | |
462 | check_warn_return(status, "error writing 0x0048"); | |
463 | ||
464 | status = ufx_reg_write(dev, 0x004C, 0x00001000); | |
465 | check_warn_return(status, "error writing 0x004C"); | |
466 | ||
467 | status = ufx_reg_write(dev, 0x005C, 0x00000007); | |
468 | check_warn_return(status, "error writing 0x005C"); | |
469 | ||
470 | status = ufx_reg_write(dev, 0x0100, 0x54F00012); | |
471 | check_warn_return(status, "error writing 0x0100"); | |
472 | ||
473 | status = ufx_reg_write(dev, 0x0104, 0x00004012); | |
474 | check_warn_return(status, "error writing 0x0104"); | |
475 | ||
476 | status = ufx_reg_write(dev, 0x0118, 0x40404040); | |
477 | check_warn_return(status, "error writing 0x0118"); | |
478 | ||
479 | status = ufx_reg_write(dev, 0x0000, 0x00000001); | |
480 | check_warn_return(status, "error writing 0x0000"); | |
481 | ||
482 | while (i++ < 500) { | |
483 | status = ufx_reg_read(dev, 0x0000, &tmp); | |
484 | check_warn_return(status, "error reading 0x0000"); | |
485 | ||
486 | if (all_bits_set(tmp, 0xC0000000)) | |
487 | return 0; | |
488 | } | |
489 | ||
490 | pr_err("DDR2 initialisation timed out, reg 0x0000=0x%08x", tmp); | |
491 | return -ETIMEDOUT; | |
492 | } | |
493 | ||
494 | struct pll_values { | |
495 | u32 div_r0; | |
496 | u32 div_f0; | |
497 | u32 div_q0; | |
498 | u32 range0; | |
499 | u32 div_r1; | |
500 | u32 div_f1; | |
501 | u32 div_q1; | |
502 | u32 range1; | |
503 | }; | |
504 | ||
505 | static u32 ufx_calc_range(u32 ref_freq) | |
506 | { | |
507 | if (ref_freq >= 88000000) | |
508 | return 7; | |
509 | ||
510 | if (ref_freq >= 54000000) | |
511 | return 6; | |
512 | ||
513 | if (ref_freq >= 34000000) | |
514 | return 5; | |
515 | ||
516 | if (ref_freq >= 21000000) | |
517 | return 4; | |
518 | ||
519 | if (ref_freq >= 13000000) | |
520 | return 3; | |
521 | ||
522 | if (ref_freq >= 8000000) | |
523 | return 2; | |
524 | ||
525 | return 1; | |
526 | } | |
527 | ||
528 | /* calculates PLL divider settings for a desired target frequency */ | |
529 | static void ufx_calc_pll_values(const u32 clk_pixel_pll, struct pll_values *asic_pll) | |
530 | { | |
531 | const u32 ref_clk = 25000000; | |
532 | u32 div_r0, div_f0, div_q0, div_r1, div_f1, div_q1; | |
533 | u32 min_error = clk_pixel_pll; | |
534 | ||
535 | for (div_r0 = 1; div_r0 <= 32; div_r0++) { | |
536 | u32 ref_freq0 = ref_clk / div_r0; | |
537 | if (ref_freq0 < 5000000) | |
538 | break; | |
539 | ||
540 | if (ref_freq0 > 200000000) | |
541 | continue; | |
542 | ||
543 | for (div_f0 = 1; div_f0 <= 256; div_f0++) { | |
544 | u32 vco_freq0 = ref_freq0 * div_f0; | |
545 | ||
546 | if (vco_freq0 < 350000000) | |
547 | continue; | |
548 | ||
549 | if (vco_freq0 > 700000000) | |
550 | break; | |
551 | ||
552 | for (div_q0 = 0; div_q0 < 7; div_q0++) { | |
553 | u32 pllout_freq0 = vco_freq0 / (1 << div_q0); | |
554 | ||
555 | if (pllout_freq0 < 5000000) | |
556 | break; | |
557 | ||
558 | if (pllout_freq0 > 200000000) | |
559 | continue; | |
560 | ||
561 | for (div_r1 = 1; div_r1 <= 32; div_r1++) { | |
562 | u32 ref_freq1 = pllout_freq0 / div_r1; | |
563 | ||
564 | if (ref_freq1 < 5000000) | |
565 | break; | |
566 | ||
567 | for (div_f1 = 1; div_f1 <= 256; div_f1++) { | |
568 | u32 vco_freq1 = ref_freq1 * div_f1; | |
569 | ||
570 | if (vco_freq1 < 350000000) | |
571 | continue; | |
572 | ||
573 | if (vco_freq1 > 700000000) | |
574 | break; | |
575 | ||
576 | for (div_q1 = 0; div_q1 < 7; div_q1++) { | |
577 | u32 pllout_freq1 = vco_freq1 / (1 << div_q1); | |
578 | int error = abs(pllout_freq1 - clk_pixel_pll); | |
579 | ||
580 | if (pllout_freq1 < 5000000) | |
581 | break; | |
582 | ||
583 | if (pllout_freq1 > 700000000) | |
584 | continue; | |
585 | ||
586 | if (error < min_error) { | |
587 | min_error = error; | |
588 | ||
589 | /* final returned value is equal to calculated value - 1 | |
590 | * because a value of 0 = divide by 1 */ | |
591 | asic_pll->div_r0 = div_r0 - 1; | |
592 | asic_pll->div_f0 = div_f0 - 1; | |
593 | asic_pll->div_q0 = div_q0; | |
594 | asic_pll->div_r1 = div_r1 - 1; | |
595 | asic_pll->div_f1 = div_f1 - 1; | |
596 | asic_pll->div_q1 = div_q1; | |
597 | ||
598 | asic_pll->range0 = ufx_calc_range(ref_freq0); | |
599 | asic_pll->range1 = ufx_calc_range(ref_freq1); | |
600 | ||
601 | if (min_error == 0) | |
602 | return; | |
603 | } | |
604 | } | |
605 | } | |
606 | } | |
607 | } | |
608 | } | |
609 | } | |
610 | } | |
611 | ||
612 | /* sets analog bit PLL configuration values */ | |
613 | static int ufx_config_pix_clk(struct ufx_data *dev, u32 pixclock) | |
614 | { | |
615 | struct pll_values asic_pll = {0}; | |
616 | u32 value, clk_pixel, clk_pixel_pll; | |
617 | int status; | |
618 | ||
619 | /* convert pixclock (in ps) to frequency (in Hz) */ | |
620 | clk_pixel = PICOS2KHZ(pixclock) * 1000; | |
621 | pr_debug("pixclock %d ps = clk_pixel %d Hz", pixclock, clk_pixel); | |
622 | ||
623 | /* clk_pixel = 1/2 clk_pixel_pll */ | |
624 | clk_pixel_pll = clk_pixel * 2; | |
625 | ||
626 | ufx_calc_pll_values(clk_pixel_pll, &asic_pll); | |
627 | ||
628 | /* Keep BYPASS and RESET signals asserted until configured */ | |
629 | status = ufx_reg_write(dev, 0x7000, 0x8000000F); | |
630 | check_warn_return(status, "error writing 0x7000"); | |
631 | ||
632 | value = (asic_pll.div_f1 | (asic_pll.div_r1 << 8) | | |
633 | (asic_pll.div_q1 << 16) | (asic_pll.range1 << 20)); | |
634 | status = ufx_reg_write(dev, 0x7008, value); | |
635 | check_warn_return(status, "error writing 0x7008"); | |
636 | ||
637 | value = (asic_pll.div_f0 | (asic_pll.div_r0 << 8) | | |
638 | (asic_pll.div_q0 << 16) | (asic_pll.range0 << 20)); | |
639 | status = ufx_reg_write(dev, 0x7004, value); | |
640 | check_warn_return(status, "error writing 0x7004"); | |
641 | ||
642 | status = ufx_reg_clear_bits(dev, 0x7000, 0x00000005); | |
643 | check_warn_return(status, | |
644 | "error clearing PLL0 bypass bits in 0x7000"); | |
645 | msleep(1); | |
646 | ||
647 | status = ufx_reg_clear_bits(dev, 0x7000, 0x0000000A); | |
648 | check_warn_return(status, | |
649 | "error clearing PLL1 bypass bits in 0x7000"); | |
650 | msleep(1); | |
651 | ||
652 | status = ufx_reg_clear_bits(dev, 0x7000, 0x80000000); | |
653 | check_warn_return(status, "error clearing gate bits in 0x7000"); | |
654 | ||
655 | return 0; | |
656 | } | |
657 | ||
658 | static int ufx_set_vid_mode(struct ufx_data *dev, struct fb_var_screeninfo *var) | |
659 | { | |
660 | u32 temp; | |
661 | u16 h_total, h_active, h_blank_start, h_blank_end, h_sync_start, h_sync_end; | |
662 | u16 v_total, v_active, v_blank_start, v_blank_end, v_sync_start, v_sync_end; | |
663 | ||
664 | int status = ufx_reg_write(dev, 0x8028, 0); | |
665 | check_warn_return(status, "ufx_set_vid_mode error disabling RGB pad"); | |
666 | ||
667 | status = ufx_reg_write(dev, 0x8024, 0); | |
668 | check_warn_return(status, "ufx_set_vid_mode error disabling VDAC"); | |
669 | ||
670 | /* shut everything down before changing timing */ | |
671 | status = ufx_blank(dev, true); | |
672 | check_warn_return(status, "ufx_set_vid_mode error blanking display"); | |
673 | ||
674 | status = ufx_disable(dev, true); | |
675 | check_warn_return(status, "ufx_set_vid_mode error disabling display"); | |
676 | ||
677 | status = ufx_config_pix_clk(dev, var->pixclock); | |
678 | check_warn_return(status, "ufx_set_vid_mode error configuring pixclock"); | |
679 | ||
680 | status = ufx_reg_write(dev, 0x2000, 0x00000104); | |
681 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2000"); | |
682 | ||
683 | /* set horizontal timings */ | |
684 | h_total = var->xres + var->right_margin + var->hsync_len + var->left_margin; | |
685 | h_active = var->xres; | |
686 | h_blank_start = var->xres + var->right_margin; | |
687 | h_blank_end = var->xres + var->right_margin + var->hsync_len; | |
688 | h_sync_start = var->xres + var->right_margin; | |
689 | h_sync_end = var->xres + var->right_margin + var->hsync_len; | |
690 | ||
691 | temp = ((h_total - 1) << 16) | (h_active - 1); | |
692 | status = ufx_reg_write(dev, 0x2008, temp); | |
693 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2008"); | |
694 | ||
695 | temp = ((h_blank_start - 1) << 16) | (h_blank_end - 1); | |
696 | status = ufx_reg_write(dev, 0x200C, temp); | |
697 | check_warn_return(status, "ufx_set_vid_mode error writing 0x200C"); | |
698 | ||
699 | temp = ((h_sync_start - 1) << 16) | (h_sync_end - 1); | |
700 | status = ufx_reg_write(dev, 0x2010, temp); | |
701 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2010"); | |
702 | ||
703 | /* set vertical timings */ | |
704 | v_total = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; | |
705 | v_active = var->yres; | |
706 | v_blank_start = var->yres + var->lower_margin; | |
707 | v_blank_end = var->yres + var->lower_margin + var->vsync_len; | |
708 | v_sync_start = var->yres + var->lower_margin; | |
709 | v_sync_end = var->yres + var->lower_margin + var->vsync_len; | |
710 | ||
711 | temp = ((v_total - 1) << 16) | (v_active - 1); | |
712 | status = ufx_reg_write(dev, 0x2014, temp); | |
713 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2014"); | |
714 | ||
715 | temp = ((v_blank_start - 1) << 16) | (v_blank_end - 1); | |
716 | status = ufx_reg_write(dev, 0x2018, temp); | |
717 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2018"); | |
718 | ||
719 | temp = ((v_sync_start - 1) << 16) | (v_sync_end - 1); | |
720 | status = ufx_reg_write(dev, 0x201C, temp); | |
721 | check_warn_return(status, "ufx_set_vid_mode error writing 0x201C"); | |
722 | ||
723 | status = ufx_reg_write(dev, 0x2020, 0x00000000); | |
724 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2020"); | |
725 | ||
726 | status = ufx_reg_write(dev, 0x2024, 0x00000000); | |
727 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2024"); | |
728 | ||
729 | /* Set the frame length register (#pix * 2 bytes/pixel) */ | |
730 | temp = var->xres * var->yres * 2; | |
731 | temp = (temp + 7) & (~0x7); | |
732 | status = ufx_reg_write(dev, 0x2028, temp); | |
733 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2028"); | |
734 | ||
735 | /* enable desired output interface & disable others */ | |
736 | status = ufx_reg_write(dev, 0x2040, 0); | |
737 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2040"); | |
738 | ||
739 | status = ufx_reg_write(dev, 0x2044, 0); | |
740 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2044"); | |
741 | ||
742 | status = ufx_reg_write(dev, 0x2048, 0); | |
743 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2048"); | |
744 | ||
745 | /* set the sync polarities & enable bit */ | |
746 | temp = 0x00000001; | |
747 | if (var->sync & FB_SYNC_HOR_HIGH_ACT) | |
748 | temp |= 0x00000010; | |
749 | ||
750 | if (var->sync & FB_SYNC_VERT_HIGH_ACT) | |
751 | temp |= 0x00000008; | |
752 | ||
753 | status = ufx_reg_write(dev, 0x2040, temp); | |
754 | check_warn_return(status, "ufx_set_vid_mode error writing 0x2040"); | |
755 | ||
756 | /* start everything back up */ | |
757 | status = ufx_enable(dev, true); | |
758 | check_warn_return(status, "ufx_set_vid_mode error enabling display"); | |
759 | ||
760 | /* Unblank the display */ | |
761 | status = ufx_unblank(dev, true); | |
762 | check_warn_return(status, "ufx_set_vid_mode error unblanking display"); | |
763 | ||
764 | /* enable RGB pad */ | |
765 | status = ufx_reg_write(dev, 0x8028, 0x00000003); | |
766 | check_warn_return(status, "ufx_set_vid_mode error enabling RGB pad"); | |
767 | ||
768 | /* enable VDAC */ | |
769 | status = ufx_reg_write(dev, 0x8024, 0x00000007); | |
770 | check_warn_return(status, "ufx_set_vid_mode error enabling VDAC"); | |
771 | ||
772 | return 0; | |
773 | } | |
774 | ||
775 | static int ufx_ops_mmap(struct fb_info *info, struct vm_area_struct *vma) | |
776 | { | |
777 | unsigned long start = vma->vm_start; | |
778 | unsigned long size = vma->vm_end - vma->vm_start; | |
779 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | |
780 | unsigned long page, pos; | |
781 | ||
04f8afbe TV |
782 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) |
783 | return -EINVAL; | |
784 | if (size > info->fix.smem_len) | |
785 | return -EINVAL; | |
786 | if (offset > info->fix.smem_len - size) | |
3c8a63e2 SG |
787 | return -EINVAL; |
788 | ||
789 | pos = (unsigned long)info->fix.smem_start + offset; | |
790 | ||
791 | pr_debug("mmap() framebuffer addr:%lu size:%lu\n", | |
792 | pos, size); | |
793 | ||
794 | while (size > 0) { | |
795 | page = vmalloc_to_pfn((void *)pos); | |
796 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) | |
797 | return -EAGAIN; | |
798 | ||
799 | start += PAGE_SIZE; | |
800 | pos += PAGE_SIZE; | |
801 | if (size > PAGE_SIZE) | |
802 | size -= PAGE_SIZE; | |
803 | else | |
804 | size = 0; | |
805 | } | |
806 | ||
3c8a63e2 SG |
807 | return 0; |
808 | } | |
809 | ||
be444890 | 810 | static void ufx_raw_rect(struct ufx_data *dev, u16 *cmd, int x, int y, |
3c8a63e2 SG |
811 | int width, int height) |
812 | { | |
813 | size_t packed_line_len = ALIGN((width * 2), 4); | |
814 | size_t packed_rect_len = packed_line_len * height; | |
815 | int line; | |
816 | ||
817 | BUG_ON(!dev); | |
818 | BUG_ON(!dev->info); | |
819 | ||
820 | /* command word */ | |
821 | *((u32 *)&cmd[0]) = cpu_to_le32(0x01); | |
822 | ||
823 | /* length word */ | |
be444890 | 824 | *((u32 *)&cmd[2]) = cpu_to_le32(packed_rect_len + 16); |
3c8a63e2 | 825 | |
be444890 SG |
826 | cmd[4] = cpu_to_le16(x); |
827 | cmd[5] = cpu_to_le16(y); | |
828 | cmd[6] = cpu_to_le16(width); | |
829 | cmd[7] = cpu_to_le16(height); | |
3c8a63e2 SG |
830 | |
831 | /* frame base address */ | |
be444890 | 832 | *((u32 *)&cmd[8]) = cpu_to_le32(0); |
3c8a63e2 SG |
833 | |
834 | /* color mode and horizontal resolution */ | |
be444890 | 835 | cmd[10] = cpu_to_le16(0x4000 | dev->info->var.xres); |
3c8a63e2 SG |
836 | |
837 | /* vertical resolution */ | |
be444890 | 838 | cmd[11] = cpu_to_le16(dev->info->var.yres); |
3c8a63e2 SG |
839 | |
840 | /* packed data */ | |
841 | for (line = 0; line < height; line++) { | |
842 | const int line_offset = dev->info->fix.line_length * (y + line); | |
843 | const int byte_offset = line_offset + (x * BPP); | |
be444890 | 844 | memcpy(&cmd[(24 + (packed_line_len * line)) / 2], |
3c8a63e2 SG |
845 | (char *)dev->info->fix.smem_start + byte_offset, width * BPP); |
846 | } | |
847 | } | |
848 | ||
35f3ec1c | 849 | static int ufx_handle_damage(struct ufx_data *dev, int x, int y, |
3c8a63e2 SG |
850 | int width, int height) |
851 | { | |
852 | size_t packed_line_len = ALIGN((width * 2), 4); | |
853 | int len, status, urb_lines, start_line = 0; | |
854 | ||
855 | if ((width <= 0) || (height <= 0) || | |
856 | (x + width > dev->info->var.xres) || | |
857 | (y + height > dev->info->var.yres)) | |
858 | return -EINVAL; | |
859 | ||
860 | if (!atomic_read(&dev->usb_active)) | |
861 | return 0; | |
862 | ||
863 | while (start_line < height) { | |
864 | struct urb *urb = ufx_get_urb(dev); | |
865 | if (!urb) { | |
866 | pr_warn("ufx_handle_damage unable to get urb"); | |
867 | return 0; | |
868 | } | |
869 | ||
870 | /* assume we have enough space to transfer at least one line */ | |
871 | BUG_ON(urb->transfer_buffer_length < (24 + (width * 2))); | |
872 | ||
873 | /* calculate the maximum number of lines we could fit in */ | |
874 | urb_lines = (urb->transfer_buffer_length - 24) / packed_line_len; | |
875 | ||
876 | /* but we might not need this many */ | |
877 | urb_lines = min(urb_lines, (height - start_line)); | |
878 | ||
879 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); | |
880 | ||
881 | ufx_raw_rect(dev, urb->transfer_buffer, x, (y + start_line), width, urb_lines); | |
882 | len = 24 + (packed_line_len * urb_lines); | |
883 | ||
884 | status = ufx_submit_urb(dev, urb, len); | |
885 | check_warn_return(status, "Error submitting URB"); | |
886 | ||
887 | start_line += urb_lines; | |
888 | } | |
889 | ||
890 | return 0; | |
891 | } | |
892 | ||
893 | /* Path triggered by usermode clients who write to filesystem | |
894 | * e.g. cat filename > /dev/fb1 | |
895 | * Not used by X Windows or text-mode console. But useful for testing. | |
896 | * Slow because of extra copy and we must assume all pixels dirty. */ | |
897 | static ssize_t ufx_ops_write(struct fb_info *info, const char __user *buf, | |
898 | size_t count, loff_t *ppos) | |
899 | { | |
900 | ssize_t result; | |
901 | struct ufx_data *dev = info->par; | |
902 | u32 offset = (u32) *ppos; | |
903 | ||
904 | result = fb_sys_write(info, buf, count, ppos); | |
905 | ||
906 | if (result > 0) { | |
2fe2d9f4 | 907 | int start = max((int)(offset / info->fix.line_length), 0); |
3c8a63e2 SG |
908 | int lines = min((u32)((result / info->fix.line_length) + 1), |
909 | (u32)info->var.yres); | |
910 | ||
911 | ufx_handle_damage(dev, 0, start, info->var.xres, lines); | |
912 | } | |
913 | ||
914 | return result; | |
915 | } | |
916 | ||
917 | static void ufx_ops_copyarea(struct fb_info *info, | |
918 | const struct fb_copyarea *area) | |
919 | { | |
920 | ||
921 | struct ufx_data *dev = info->par; | |
922 | ||
923 | sys_copyarea(info, area); | |
924 | ||
925 | ufx_handle_damage(dev, area->dx, area->dy, | |
926 | area->width, area->height); | |
927 | } | |
928 | ||
929 | static void ufx_ops_imageblit(struct fb_info *info, | |
930 | const struct fb_image *image) | |
931 | { | |
932 | struct ufx_data *dev = info->par; | |
933 | ||
934 | sys_imageblit(info, image); | |
935 | ||
936 | ufx_handle_damage(dev, image->dx, image->dy, | |
937 | image->width, image->height); | |
938 | } | |
939 | ||
940 | static void ufx_ops_fillrect(struct fb_info *info, | |
941 | const struct fb_fillrect *rect) | |
942 | { | |
943 | struct ufx_data *dev = info->par; | |
944 | ||
945 | sys_fillrect(info, rect); | |
946 | ||
947 | ufx_handle_damage(dev, rect->dx, rect->dy, rect->width, | |
948 | rect->height); | |
949 | } | |
950 | ||
951 | /* NOTE: fb_defio.c is holding info->fbdefio.mutex | |
952 | * Touching ANY framebuffer memory that triggers a page fault | |
953 | * in fb_defio will cause a deadlock, when it also tries to | |
954 | * grab the same mutex. */ | |
955 | static void ufx_dpy_deferred_io(struct fb_info *info, | |
956 | struct list_head *pagelist) | |
957 | { | |
958 | struct page *cur; | |
959 | struct fb_deferred_io *fbdefio = info->fbdefio; | |
960 | struct ufx_data *dev = info->par; | |
961 | ||
962 | if (!fb_defio) | |
963 | return; | |
964 | ||
965 | if (!atomic_read(&dev->usb_active)) | |
966 | return; | |
967 | ||
968 | /* walk the written page list and render each to device */ | |
969 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { | |
970 | /* create a rectangle of full screen width that encloses the | |
971 | * entire dirty framebuffer page */ | |
972 | const int x = 0; | |
973 | const int width = dev->info->var.xres; | |
974 | const int y = (cur->index << PAGE_SHIFT) / (width * 2); | |
975 | int height = (PAGE_SIZE / (width * 2)) + 1; | |
976 | height = min(height, (int)(dev->info->var.yres - y)); | |
977 | ||
978 | BUG_ON(y >= dev->info->var.yres); | |
979 | BUG_ON((y + height) > dev->info->var.yres); | |
980 | ||
981 | ufx_handle_damage(dev, x, y, width, height); | |
982 | } | |
983 | } | |
984 | ||
985 | static int ufx_ops_ioctl(struct fb_info *info, unsigned int cmd, | |
986 | unsigned long arg) | |
987 | { | |
988 | struct ufx_data *dev = info->par; | |
989 | struct dloarea *area = NULL; | |
990 | ||
991 | if (!atomic_read(&dev->usb_active)) | |
992 | return 0; | |
993 | ||
994 | /* TODO: Update X server to get this from sysfs instead */ | |
995 | if (cmd == UFX_IOCTL_RETURN_EDID) { | |
261e7676 | 996 | u8 __user *edid = (u8 __user *)arg; |
3c8a63e2 SG |
997 | if (copy_to_user(edid, dev->edid, dev->edid_size)) |
998 | return -EFAULT; | |
999 | return 0; | |
1000 | } | |
1001 | ||
1002 | /* TODO: Help propose a standard fb.h ioctl to report mmap damage */ | |
1003 | if (cmd == UFX_IOCTL_REPORT_DAMAGE) { | |
1004 | /* If we have a damage-aware client, turn fb_defio "off" | |
ff0c2642 | 1005 | * To avoid perf imact of unnecessary page fault handling. |
3c8a63e2 SG |
1006 | * Done by resetting the delay for this fb_info to a very |
1007 | * long period. Pages will become writable and stay that way. | |
1008 | * Reset to normal value when all clients have closed this fb. | |
1009 | */ | |
1010 | if (info->fbdefio) | |
1011 | info->fbdefio->delay = UFX_DEFIO_WRITE_DISABLE; | |
1012 | ||
1013 | area = (struct dloarea *)arg; | |
1014 | ||
1015 | if (area->x < 0) | |
1016 | area->x = 0; | |
1017 | ||
1018 | if (area->x > info->var.xres) | |
1019 | area->x = info->var.xres; | |
1020 | ||
1021 | if (area->y < 0) | |
1022 | area->y = 0; | |
1023 | ||
1024 | if (area->y > info->var.yres) | |
1025 | area->y = info->var.yres; | |
1026 | ||
1027 | ufx_handle_damage(dev, area->x, area->y, area->w, area->h); | |
1028 | } | |
1029 | ||
1030 | return 0; | |
1031 | } | |
1032 | ||
1033 | /* taken from vesafb */ | |
1034 | static int | |
1035 | ufx_ops_setcolreg(unsigned regno, unsigned red, unsigned green, | |
1036 | unsigned blue, unsigned transp, struct fb_info *info) | |
1037 | { | |
1038 | int err = 0; | |
1039 | ||
1040 | if (regno >= info->cmap.len) | |
1041 | return 1; | |
1042 | ||
1043 | if (regno < 16) { | |
1044 | if (info->var.red.offset == 10) { | |
1045 | /* 1:5:5:5 */ | |
1046 | ((u32 *) (info->pseudo_palette))[regno] = | |
1047 | ((red & 0xf800) >> 1) | | |
1048 | ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); | |
1049 | } else { | |
1050 | /* 0:5:6:5 */ | |
1051 | ((u32 *) (info->pseudo_palette))[regno] = | |
1052 | ((red & 0xf800)) | | |
1053 | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); | |
1054 | } | |
1055 | } | |
1056 | ||
1057 | return err; | |
1058 | } | |
1059 | ||
1060 | /* It's common for several clients to have framebuffer open simultaneously. | |
1061 | * e.g. both fbcon and X. Makes things interesting. | |
1062 | * Assumes caller is holding info->lock (for open and release at least) */ | |
1063 | static int ufx_ops_open(struct fb_info *info, int user) | |
1064 | { | |
1065 | struct ufx_data *dev = info->par; | |
1066 | ||
1067 | /* fbcon aggressively connects to first framebuffer it finds, | |
1068 | * preventing other clients (X) from working properly. Usually | |
1069 | * not what the user wants. Fail by default with option to enable. */ | |
1070 | if (user == 0 && !console) | |
1071 | return -EBUSY; | |
1072 | ||
1073 | /* If the USB device is gone, we don't accept new opens */ | |
1074 | if (dev->virtualized) | |
1075 | return -ENODEV; | |
1076 | ||
1077 | dev->fb_count++; | |
1078 | ||
1079 | kref_get(&dev->kref); | |
1080 | ||
1081 | if (fb_defio && (info->fbdefio == NULL)) { | |
1082 | /* enable defio at last moment if not disabled by client */ | |
1083 | ||
1084 | struct fb_deferred_io *fbdefio; | |
1085 | ||
defddeff | 1086 | fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL); |
3c8a63e2 SG |
1087 | if (fbdefio) { |
1088 | fbdefio->delay = UFX_DEFIO_WRITE_DELAY; | |
1089 | fbdefio->deferred_io = ufx_dpy_deferred_io; | |
1090 | } | |
1091 | ||
1092 | info->fbdefio = fbdefio; | |
1093 | fb_deferred_io_init(info); | |
1094 | } | |
1095 | ||
1096 | pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d", | |
1097 | info->node, user, info, dev->fb_count); | |
1098 | ||
1099 | return 0; | |
1100 | } | |
1101 | ||
1102 | /* | |
1103 | * Called when all client interfaces to start transactions have been disabled, | |
1104 | * and all references to our device instance (ufx_data) are released. | |
1105 | * Every transaction must have a reference, so we know are fully spun down | |
1106 | */ | |
1107 | static void ufx_free(struct kref *kref) | |
1108 | { | |
1109 | struct ufx_data *dev = container_of(kref, struct ufx_data, kref); | |
1110 | ||
1111 | /* this function will wait for all in-flight urbs to complete */ | |
1112 | if (dev->urbs.count > 0) | |
1113 | ufx_free_urb_list(dev); | |
1114 | ||
1115 | pr_debug("freeing ufx_data %p", dev); | |
1116 | ||
1117 | kfree(dev); | |
1118 | } | |
1119 | ||
1120 | static void ufx_release_urb_work(struct work_struct *work) | |
1121 | { | |
1122 | struct urb_node *unode = container_of(work, struct urb_node, | |
1123 | release_urb_work.work); | |
1124 | ||
1125 | up(&unode->dev->urbs.limit_sem); | |
1126 | } | |
1127 | ||
1128 | static void ufx_free_framebuffer_work(struct work_struct *work) | |
1129 | { | |
1130 | struct ufx_data *dev = container_of(work, struct ufx_data, | |
1131 | free_framebuffer_work.work); | |
1132 | struct fb_info *info = dev->info; | |
1133 | int node = info->node; | |
1134 | ||
1135 | unregister_framebuffer(info); | |
1136 | ||
1137 | if (info->cmap.len != 0) | |
1138 | fb_dealloc_cmap(&info->cmap); | |
1139 | if (info->monspecs.modedb) | |
1140 | fb_destroy_modedb(info->monspecs.modedb); | |
2daff4d4 | 1141 | vfree(info->screen_base); |
3c8a63e2 SG |
1142 | |
1143 | fb_destroy_modelist(&info->modelist); | |
1144 | ||
9aae307c | 1145 | dev->info = NULL; |
3c8a63e2 SG |
1146 | |
1147 | /* Assume info structure is freed after this point */ | |
1148 | framebuffer_release(info); | |
1149 | ||
1150 | pr_debug("fb_info for /dev/fb%d has been freed", node); | |
1151 | ||
1152 | /* ref taken in probe() as part of registering framebfufer */ | |
1153 | kref_put(&dev->kref, ufx_free); | |
1154 | } | |
1155 | ||
1156 | /* | |
1157 | * Assumes caller is holding info->lock mutex (for open and release at least) | |
1158 | */ | |
1159 | static int ufx_ops_release(struct fb_info *info, int user) | |
1160 | { | |
1161 | struct ufx_data *dev = info->par; | |
1162 | ||
1163 | dev->fb_count--; | |
1164 | ||
1165 | /* We can't free fb_info here - fbmem will touch it when we return */ | |
1166 | if (dev->virtualized && (dev->fb_count == 0)) | |
1167 | schedule_delayed_work(&dev->free_framebuffer_work, HZ); | |
1168 | ||
1169 | if ((dev->fb_count == 0) && (info->fbdefio)) { | |
1170 | fb_deferred_io_cleanup(info); | |
1171 | kfree(info->fbdefio); | |
1172 | info->fbdefio = NULL; | |
1173 | info->fbops->fb_mmap = ufx_ops_mmap; | |
1174 | } | |
1175 | ||
1176 | pr_debug("released /dev/fb%d user=%d count=%d", | |
1177 | info->node, user, dev->fb_count); | |
1178 | ||
1179 | kref_put(&dev->kref, ufx_free); | |
1180 | ||
1181 | return 0; | |
1182 | } | |
1183 | ||
1184 | /* Check whether a video mode is supported by the chip | |
1185 | * We start from monitor's modes, so don't need to filter that here */ | |
1186 | static int ufx_is_valid_mode(struct fb_videomode *mode, | |
1187 | struct fb_info *info) | |
1188 | { | |
1189 | if ((mode->xres * mode->yres) > (2048 * 1152)) { | |
1190 | pr_debug("%dx%d too many pixels", | |
1191 | mode->xres, mode->yres); | |
1192 | return 0; | |
1193 | } | |
1194 | ||
1195 | if (mode->pixclock < 5000) { | |
1196 | pr_debug("%dx%d %dps pixel clock too fast", | |
1197 | mode->xres, mode->yres, mode->pixclock); | |
1198 | return 0; | |
1199 | } | |
1200 | ||
1201 | pr_debug("%dx%d (pixclk %dps %dMHz) valid mode", mode->xres, mode->yres, | |
1202 | mode->pixclock, (1000000 / mode->pixclock)); | |
1203 | return 1; | |
1204 | } | |
1205 | ||
1206 | static void ufx_var_color_format(struct fb_var_screeninfo *var) | |
1207 | { | |
1208 | const struct fb_bitfield red = { 11, 5, 0 }; | |
1209 | const struct fb_bitfield green = { 5, 6, 0 }; | |
1210 | const struct fb_bitfield blue = { 0, 5, 0 }; | |
1211 | ||
1212 | var->bits_per_pixel = 16; | |
1213 | var->red = red; | |
1214 | var->green = green; | |
1215 | var->blue = blue; | |
1216 | } | |
1217 | ||
1218 | static int ufx_ops_check_var(struct fb_var_screeninfo *var, | |
1219 | struct fb_info *info) | |
1220 | { | |
1221 | struct fb_videomode mode; | |
1222 | ||
1223 | /* TODO: support dynamically changing framebuffer size */ | |
1224 | if ((var->xres * var->yres * 2) > info->fix.smem_len) | |
1225 | return -EINVAL; | |
1226 | ||
1227 | /* set device-specific elements of var unrelated to mode */ | |
1228 | ufx_var_color_format(var); | |
1229 | ||
1230 | fb_var_to_videomode(&mode, var); | |
1231 | ||
1232 | if (!ufx_is_valid_mode(&mode, info)) | |
1233 | return -EINVAL; | |
1234 | ||
1235 | return 0; | |
1236 | } | |
1237 | ||
1238 | static int ufx_ops_set_par(struct fb_info *info) | |
1239 | { | |
1240 | struct ufx_data *dev = info->par; | |
1241 | int result; | |
1242 | u16 *pix_framebuffer; | |
1243 | int i; | |
1244 | ||
1245 | pr_debug("set_par mode %dx%d", info->var.xres, info->var.yres); | |
1246 | result = ufx_set_vid_mode(dev, &info->var); | |
1247 | ||
1248 | if ((result == 0) && (dev->fb_count == 0)) { | |
1249 | /* paint greenscreen */ | |
1250 | pix_framebuffer = (u16 *) info->screen_base; | |
1251 | for (i = 0; i < info->fix.smem_len / 2; i++) | |
1252 | pix_framebuffer[i] = 0x37e6; | |
1253 | ||
1254 | ufx_handle_damage(dev, 0, 0, info->var.xres, info->var.yres); | |
1255 | } | |
1256 | ||
1257 | /* re-enable defio if previously disabled by damage tracking */ | |
1258 | if (info->fbdefio) | |
1259 | info->fbdefio->delay = UFX_DEFIO_WRITE_DELAY; | |
1260 | ||
1261 | return result; | |
1262 | } | |
1263 | ||
1264 | /* In order to come back from full DPMS off, we need to set the mode again */ | |
1265 | static int ufx_ops_blank(int blank_mode, struct fb_info *info) | |
1266 | { | |
1267 | struct ufx_data *dev = info->par; | |
1268 | ufx_set_vid_mode(dev, &info->var); | |
1269 | return 0; | |
1270 | } | |
1271 | ||
1272 | static struct fb_ops ufx_ops = { | |
1273 | .owner = THIS_MODULE, | |
1274 | .fb_read = fb_sys_read, | |
1275 | .fb_write = ufx_ops_write, | |
1276 | .fb_setcolreg = ufx_ops_setcolreg, | |
1277 | .fb_fillrect = ufx_ops_fillrect, | |
1278 | .fb_copyarea = ufx_ops_copyarea, | |
1279 | .fb_imageblit = ufx_ops_imageblit, | |
1280 | .fb_mmap = ufx_ops_mmap, | |
1281 | .fb_ioctl = ufx_ops_ioctl, | |
1282 | .fb_open = ufx_ops_open, | |
1283 | .fb_release = ufx_ops_release, | |
1284 | .fb_blank = ufx_ops_blank, | |
1285 | .fb_check_var = ufx_ops_check_var, | |
1286 | .fb_set_par = ufx_ops_set_par, | |
1287 | }; | |
1288 | ||
1289 | /* Assumes &info->lock held by caller | |
1290 | * Assumes no active clients have framebuffer open */ | |
1291 | static int ufx_realloc_framebuffer(struct ufx_data *dev, struct fb_info *info) | |
1292 | { | |
3c8a63e2 SG |
1293 | int old_len = info->fix.smem_len; |
1294 | int new_len; | |
1295 | unsigned char *old_fb = info->screen_base; | |
1296 | unsigned char *new_fb; | |
1297 | ||
1298 | pr_debug("Reallocating framebuffer. Addresses will change!"); | |
1299 | ||
1300 | new_len = info->fix.line_length * info->var.yres; | |
1301 | ||
1302 | if (PAGE_ALIGN(new_len) > old_len) { | |
1303 | /* | |
1304 | * Alloc system memory for virtual framebuffer | |
1305 | */ | |
1306 | new_fb = vmalloc(new_len); | |
66891254 | 1307 | if (!new_fb) |
4befd0cf | 1308 | return -ENOMEM; |
3c8a63e2 SG |
1309 | |
1310 | if (info->screen_base) { | |
1311 | memcpy(new_fb, old_fb, old_len); | |
1312 | vfree(info->screen_base); | |
1313 | } | |
1314 | ||
1315 | info->screen_base = new_fb; | |
1316 | info->fix.smem_len = PAGE_ALIGN(new_len); | |
1317 | info->fix.smem_start = (unsigned long) new_fb; | |
1318 | info->flags = smscufx_info_flags; | |
1319 | } | |
4befd0cf | 1320 | return 0; |
3c8a63e2 SG |
1321 | } |
1322 | ||
1323 | /* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, master, | |
1324 | * restart enabled, but no start byte, enable controller */ | |
1325 | static int ufx_i2c_init(struct ufx_data *dev) | |
1326 | { | |
1327 | u32 tmp; | |
1328 | ||
1329 | /* disable the controller before it can be reprogrammed */ | |
1330 | int status = ufx_reg_write(dev, 0x106C, 0x00); | |
1331 | check_warn_return(status, "failed to disable I2C"); | |
1332 | ||
1333 | /* Setup the clock count registers | |
1334 | * (12+1) = 13 clks @ 2.5 MHz = 5.2 uS */ | |
1335 | status = ufx_reg_write(dev, 0x1018, 12); | |
1336 | check_warn_return(status, "error writing 0x1018"); | |
1337 | ||
1338 | /* (6+8) = 14 clks @ 2.5 MHz = 5.6 uS */ | |
1339 | status = ufx_reg_write(dev, 0x1014, 6); | |
1340 | check_warn_return(status, "error writing 0x1014"); | |
1341 | ||
1342 | status = ufx_reg_read(dev, 0x1000, &tmp); | |
1343 | check_warn_return(status, "error reading 0x1000"); | |
1344 | ||
1345 | /* set speed to std mode */ | |
1346 | tmp &= ~(0x06); | |
1347 | tmp |= 0x02; | |
1348 | ||
1349 | /* 7-bit (not 10-bit) addressing */ | |
1350 | tmp &= ~(0x10); | |
1351 | ||
1352 | /* enable restart conditions and master mode */ | |
1353 | tmp |= 0x21; | |
1354 | ||
1355 | status = ufx_reg_write(dev, 0x1000, tmp); | |
1356 | check_warn_return(status, "error writing 0x1000"); | |
1357 | ||
1358 | /* Set normal tx using target address 0 */ | |
1359 | status = ufx_reg_clear_and_set_bits(dev, 0x1004, 0xC00, 0x000); | |
1360 | check_warn_return(status, "error setting TX mode bits in 0x1004"); | |
1361 | ||
1362 | /* Enable the controller */ | |
1363 | status = ufx_reg_write(dev, 0x106C, 0x01); | |
1364 | check_warn_return(status, "failed to enable I2C"); | |
1365 | ||
1366 | return 0; | |
1367 | } | |
1368 | ||
1369 | /* sets the I2C port mux and target address */ | |
1370 | static int ufx_i2c_configure(struct ufx_data *dev) | |
1371 | { | |
1372 | int status = ufx_reg_write(dev, 0x106C, 0x00); | |
1373 | check_warn_return(status, "failed to disable I2C"); | |
1374 | ||
1375 | status = ufx_reg_write(dev, 0x3010, 0x00000000); | |
1376 | check_warn_return(status, "failed to write 0x3010"); | |
1377 | ||
1378 | /* A0h is std for any EDID, right shifted by one */ | |
1379 | status = ufx_reg_clear_and_set_bits(dev, 0x1004, 0x3FF, (0xA0 >> 1)); | |
1380 | check_warn_return(status, "failed to set TAR bits in 0x1004"); | |
1381 | ||
1382 | status = ufx_reg_write(dev, 0x106C, 0x01); | |
1383 | check_warn_return(status, "failed to enable I2C"); | |
1384 | ||
1385 | return 0; | |
1386 | } | |
1387 | ||
1388 | /* wait for BUSY to clear, with a timeout of 50ms with 10ms sleeps. if no | |
1389 | * monitor is connected, there is no error except for timeout */ | |
1390 | static int ufx_i2c_wait_busy(struct ufx_data *dev) | |
1391 | { | |
1392 | u32 tmp; | |
1393 | int i, status; | |
1394 | ||
1395 | for (i = 0; i < 15; i++) { | |
1396 | status = ufx_reg_read(dev, 0x1100, &tmp); | |
1397 | check_warn_return(status, "0x1100 read failed"); | |
1398 | ||
1399 | /* if BUSY is clear, check for error */ | |
1400 | if ((tmp & 0x80000000) == 0) { | |
1401 | if (tmp & 0x20000000) { | |
1402 | pr_warn("I2C read failed, 0x1100=0x%08x", tmp); | |
1403 | return -EIO; | |
1404 | } | |
1405 | ||
1406 | return 0; | |
1407 | } | |
1408 | ||
1409 | /* perform the first 10 retries without delay */ | |
1410 | if (i >= 10) | |
1411 | msleep(10); | |
1412 | } | |
1413 | ||
1414 | pr_warn("I2C access timed out, resetting I2C hardware"); | |
1415 | status = ufx_reg_write(dev, 0x1100, 0x40000000); | |
1416 | check_warn_return(status, "0x1100 write failed"); | |
1417 | ||
1418 | return -ETIMEDOUT; | |
1419 | } | |
1420 | ||
1421 | /* reads a 128-byte EDID block from the currently selected port and TAR */ | |
261e7676 | 1422 | static int ufx_read_edid(struct ufx_data *dev, u8 *edid, int edid_len) |
3c8a63e2 SG |
1423 | { |
1424 | int i, j, status; | |
1425 | u32 *edid_u32 = (u32 *)edid; | |
1426 | ||
1427 | BUG_ON(edid_len != EDID_LENGTH); | |
1428 | ||
1429 | status = ufx_i2c_configure(dev); | |
1430 | if (status < 0) { | |
1431 | pr_err("ufx_i2c_configure failed"); | |
1432 | return status; | |
1433 | } | |
1434 | ||
1435 | memset(edid, 0xff, EDID_LENGTH); | |
1436 | ||
1437 | /* Read the 128-byte EDID as 2 bursts of 64 bytes */ | |
1438 | for (i = 0; i < 2; i++) { | |
1439 | u32 temp = 0x28070000 | (63 << 20) | (((u32)(i * 64)) << 8); | |
1440 | status = ufx_reg_write(dev, 0x1100, temp); | |
1441 | check_warn_return(status, "Failed to write 0x1100"); | |
1442 | ||
1443 | temp |= 0x80000000; | |
1444 | status = ufx_reg_write(dev, 0x1100, temp); | |
1445 | check_warn_return(status, "Failed to write 0x1100"); | |
1446 | ||
1447 | status = ufx_i2c_wait_busy(dev); | |
1448 | check_warn_return(status, "Timeout waiting for I2C BUSY to clear"); | |
1449 | ||
1450 | for (j = 0; j < 16; j++) { | |
1451 | u32 data_reg_addr = 0x1110 + (j * 4); | |
1452 | status = ufx_reg_read(dev, data_reg_addr, edid_u32++); | |
1453 | check_warn_return(status, "Error reading i2c data"); | |
1454 | } | |
1455 | } | |
1456 | ||
1457 | /* all FF's in the first 16 bytes indicates nothing is connected */ | |
1458 | for (i = 0; i < 16; i++) { | |
1459 | if (edid[i] != 0xFF) { | |
ff0c2642 | 1460 | pr_debug("edid data read successfully"); |
3c8a63e2 SG |
1461 | return EDID_LENGTH; |
1462 | } | |
1463 | } | |
1464 | ||
1465 | pr_warn("edid data contains all 0xff"); | |
1466 | return -ETIMEDOUT; | |
1467 | } | |
1468 | ||
1469 | /* 1) use sw default | |
1470 | * 2) Parse into various fb_info structs | |
1471 | * 3) Allocate virtual framebuffer memory to back highest res mode | |
1472 | * | |
1473 | * Parses EDID into three places used by various parts of fbdev: | |
1474 | * fb_var_screeninfo contains the timing of the monitor's preferred mode | |
1475 | * fb_info.monspecs is full parsed EDID info, including monspecs.modedb | |
1476 | * fb_info.modelist is a linked list of all monitor & VESA modes which work | |
1477 | * | |
1478 | * If EDID is not readable/valid, then modelist is all VESA modes, | |
1479 | * monspecs is NULL, and fb_var_screeninfo is set to safe VESA mode | |
1480 | * Returns 0 if successful */ | |
1481 | static int ufx_setup_modes(struct ufx_data *dev, struct fb_info *info, | |
1482 | char *default_edid, size_t default_edid_size) | |
1483 | { | |
1484 | const struct fb_videomode *default_vmode = NULL; | |
261e7676 | 1485 | u8 *edid; |
3c8a63e2 SG |
1486 | int i, result = 0, tries = 3; |
1487 | ||
1488 | if (info->dev) /* only use mutex if info has been registered */ | |
1489 | mutex_lock(&info->lock); | |
1490 | ||
1491 | edid = kmalloc(EDID_LENGTH, GFP_KERNEL); | |
1492 | if (!edid) { | |
1493 | result = -ENOMEM; | |
1494 | goto error; | |
1495 | } | |
1496 | ||
1497 | fb_destroy_modelist(&info->modelist); | |
1498 | memset(&info->monspecs, 0, sizeof(info->monspecs)); | |
1499 | ||
1500 | /* Try to (re)read EDID from hardware first | |
1501 | * EDID data may return, but not parse as valid | |
1502 | * Try again a few times, in case of e.g. analog cable noise */ | |
1503 | while (tries--) { | |
1504 | i = ufx_read_edid(dev, edid, EDID_LENGTH); | |
1505 | ||
1506 | if (i >= EDID_LENGTH) | |
1507 | fb_edid_to_monspecs(edid, &info->monspecs); | |
1508 | ||
1509 | if (info->monspecs.modedb_len > 0) { | |
1510 | dev->edid = edid; | |
1511 | dev->edid_size = i; | |
1512 | break; | |
1513 | } | |
1514 | } | |
1515 | ||
1516 | /* If that fails, use a previously returned EDID if available */ | |
1517 | if (info->monspecs.modedb_len == 0) { | |
1518 | pr_err("Unable to get valid EDID from device/display\n"); | |
1519 | ||
1520 | if (dev->edid) { | |
1521 | fb_edid_to_monspecs(dev->edid, &info->monspecs); | |
1522 | if (info->monspecs.modedb_len > 0) | |
1523 | pr_err("Using previously queried EDID\n"); | |
1524 | } | |
1525 | } | |
1526 | ||
1527 | /* If that fails, use the default EDID we were handed */ | |
1528 | if (info->monspecs.modedb_len == 0) { | |
1529 | if (default_edid_size >= EDID_LENGTH) { | |
1530 | fb_edid_to_monspecs(default_edid, &info->monspecs); | |
1531 | if (info->monspecs.modedb_len > 0) { | |
1532 | memcpy(edid, default_edid, default_edid_size); | |
1533 | dev->edid = edid; | |
1534 | dev->edid_size = default_edid_size; | |
1535 | pr_err("Using default/backup EDID\n"); | |
1536 | } | |
1537 | } | |
1538 | } | |
1539 | ||
1540 | /* If we've got modes, let's pick a best default mode */ | |
1541 | if (info->monspecs.modedb_len > 0) { | |
1542 | ||
1543 | for (i = 0; i < info->monspecs.modedb_len; i++) { | |
1544 | if (ufx_is_valid_mode(&info->monspecs.modedb[i], info)) | |
1545 | fb_add_videomode(&info->monspecs.modedb[i], | |
1546 | &info->modelist); | |
1547 | else /* if we've removed top/best mode */ | |
1548 | info->monspecs.misc &= ~FB_MISC_1ST_DETAIL; | |
1549 | } | |
1550 | ||
1551 | default_vmode = fb_find_best_display(&info->monspecs, | |
1552 | &info->modelist); | |
1553 | } | |
1554 | ||
1555 | /* If everything else has failed, fall back to safe default mode */ | |
1556 | if (default_vmode == NULL) { | |
1557 | ||
1558 | struct fb_videomode fb_vmode = {0}; | |
1559 | ||
1560 | /* Add the standard VESA modes to our modelist | |
1561 | * Since we don't have EDID, there may be modes that | |
1562 | * overspec monitor and/or are incorrect aspect ratio, etc. | |
1563 | * But at least the user has a chance to choose | |
1564 | */ | |
1565 | for (i = 0; i < VESA_MODEDB_SIZE; i++) { | |
1566 | if (ufx_is_valid_mode((struct fb_videomode *) | |
1567 | &vesa_modes[i], info)) | |
1568 | fb_add_videomode(&vesa_modes[i], | |
1569 | &info->modelist); | |
1570 | } | |
1571 | ||
1572 | /* default to resolution safe for projectors | |
1573 | * (since they are most common case without EDID) | |
1574 | */ | |
1575 | fb_vmode.xres = 800; | |
1576 | fb_vmode.yres = 600; | |
1577 | fb_vmode.refresh = 60; | |
1578 | default_vmode = fb_find_nearest_mode(&fb_vmode, | |
1579 | &info->modelist); | |
1580 | } | |
1581 | ||
1582 | /* If we have good mode and no active clients */ | |
1583 | if ((default_vmode != NULL) && (dev->fb_count == 0)) { | |
1584 | ||
1585 | fb_videomode_to_var(&info->var, default_vmode); | |
1586 | ufx_var_color_format(&info->var); | |
1587 | ||
1588 | /* with mode size info, we can now alloc our framebuffer */ | |
1589 | memcpy(&info->fix, &ufx_fix, sizeof(ufx_fix)); | |
1590 | info->fix.line_length = info->var.xres * | |
1591 | (info->var.bits_per_pixel / 8); | |
1592 | ||
1593 | result = ufx_realloc_framebuffer(dev, info); | |
1594 | ||
1595 | } else | |
1596 | result = -EINVAL; | |
1597 | ||
1598 | error: | |
1599 | if (edid && (dev->edid != edid)) | |
1600 | kfree(edid); | |
1601 | ||
1602 | if (info->dev) | |
1603 | mutex_unlock(&info->lock); | |
1604 | ||
1605 | return result; | |
1606 | } | |
1607 | ||
1608 | static int ufx_usb_probe(struct usb_interface *interface, | |
1609 | const struct usb_device_id *id) | |
1610 | { | |
1611 | struct usb_device *usbdev; | |
1612 | struct ufx_data *dev; | |
daa0524b ME |
1613 | struct fb_info *info; |
1614 | int retval; | |
3c8a63e2 SG |
1615 | u32 id_rev, fpga_rev; |
1616 | ||
1617 | /* usb initialization */ | |
1618 | usbdev = interface_to_usbdev(interface); | |
1619 | BUG_ON(!usbdev); | |
1620 | ||
1621 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | |
1622 | if (dev == NULL) { | |
1623 | dev_err(&usbdev->dev, "ufx_usb_probe: failed alloc of dev struct\n"); | |
daa0524b | 1624 | return -ENOMEM; |
3c8a63e2 SG |
1625 | } |
1626 | ||
1627 | /* we need to wait for both usb and fbdev to spin down on disconnect */ | |
1628 | kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */ | |
1629 | kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */ | |
1630 | ||
1631 | dev->udev = usbdev; | |
1632 | dev->gdev = &usbdev->dev; /* our generic struct device * */ | |
1633 | usb_set_intfdata(interface, dev); | |
1634 | ||
1635 | dev_dbg(dev->gdev, "%s %s - serial #%s\n", | |
1636 | usbdev->manufacturer, usbdev->product, usbdev->serial); | |
1637 | dev_dbg(dev->gdev, "vid_%04x&pid_%04x&rev_%04x driver's ufx_data struct at %p\n", | |
12351855 JH |
1638 | le16_to_cpu(usbdev->descriptor.idVendor), |
1639 | le16_to_cpu(usbdev->descriptor.idProduct), | |
1640 | le16_to_cpu(usbdev->descriptor.bcdDevice), dev); | |
3c8a63e2 SG |
1641 | dev_dbg(dev->gdev, "console enable=%d\n", console); |
1642 | dev_dbg(dev->gdev, "fb_defio enable=%d\n", fb_defio); | |
1643 | ||
1644 | if (!ufx_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) { | |
3c8a63e2 | 1645 | dev_err(dev->gdev, "ufx_alloc_urb_list failed\n"); |
daa0524b | 1646 | goto e_nomem; |
3c8a63e2 SG |
1647 | } |
1648 | ||
1649 | /* We don't register a new USB class. Our client interface is fbdev */ | |
1650 | ||
1651 | /* allocates framebuffer driver structure, not framebuffer memory */ | |
1652 | info = framebuffer_alloc(0, &usbdev->dev); | |
1653 | if (!info) { | |
3c8a63e2 | 1654 | dev_err(dev->gdev, "framebuffer_alloc failed\n"); |
daa0524b | 1655 | goto e_nomem; |
3c8a63e2 SG |
1656 | } |
1657 | ||
1658 | dev->info = info; | |
1659 | info->par = dev; | |
1660 | info->pseudo_palette = dev->pseudo_palette; | |
1661 | info->fbops = &ufx_ops; | |
1662 | ||
1663 | retval = fb_alloc_cmap(&info->cmap, 256, 0); | |
1664 | if (retval < 0) { | |
1665 | dev_err(dev->gdev, "fb_alloc_cmap failed %x\n", retval); | |
daa0524b | 1666 | goto destroy_modedb; |
3c8a63e2 SG |
1667 | } |
1668 | ||
1669 | INIT_DELAYED_WORK(&dev->free_framebuffer_work, | |
1670 | ufx_free_framebuffer_work); | |
1671 | ||
1672 | INIT_LIST_HEAD(&info->modelist); | |
1673 | ||
1674 | retval = ufx_reg_read(dev, 0x3000, &id_rev); | |
1675 | check_warn_goto_error(retval, "error %d reading 0x3000 register from device", retval); | |
1676 | dev_dbg(dev->gdev, "ID_REV register value 0x%08x", id_rev); | |
1677 | ||
1678 | retval = ufx_reg_read(dev, 0x3004, &fpga_rev); | |
1679 | check_warn_goto_error(retval, "error %d reading 0x3004 register from device", retval); | |
1680 | dev_dbg(dev->gdev, "FPGA_REV register value 0x%08x", fpga_rev); | |
1681 | ||
1682 | dev_dbg(dev->gdev, "resetting device"); | |
1683 | retval = ufx_lite_reset(dev); | |
1684 | check_warn_goto_error(retval, "error %d resetting device", retval); | |
1685 | ||
1686 | dev_dbg(dev->gdev, "configuring system clock"); | |
1687 | retval = ufx_config_sys_clk(dev); | |
1688 | check_warn_goto_error(retval, "error %d configuring system clock", retval); | |
1689 | ||
1690 | dev_dbg(dev->gdev, "configuring DDR2 controller"); | |
1691 | retval = ufx_config_ddr2(dev); | |
1692 | check_warn_goto_error(retval, "error %d initialising DDR2 controller", retval); | |
1693 | ||
1694 | dev_dbg(dev->gdev, "configuring I2C controller"); | |
1695 | retval = ufx_i2c_init(dev); | |
1696 | check_warn_goto_error(retval, "error %d initialising I2C controller", retval); | |
1697 | ||
1698 | dev_dbg(dev->gdev, "selecting display mode"); | |
1699 | retval = ufx_setup_modes(dev, info, NULL, 0); | |
1700 | check_warn_goto_error(retval, "unable to find common mode for display and adapter"); | |
1701 | ||
1702 | retval = ufx_reg_set_bits(dev, 0x4000, 0x00000001); | |
1703 | check_warn_goto_error(retval, "error %d enabling graphics engine", retval); | |
1704 | ||
1705 | /* ready to begin using device */ | |
1706 | atomic_set(&dev->usb_active, 1); | |
1707 | ||
1708 | dev_dbg(dev->gdev, "checking var"); | |
1709 | retval = ufx_ops_check_var(&info->var, info); | |
1710 | check_warn_goto_error(retval, "error %d ufx_ops_check_var", retval); | |
1711 | ||
1712 | dev_dbg(dev->gdev, "setting par"); | |
1713 | retval = ufx_ops_set_par(info); | |
1714 | check_warn_goto_error(retval, "error %d ufx_ops_set_par", retval); | |
1715 | ||
1716 | dev_dbg(dev->gdev, "registering framebuffer"); | |
1717 | retval = register_framebuffer(info); | |
1718 | check_warn_goto_error(retval, "error %d register_framebuffer", retval); | |
1719 | ||
1720 | dev_info(dev->gdev, "SMSC UDX USB device /dev/fb%d attached. %dx%d resolution." | |
1721 | " Using %dK framebuffer memory\n", info->node, | |
1722 | info->var.xres, info->var.yres, info->fix.smem_len >> 10); | |
1723 | ||
1724 | return 0; | |
1725 | ||
1726 | error: | |
daa0524b ME |
1727 | fb_dealloc_cmap(&info->cmap); |
1728 | destroy_modedb: | |
1729 | fb_destroy_modedb(info->monspecs.modedb); | |
1730 | vfree(info->screen_base); | |
1731 | fb_destroy_modelist(&info->modelist); | |
1732 | framebuffer_release(info); | |
1733 | put_ref: | |
1734 | kref_put(&dev->kref, ufx_free); /* ref for framebuffer */ | |
1735 | kref_put(&dev->kref, ufx_free); /* last ref from kref_init */ | |
3c8a63e2 | 1736 | return retval; |
daa0524b ME |
1737 | |
1738 | e_nomem: | |
1739 | retval = -ENOMEM; | |
1740 | goto put_ref; | |
3c8a63e2 SG |
1741 | } |
1742 | ||
1743 | static void ufx_usb_disconnect(struct usb_interface *interface) | |
1744 | { | |
1745 | struct ufx_data *dev; | |
3c8a63e2 SG |
1746 | |
1747 | dev = usb_get_intfdata(interface); | |
3c8a63e2 SG |
1748 | |
1749 | pr_debug("USB disconnect starting\n"); | |
1750 | ||
1751 | /* we virtualize until all fb clients release. Then we free */ | |
1752 | dev->virtualized = true; | |
1753 | ||
1754 | /* When non-active we'll update virtual framebuffer, but no new urbs */ | |
1755 | atomic_set(&dev->usb_active, 0); | |
1756 | ||
1757 | usb_set_intfdata(interface, NULL); | |
1758 | ||
1759 | /* if clients still have us open, will be freed on last close */ | |
1760 | if (dev->fb_count == 0) | |
1761 | schedule_delayed_work(&dev->free_framebuffer_work, 0); | |
1762 | ||
1763 | /* release reference taken by kref_init in probe() */ | |
1764 | kref_put(&dev->kref, ufx_free); | |
1765 | ||
1766 | /* consider ufx_data freed */ | |
1767 | } | |
1768 | ||
1769 | static struct usb_driver ufx_driver = { | |
1770 | .name = "smscufx", | |
1771 | .probe = ufx_usb_probe, | |
1772 | .disconnect = ufx_usb_disconnect, | |
1773 | .id_table = id_table, | |
1774 | }; | |
1775 | ||
fe748483 | 1776 | module_usb_driver(ufx_driver); |
3c8a63e2 SG |
1777 | |
1778 | static void ufx_urb_completion(struct urb *urb) | |
1779 | { | |
1780 | struct urb_node *unode = urb->context; | |
1781 | struct ufx_data *dev = unode->dev; | |
1782 | unsigned long flags; | |
1783 | ||
1784 | /* sync/async unlink faults aren't errors */ | |
1785 | if (urb->status) { | |
1786 | if (!(urb->status == -ENOENT || | |
1787 | urb->status == -ECONNRESET || | |
1788 | urb->status == -ESHUTDOWN)) { | |
1789 | pr_err("%s - nonzero write bulk status received: %d\n", | |
1790 | __func__, urb->status); | |
1791 | atomic_set(&dev->lost_pixels, 1); | |
1792 | } | |
1793 | } | |
1794 | ||
1795 | urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */ | |
1796 | ||
1797 | spin_lock_irqsave(&dev->urbs.lock, flags); | |
1798 | list_add_tail(&unode->entry, &dev->urbs.list); | |
1799 | dev->urbs.available++; | |
1800 | spin_unlock_irqrestore(&dev->urbs.lock, flags); | |
1801 | ||
1802 | /* When using fb_defio, we deadlock if up() is called | |
1803 | * while another is waiting. So queue to another process */ | |
1804 | if (fb_defio) | |
1805 | schedule_delayed_work(&unode->release_urb_work, 0); | |
1806 | else | |
1807 | up(&dev->urbs.limit_sem); | |
1808 | } | |
1809 | ||
1810 | static void ufx_free_urb_list(struct ufx_data *dev) | |
1811 | { | |
1812 | int count = dev->urbs.count; | |
1813 | struct list_head *node; | |
1814 | struct urb_node *unode; | |
1815 | struct urb *urb; | |
1816 | int ret; | |
1817 | unsigned long flags; | |
1818 | ||
1819 | pr_debug("Waiting for completes and freeing all render urbs\n"); | |
1820 | ||
1821 | /* keep waiting and freeing, until we've got 'em all */ | |
1822 | while (count--) { | |
1823 | /* Getting interrupted means a leak, but ok at shutdown*/ | |
1824 | ret = down_interruptible(&dev->urbs.limit_sem); | |
1825 | if (ret) | |
1826 | break; | |
1827 | ||
1828 | spin_lock_irqsave(&dev->urbs.lock, flags); | |
1829 | ||
1830 | node = dev->urbs.list.next; /* have reserved one with sem */ | |
1831 | list_del_init(node); | |
1832 | ||
1833 | spin_unlock_irqrestore(&dev->urbs.lock, flags); | |
1834 | ||
1835 | unode = list_entry(node, struct urb_node, entry); | |
1836 | urb = unode->urb; | |
1837 | ||
1838 | /* Free each separately allocated piece */ | |
1839 | usb_free_coherent(urb->dev, dev->urbs.size, | |
1840 | urb->transfer_buffer, urb->transfer_dma); | |
1841 | usb_free_urb(urb); | |
1842 | kfree(node); | |
1843 | } | |
1844 | } | |
1845 | ||
1846 | static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size) | |
1847 | { | |
1848 | int i = 0; | |
1849 | struct urb *urb; | |
1850 | struct urb_node *unode; | |
1851 | char *buf; | |
1852 | ||
1853 | spin_lock_init(&dev->urbs.lock); | |
1854 | ||
1855 | dev->urbs.size = size; | |
1856 | INIT_LIST_HEAD(&dev->urbs.list); | |
1857 | ||
1858 | while (i < count) { | |
defddeff | 1859 | unode = kzalloc(sizeof(*unode), GFP_KERNEL); |
3c8a63e2 SG |
1860 | if (!unode) |
1861 | break; | |
1862 | unode->dev = dev; | |
1863 | ||
1864 | INIT_DELAYED_WORK(&unode->release_urb_work, | |
1865 | ufx_release_urb_work); | |
1866 | ||
1867 | urb = usb_alloc_urb(0, GFP_KERNEL); | |
1868 | if (!urb) { | |
1869 | kfree(unode); | |
1870 | break; | |
1871 | } | |
1872 | unode->urb = urb; | |
1873 | ||
1874 | buf = usb_alloc_coherent(dev->udev, size, GFP_KERNEL, | |
1875 | &urb->transfer_dma); | |
1876 | if (!buf) { | |
1877 | kfree(unode); | |
1878 | usb_free_urb(urb); | |
1879 | break; | |
1880 | } | |
1881 | ||
1882 | /* urb->transfer_buffer_length set to actual before submit */ | |
1883 | usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1), | |
1884 | buf, size, ufx_urb_completion, unode); | |
1885 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | |
1886 | ||
1887 | list_add_tail(&unode->entry, &dev->urbs.list); | |
1888 | ||
1889 | i++; | |
1890 | } | |
1891 | ||
1892 | sema_init(&dev->urbs.limit_sem, i); | |
1893 | dev->urbs.count = i; | |
1894 | dev->urbs.available = i; | |
1895 | ||
1896 | pr_debug("allocated %d %d byte urbs\n", i, (int) size); | |
1897 | ||
1898 | return i; | |
1899 | } | |
1900 | ||
1901 | static struct urb *ufx_get_urb(struct ufx_data *dev) | |
1902 | { | |
1903 | int ret = 0; | |
1904 | struct list_head *entry; | |
1905 | struct urb_node *unode; | |
1906 | struct urb *urb = NULL; | |
1907 | unsigned long flags; | |
1908 | ||
1909 | /* Wait for an in-flight buffer to complete and get re-queued */ | |
1910 | ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT); | |
1911 | if (ret) { | |
1912 | atomic_set(&dev->lost_pixels, 1); | |
1913 | pr_warn("wait for urb interrupted: %x available: %d\n", | |
1914 | ret, dev->urbs.available); | |
1915 | goto error; | |
1916 | } | |
1917 | ||
1918 | spin_lock_irqsave(&dev->urbs.lock, flags); | |
1919 | ||
1920 | BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */ | |
1921 | entry = dev->urbs.list.next; | |
1922 | list_del_init(entry); | |
1923 | dev->urbs.available--; | |
1924 | ||
1925 | spin_unlock_irqrestore(&dev->urbs.lock, flags); | |
1926 | ||
1927 | unode = list_entry(entry, struct urb_node, entry); | |
1928 | urb = unode->urb; | |
1929 | ||
1930 | error: | |
1931 | return urb; | |
1932 | } | |
1933 | ||
1934 | static int ufx_submit_urb(struct ufx_data *dev, struct urb *urb, size_t len) | |
1935 | { | |
1936 | int ret; | |
1937 | ||
1938 | BUG_ON(len > dev->urbs.size); | |
1939 | ||
1940 | urb->transfer_buffer_length = len; /* set to actual payload len */ | |
1941 | ret = usb_submit_urb(urb, GFP_KERNEL); | |
1942 | if (ret) { | |
1943 | ufx_urb_completion(urb); /* because no one else will */ | |
1944 | atomic_set(&dev->lost_pixels, 1); | |
1945 | pr_err("usb_submit_urb error %x\n", ret); | |
1946 | } | |
1947 | return ret; | |
1948 | } | |
1949 | ||
1950 | module_param(console, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); | |
1951 | MODULE_PARM_DESC(console, "Allow fbcon to be used on this display"); | |
1952 | ||
1953 | module_param(fb_defio, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); | |
1954 | MODULE_PARM_DESC(fb_defio, "Enable fb_defio mmap support"); | |
1955 | ||
90b24cfb | 1956 | MODULE_AUTHOR("Steve Glendinning <steve.glendinning@shawell.net>"); |
3c8a63e2 SG |
1957 | MODULE_DESCRIPTION("SMSC UFX kernel framebuffer driver"); |
1958 | MODULE_LICENSE("GPL"); |