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