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