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