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