]> Git Repo - linux.git/blob - drivers/gpu/drm/tiny/gm12u320.c
Merge tag 'keys-cve-2020-26541-v3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / gpu / drm / tiny / gm12u320.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019 Hans de Goede <[email protected]>
4  */
5
6 #include <linux/dma-buf.h>
7 #include <linux/module.h>
8 #include <linux/usb.h>
9
10 #include <drm/drm_atomic_helper.h>
11 #include <drm/drm_atomic_state_helper.h>
12 #include <drm/drm_connector.h>
13 #include <drm/drm_damage_helper.h>
14 #include <drm/drm_drv.h>
15 #include <drm/drm_fb_helper.h>
16 #include <drm/drm_file.h>
17 #include <drm/drm_format_helper.h>
18 #include <drm/drm_fourcc.h>
19 #include <drm/drm_gem_shmem_helper.h>
20 #include <drm/drm_gem_framebuffer_helper.h>
21 #include <drm/drm_ioctl.h>
22 #include <drm/drm_managed.h>
23 #include <drm/drm_modeset_helper_vtables.h>
24 #include <drm/drm_probe_helper.h>
25 #include <drm/drm_simple_kms_helper.h>
26
27 static bool eco_mode;
28 module_param(eco_mode, bool, 0644);
29 MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
30
31 #define DRIVER_NAME             "gm12u320"
32 #define DRIVER_DESC             "Grain Media GM12U320 USB projector display"
33 #define DRIVER_DATE             "2019"
34 #define DRIVER_MAJOR            1
35 #define DRIVER_MINOR            0
36
37 /*
38  * The DLP has an actual width of 854 pixels, but that is not a multiple
39  * of 8, breaking things left and right, so we export a width of 848.
40  */
41 #define GM12U320_USER_WIDTH             848
42 #define GM12U320_REAL_WIDTH             854
43 #define GM12U320_HEIGHT                 480
44
45 #define GM12U320_BLOCK_COUNT            20
46
47 #define GM12U320_ERR(fmt, ...) \
48         DRM_DEV_ERROR(gm12u320->dev.dev, fmt, ##__VA_ARGS__)
49
50 #define MISC_RCV_EPT                    1
51 #define DATA_RCV_EPT                    2
52 #define DATA_SND_EPT                    3
53 #define MISC_SND_EPT                    4
54
55 #define DATA_BLOCK_HEADER_SIZE          84
56 #define DATA_BLOCK_CONTENT_SIZE         64512
57 #define DATA_BLOCK_FOOTER_SIZE          20
58 #define DATA_BLOCK_SIZE                 (DATA_BLOCK_HEADER_SIZE + \
59                                          DATA_BLOCK_CONTENT_SIZE + \
60                                          DATA_BLOCK_FOOTER_SIZE)
61 #define DATA_LAST_BLOCK_CONTENT_SIZE    4032
62 #define DATA_LAST_BLOCK_SIZE            (DATA_BLOCK_HEADER_SIZE + \
63                                          DATA_LAST_BLOCK_CONTENT_SIZE + \
64                                          DATA_BLOCK_FOOTER_SIZE)
65
66 #define CMD_SIZE                        31
67 #define READ_STATUS_SIZE                13
68 #define MISC_VALUE_SIZE                 4
69
70 #define CMD_TIMEOUT                     msecs_to_jiffies(200)
71 #define DATA_TIMEOUT                    msecs_to_jiffies(1000)
72 #define IDLE_TIMEOUT                    msecs_to_jiffies(2000)
73 #define FIRST_FRAME_TIMEOUT             msecs_to_jiffies(2000)
74
75 #define MISC_REQ_GET_SET_ECO_A          0xff
76 #define MISC_REQ_GET_SET_ECO_B          0x35
77 /* Windows driver does once every second, with arg d = 1, other args 0 */
78 #define MISC_REQ_UNKNOWN1_A             0xff
79 #define MISC_REQ_UNKNOWN1_B             0x38
80 /* Windows driver does this on init, with arg a, b = 0, c = 0xa0, d = 4 */
81 #define MISC_REQ_UNKNOWN2_A             0xa5
82 #define MISC_REQ_UNKNOWN2_B             0x00
83
84 struct gm12u320_device {
85         struct drm_device                dev;
86         struct device                   *dmadev;
87         struct drm_simple_display_pipe   pipe;
88         struct drm_connector             conn;
89         unsigned char                   *cmd_buf;
90         unsigned char                   *data_buf[GM12U320_BLOCK_COUNT];
91         struct {
92                 struct delayed_work       work;
93                 struct mutex             lock;
94                 struct drm_framebuffer  *fb;
95                 struct drm_rect          rect;
96                 int frame;
97                 int draw_status_timeout;
98         } fb_update;
99 };
100
101 #define to_gm12u320(__dev) container_of(__dev, struct gm12u320_device, dev)
102
103 static const char cmd_data[CMD_SIZE] = {
104         0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
105         0x68, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff,
106         0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80, 0x00,
107         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
108 };
109
110 static const char cmd_draw[CMD_SIZE] = {
111         0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
112         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xfe,
113         0x00, 0x00, 0x00, 0xc0, 0xd1, 0x05, 0x00, 0x40,
114         0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
115 };
116
117 static const char cmd_misc[CMD_SIZE] = {
118         0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
119         0x04, 0x00, 0x00, 0x00, 0x80, 0x01, 0x10, 0xfd,
120         0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
121         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
122 };
123
124 static const char data_block_header[DATA_BLOCK_HEADER_SIZE] = {
125         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133         0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134         0x00, 0x04, 0x15, 0x00, 0x00, 0xfc, 0x00, 0x00,
135         0x01, 0x00, 0x00, 0xdb
136 };
137
138 static const char data_last_block_header[DATA_BLOCK_HEADER_SIZE] = {
139         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147         0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148         0x2a, 0x00, 0x20, 0x00, 0xc0, 0x0f, 0x00, 0x00,
149         0x01, 0x00, 0x00, 0xd7
150 };
151
152 static const char data_block_footer[DATA_BLOCK_FOOTER_SIZE] = {
153         0xfb, 0x14, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
154         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155         0x80, 0x00, 0x00, 0x4f
156 };
157
158 static inline struct usb_device *gm12u320_to_usb_device(struct gm12u320_device *gm12u320)
159 {
160         return interface_to_usbdev(to_usb_interface(gm12u320->dev.dev));
161 }
162
163 static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
164 {
165         int i, block_size;
166         const char *hdr;
167
168         gm12u320->cmd_buf = drmm_kmalloc(&gm12u320->dev, CMD_SIZE, GFP_KERNEL);
169         if (!gm12u320->cmd_buf)
170                 return -ENOMEM;
171
172         for (i = 0; i < GM12U320_BLOCK_COUNT; i++) {
173                 if (i == GM12U320_BLOCK_COUNT - 1) {
174                         block_size = DATA_LAST_BLOCK_SIZE;
175                         hdr = data_last_block_header;
176                 } else {
177                         block_size = DATA_BLOCK_SIZE;
178                         hdr = data_block_header;
179                 }
180
181                 gm12u320->data_buf[i] = drmm_kzalloc(&gm12u320->dev,
182                                                      block_size, GFP_KERNEL);
183                 if (!gm12u320->data_buf[i])
184                         return -ENOMEM;
185
186                 memcpy(gm12u320->data_buf[i], hdr, DATA_BLOCK_HEADER_SIZE);
187                 memcpy(gm12u320->data_buf[i] +
188                                 (block_size - DATA_BLOCK_FOOTER_SIZE),
189                        data_block_footer, DATA_BLOCK_FOOTER_SIZE);
190         }
191
192         return 0;
193 }
194
195 static int gm12u320_misc_request(struct gm12u320_device *gm12u320,
196                                  u8 req_a, u8 req_b,
197                                  u8 arg_a, u8 arg_b, u8 arg_c, u8 arg_d)
198 {
199         struct usb_device *udev = gm12u320_to_usb_device(gm12u320);
200         int ret, len;
201
202         memcpy(gm12u320->cmd_buf, &cmd_misc, CMD_SIZE);
203         gm12u320->cmd_buf[20] = req_a;
204         gm12u320->cmd_buf[21] = req_b;
205         gm12u320->cmd_buf[22] = arg_a;
206         gm12u320->cmd_buf[23] = arg_b;
207         gm12u320->cmd_buf[24] = arg_c;
208         gm12u320->cmd_buf[25] = arg_d;
209
210         /* Send request */
211         ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, MISC_SND_EPT),
212                            gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
213         if (ret || len != CMD_SIZE) {
214                 GM12U320_ERR("Misc. req. error %d\n", ret);
215                 return -EIO;
216         }
217
218         /* Read value */
219         ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, MISC_RCV_EPT),
220                            gm12u320->cmd_buf, MISC_VALUE_SIZE, &len,
221                            DATA_TIMEOUT);
222         if (ret || len != MISC_VALUE_SIZE) {
223                 GM12U320_ERR("Misc. value error %d\n", ret);
224                 return -EIO;
225         }
226         /* cmd_buf[0] now contains the read value, which we don't use */
227
228         /* Read status */
229         ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, MISC_RCV_EPT),
230                            gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
231                            CMD_TIMEOUT);
232         if (ret || len != READ_STATUS_SIZE) {
233                 GM12U320_ERR("Misc. status error %d\n", ret);
234                 return -EIO;
235         }
236
237         return 0;
238 }
239
240 static void gm12u320_32bpp_to_24bpp_packed(u8 *dst, u8 *src, int len)
241 {
242         while (len--) {
243                 *dst++ = *src++;
244                 *dst++ = *src++;
245                 *dst++ = *src++;
246                 src++;
247         }
248 }
249
250 static void gm12u320_copy_fb_to_blocks(struct gm12u320_device *gm12u320)
251 {
252         int block, dst_offset, len, remain, ret, x1, x2, y1, y2;
253         struct drm_framebuffer *fb;
254         struct dma_buf_map map;
255         void *vaddr;
256         u8 *src;
257
258         mutex_lock(&gm12u320->fb_update.lock);
259
260         if (!gm12u320->fb_update.fb)
261                 goto unlock;
262
263         fb = gm12u320->fb_update.fb;
264         x1 = gm12u320->fb_update.rect.x1;
265         x2 = gm12u320->fb_update.rect.x2;
266         y1 = gm12u320->fb_update.rect.y1;
267         y2 = gm12u320->fb_update.rect.y2;
268
269         ret = drm_gem_shmem_vmap(fb->obj[0], &map);
270         if (ret) {
271                 GM12U320_ERR("failed to vmap fb: %d\n", ret);
272                 goto put_fb;
273         }
274         vaddr = map.vaddr; /* TODO: Use mapping abstraction properly */
275
276         if (fb->obj[0]->import_attach) {
277                 ret = dma_buf_begin_cpu_access(
278                         fb->obj[0]->import_attach->dmabuf, DMA_FROM_DEVICE);
279                 if (ret) {
280                         GM12U320_ERR("dma_buf_begin_cpu_access err: %d\n", ret);
281                         goto vunmap;
282                 }
283         }
284
285         src = vaddr + y1 * fb->pitches[0] + x1 * 4;
286
287         x1 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
288         x2 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
289
290         for (; y1 < y2; y1++) {
291                 remain = 0;
292                 len = (x2 - x1) * 3;
293                 dst_offset = (y1 * GM12U320_REAL_WIDTH + x1) * 3;
294                 block = dst_offset / DATA_BLOCK_CONTENT_SIZE;
295                 dst_offset %= DATA_BLOCK_CONTENT_SIZE;
296
297                 if ((dst_offset + len) > DATA_BLOCK_CONTENT_SIZE) {
298                         remain = dst_offset + len - DATA_BLOCK_CONTENT_SIZE;
299                         len = DATA_BLOCK_CONTENT_SIZE - dst_offset;
300                 }
301
302                 dst_offset += DATA_BLOCK_HEADER_SIZE;
303                 len /= 3;
304
305                 gm12u320_32bpp_to_24bpp_packed(
306                         gm12u320->data_buf[block] + dst_offset,
307                         src, len);
308
309                 if (remain) {
310                         block++;
311                         dst_offset = DATA_BLOCK_HEADER_SIZE;
312                         gm12u320_32bpp_to_24bpp_packed(
313                                 gm12u320->data_buf[block] + dst_offset,
314                                 src + len * 4, remain / 3);
315                 }
316                 src += fb->pitches[0];
317         }
318
319         if (fb->obj[0]->import_attach) {
320                 ret = dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf,
321                                              DMA_FROM_DEVICE);
322                 if (ret)
323                         GM12U320_ERR("dma_buf_end_cpu_access err: %d\n", ret);
324         }
325 vunmap:
326         drm_gem_shmem_vunmap(fb->obj[0], &map);
327 put_fb:
328         drm_framebuffer_put(fb);
329         gm12u320->fb_update.fb = NULL;
330 unlock:
331         mutex_unlock(&gm12u320->fb_update.lock);
332 }
333
334 static void gm12u320_fb_update_work(struct work_struct *work)
335 {
336         struct gm12u320_device *gm12u320 =
337                 container_of(to_delayed_work(work), struct gm12u320_device,
338                              fb_update.work);
339         struct usb_device *udev = gm12u320_to_usb_device(gm12u320);
340         int block, block_size, len;
341         int ret = 0;
342
343         gm12u320_copy_fb_to_blocks(gm12u320);
344
345         for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
346                 if (block == GM12U320_BLOCK_COUNT - 1)
347                         block_size = DATA_LAST_BLOCK_SIZE;
348                 else
349                         block_size = DATA_BLOCK_SIZE;
350
351                 /* Send data command to device */
352                 memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
353                 gm12u320->cmd_buf[8] = block_size & 0xff;
354                 gm12u320->cmd_buf[9] = block_size >> 8;
355                 gm12u320->cmd_buf[20] = 0xfc - block * 4;
356                 gm12u320->cmd_buf[21] =
357                         block | (gm12u320->fb_update.frame << 7);
358
359                 ret = usb_bulk_msg(udev,
360                                    usb_sndbulkpipe(udev, DATA_SND_EPT),
361                                    gm12u320->cmd_buf, CMD_SIZE, &len,
362                                    CMD_TIMEOUT);
363                 if (ret || len != CMD_SIZE)
364                         goto err;
365
366                 /* Send data block to device */
367                 ret = usb_bulk_msg(udev,
368                                    usb_sndbulkpipe(udev, DATA_SND_EPT),
369                                    gm12u320->data_buf[block], block_size,
370                                    &len, DATA_TIMEOUT);
371                 if (ret || len != block_size)
372                         goto err;
373
374                 /* Read status */
375                 ret = usb_bulk_msg(udev,
376                                    usb_rcvbulkpipe(udev, DATA_RCV_EPT),
377                                    gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
378                                    CMD_TIMEOUT);
379                 if (ret || len != READ_STATUS_SIZE)
380                         goto err;
381         }
382
383         /* Send draw command to device */
384         memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
385         ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, DATA_SND_EPT),
386                            gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
387         if (ret || len != CMD_SIZE)
388                 goto err;
389
390         /* Read status */
391         ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, DATA_RCV_EPT),
392                            gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
393                            gm12u320->fb_update.draw_status_timeout);
394         if (ret || len != READ_STATUS_SIZE)
395                 goto err;
396
397         gm12u320->fb_update.draw_status_timeout = CMD_TIMEOUT;
398         gm12u320->fb_update.frame = !gm12u320->fb_update.frame;
399
400         /*
401          * We must draw a frame every 2s otherwise the projector
402          * switches back to showing its logo.
403          */
404         queue_delayed_work(system_long_wq, &gm12u320->fb_update.work,
405                            IDLE_TIMEOUT);
406
407         return;
408 err:
409         /* Do not log errors caused by module unload or device unplug */
410         if (ret != -ENODEV && ret != -ECONNRESET && ret != -ESHUTDOWN)
411                 GM12U320_ERR("Frame update error: %d\n", ret);
412 }
413
414 static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb,
415                                    struct drm_rect *dirty)
416 {
417         struct gm12u320_device *gm12u320 = to_gm12u320(fb->dev);
418         struct drm_framebuffer *old_fb = NULL;
419         bool wakeup = false;
420
421         mutex_lock(&gm12u320->fb_update.lock);
422
423         if (gm12u320->fb_update.fb != fb) {
424                 old_fb = gm12u320->fb_update.fb;
425                 drm_framebuffer_get(fb);
426                 gm12u320->fb_update.fb = fb;
427                 gm12u320->fb_update.rect = *dirty;
428                 wakeup = true;
429         } else {
430                 struct drm_rect *rect = &gm12u320->fb_update.rect;
431
432                 rect->x1 = min(rect->x1, dirty->x1);
433                 rect->y1 = min(rect->y1, dirty->y1);
434                 rect->x2 = max(rect->x2, dirty->x2);
435                 rect->y2 = max(rect->y2, dirty->y2);
436         }
437
438         mutex_unlock(&gm12u320->fb_update.lock);
439
440         if (wakeup)
441                 mod_delayed_work(system_long_wq, &gm12u320->fb_update.work, 0);
442
443         if (old_fb)
444                 drm_framebuffer_put(old_fb);
445 }
446
447 static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320)
448 {
449         struct drm_framebuffer *old_fb;
450
451         cancel_delayed_work_sync(&gm12u320->fb_update.work);
452
453         mutex_lock(&gm12u320->fb_update.lock);
454         old_fb = gm12u320->fb_update.fb;
455         gm12u320->fb_update.fb = NULL;
456         mutex_unlock(&gm12u320->fb_update.lock);
457
458         drm_framebuffer_put(old_fb);
459 }
460
461 static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320)
462 {
463         return gm12u320_misc_request(gm12u320, MISC_REQ_GET_SET_ECO_A,
464                                      MISC_REQ_GET_SET_ECO_B, 0x01 /* set */,
465                                      eco_mode ? 0x01 : 0x00, 0x00, 0x01);
466 }
467
468 /* ------------------------------------------------------------------ */
469 /* gm12u320 connector                                                 */
470
471 /*
472  * We use fake EDID info so that userspace know that it is dealing with
473  * an Acer projector, rather then listing this as an "unknown" monitor.
474  * Note this assumes this driver is only ever used with the Acer C120, if we
475  * add support for other devices the vendor and model should be parameterized.
476  */
477 static struct edid gm12u320_edid = {
478         .header         = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 },
479         .mfg_id         = { 0x04, 0x72 },       /* "ACR" */
480         .prod_code      = { 0x20, 0xc1 },       /* C120h */
481         .serial         = 0xaa55aa55,
482         .mfg_week       = 1,
483         .mfg_year       = 16,
484         .version        = 1,                    /* EDID 1.3 */
485         .revision       = 3,                    /* EDID 1.3 */
486         .input          = 0x08,                 /* Analog input */
487         .features       = 0x0a,                 /* Pref timing in DTD 1 */
488         .standard_timings = { { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
489                               { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 } },
490         .detailed_timings = { {
491                 .pixel_clock = 3383,
492                 /* hactive = 848, hblank = 256 */
493                 .data.pixel_data.hactive_lo = 0x50,
494                 .data.pixel_data.hblank_lo = 0x00,
495                 .data.pixel_data.hactive_hblank_hi = 0x31,
496                 /* vactive = 480, vblank = 28 */
497                 .data.pixel_data.vactive_lo = 0xe0,
498                 .data.pixel_data.vblank_lo = 0x1c,
499                 .data.pixel_data.vactive_vblank_hi = 0x10,
500                 /* hsync offset 40 pw 128, vsync offset 1 pw 4 */
501                 .data.pixel_data.hsync_offset_lo = 0x28,
502                 .data.pixel_data.hsync_pulse_width_lo = 0x80,
503                 .data.pixel_data.vsync_offset_pulse_width_lo = 0x14,
504                 .data.pixel_data.hsync_vsync_offset_pulse_width_hi = 0x00,
505                 /* Digital separate syncs, hsync+, vsync+ */
506                 .data.pixel_data.misc = 0x1e,
507         }, {
508                 .pixel_clock = 0,
509                 .data.other_data.type = 0xfd, /* Monitor ranges */
510                 .data.other_data.data.range.min_vfreq = 59,
511                 .data.other_data.data.range.max_vfreq = 61,
512                 .data.other_data.data.range.min_hfreq_khz = 29,
513                 .data.other_data.data.range.max_hfreq_khz = 32,
514                 .data.other_data.data.range.pixel_clock_mhz = 4, /* 40 MHz */
515                 .data.other_data.data.range.flags = 0,
516                 .data.other_data.data.range.formula.cvt = {
517                         0xa0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
518         }, {
519                 .pixel_clock = 0,
520                 .data.other_data.type = 0xfc, /* Model string */
521                 .data.other_data.data.str.str = {
522                         'P', 'r', 'o', 'j', 'e', 'c', 't', 'o', 'r', '\n',
523                         ' ', ' ',  ' ' },
524         }, {
525                 .pixel_clock = 0,
526                 .data.other_data.type = 0xfe, /* Unspecified text / padding */
527                 .data.other_data.data.str.str = {
528                         '\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
529                         ' ', ' ',  ' ' },
530         } },
531         .checksum = 0x13,
532 };
533
534 static int gm12u320_conn_get_modes(struct drm_connector *connector)
535 {
536         drm_connector_update_edid_property(connector, &gm12u320_edid);
537         return drm_add_edid_modes(connector, &gm12u320_edid);
538 }
539
540 static const struct drm_connector_helper_funcs gm12u320_conn_helper_funcs = {
541         .get_modes = gm12u320_conn_get_modes,
542 };
543
544 static const struct drm_connector_funcs gm12u320_conn_funcs = {
545         .fill_modes = drm_helper_probe_single_connector_modes,
546         .destroy = drm_connector_cleanup,
547         .reset = drm_atomic_helper_connector_reset,
548         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
549         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
550 };
551
552 static int gm12u320_conn_init(struct gm12u320_device *gm12u320)
553 {
554         drm_connector_helper_add(&gm12u320->conn, &gm12u320_conn_helper_funcs);
555         return drm_connector_init(&gm12u320->dev, &gm12u320->conn,
556                                   &gm12u320_conn_funcs, DRM_MODE_CONNECTOR_VGA);
557 }
558
559 /* ------------------------------------------------------------------ */
560 /* gm12u320 (simple) display pipe                                     */
561
562 static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
563                                  struct drm_crtc_state *crtc_state,
564                                  struct drm_plane_state *plane_state)
565 {
566         struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT };
567         struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
568
569         gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT;
570         gm12u320_fb_mark_dirty(plane_state->fb, &rect);
571 }
572
573 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
574 {
575         struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
576
577         gm12u320_stop_fb_update(gm12u320);
578 }
579
580 static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
581                                  struct drm_plane_state *old_state)
582 {
583         struct drm_plane_state *state = pipe->plane.state;
584         struct drm_rect rect;
585
586         if (drm_atomic_helper_damage_merged(old_state, state, &rect))
587                 gm12u320_fb_mark_dirty(pipe->plane.state->fb, &rect);
588 }
589
590 static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = {
591         .enable     = gm12u320_pipe_enable,
592         .disable    = gm12u320_pipe_disable,
593         .update     = gm12u320_pipe_update,
594 };
595
596 static const uint32_t gm12u320_pipe_formats[] = {
597         DRM_FORMAT_XRGB8888,
598 };
599
600 static const uint64_t gm12u320_pipe_modifiers[] = {
601         DRM_FORMAT_MOD_LINEAR,
602         DRM_FORMAT_MOD_INVALID
603 };
604
605 /*
606  * FIXME: Dma-buf sharing requires DMA support by the importing device.
607  *        This function is a workaround to make USB devices work as well.
608  *        See todo.rst for how to fix the issue in the dma-buf framework.
609  */
610 static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev,
611                                                         struct dma_buf *dma_buf)
612 {
613         struct gm12u320_device *gm12u320 = to_gm12u320(dev);
614
615         if (!gm12u320->dmadev)
616                 return ERR_PTR(-ENODEV);
617
618         return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev);
619 }
620
621 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
622
623 static const struct drm_driver gm12u320_drm_driver = {
624         .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
625
626         .name            = DRIVER_NAME,
627         .desc            = DRIVER_DESC,
628         .date            = DRIVER_DATE,
629         .major           = DRIVER_MAJOR,
630         .minor           = DRIVER_MINOR,
631
632         .fops            = &gm12u320_fops,
633         DRM_GEM_SHMEM_DRIVER_OPS,
634         .gem_prime_import = gm12u320_gem_prime_import,
635 };
636
637 static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = {
638         .fb_create = drm_gem_fb_create_with_dirty,
639         .atomic_check = drm_atomic_helper_check,
640         .atomic_commit = drm_atomic_helper_commit,
641 };
642
643 static int gm12u320_usb_probe(struct usb_interface *interface,
644                               const struct usb_device_id *id)
645 {
646         struct gm12u320_device *gm12u320;
647         struct drm_device *dev;
648         int ret;
649
650         /*
651          * The gm12u320 presents itself to the system as 2 usb mass-storage
652          * interfaces, we only care about / need the first one.
653          */
654         if (interface->cur_altsetting->desc.bInterfaceNumber != 0)
655                 return -ENODEV;
656
657         gm12u320 = devm_drm_dev_alloc(&interface->dev, &gm12u320_drm_driver,
658                                       struct gm12u320_device, dev);
659         if (IS_ERR(gm12u320))
660                 return PTR_ERR(gm12u320);
661         dev = &gm12u320->dev;
662
663         gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev));
664         if (!gm12u320->dmadev)
665                 drm_warn(dev, "buffer sharing not supported"); /* not an error */
666
667         INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
668         mutex_init(&gm12u320->fb_update.lock);
669
670         ret = drmm_mode_config_init(dev);
671         if (ret)
672                 goto err_put_device;
673
674         dev->mode_config.min_width = GM12U320_USER_WIDTH;
675         dev->mode_config.max_width = GM12U320_USER_WIDTH;
676         dev->mode_config.min_height = GM12U320_HEIGHT;
677         dev->mode_config.max_height = GM12U320_HEIGHT;
678         dev->mode_config.funcs = &gm12u320_mode_config_funcs;
679
680         ret = gm12u320_usb_alloc(gm12u320);
681         if (ret)
682                 goto err_put_device;
683
684         ret = gm12u320_set_ecomode(gm12u320);
685         if (ret)
686                 goto err_put_device;
687
688         ret = gm12u320_conn_init(gm12u320);
689         if (ret)
690                 goto err_put_device;
691
692         ret = drm_simple_display_pipe_init(&gm12u320->dev,
693                                            &gm12u320->pipe,
694                                            &gm12u320_pipe_funcs,
695                                            gm12u320_pipe_formats,
696                                            ARRAY_SIZE(gm12u320_pipe_formats),
697                                            gm12u320_pipe_modifiers,
698                                            &gm12u320->conn);
699         if (ret)
700                 goto err_put_device;
701
702         drm_mode_config_reset(dev);
703
704         usb_set_intfdata(interface, dev);
705         ret = drm_dev_register(dev, 0);
706         if (ret)
707                 goto err_put_device;
708
709         drm_fbdev_generic_setup(dev, 0);
710
711         return 0;
712
713 err_put_device:
714         put_device(gm12u320->dmadev);
715         return ret;
716 }
717
718 static void gm12u320_usb_disconnect(struct usb_interface *interface)
719 {
720         struct drm_device *dev = usb_get_intfdata(interface);
721         struct gm12u320_device *gm12u320 = to_gm12u320(dev);
722
723         put_device(gm12u320->dmadev);
724         gm12u320->dmadev = NULL;
725         drm_dev_unplug(dev);
726         drm_atomic_helper_shutdown(dev);
727 }
728
729 static __maybe_unused int gm12u320_suspend(struct usb_interface *interface,
730                                            pm_message_t message)
731 {
732         struct drm_device *dev = usb_get_intfdata(interface);
733
734         return drm_mode_config_helper_suspend(dev);
735 }
736
737 static __maybe_unused int gm12u320_resume(struct usb_interface *interface)
738 {
739         struct drm_device *dev = usb_get_intfdata(interface);
740         struct gm12u320_device *gm12u320 = to_gm12u320(dev);
741
742         gm12u320_set_ecomode(gm12u320);
743
744         return drm_mode_config_helper_resume(dev);
745 }
746
747 static const struct usb_device_id id_table[] = {
748         { USB_DEVICE(0x1de1, 0xc102) },
749         {},
750 };
751 MODULE_DEVICE_TABLE(usb, id_table);
752
753 static struct usb_driver gm12u320_usb_driver = {
754         .name = "gm12u320",
755         .probe = gm12u320_usb_probe,
756         .disconnect = gm12u320_usb_disconnect,
757         .id_table = id_table,
758 #ifdef CONFIG_PM
759         .suspend = gm12u320_suspend,
760         .resume = gm12u320_resume,
761         .reset_resume = gm12u320_resume,
762 #endif
763 };
764
765 module_usb_driver(gm12u320_usb_driver);
766 MODULE_AUTHOR("Hans de Goede <[email protected]>");
767 MODULE_LICENSE("GPL");
This page took 0.081326 seconds and 4 git commands to generate.