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