xref: /linux/drivers/gpu/drm/tiny/gm12u320.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
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_connector.h>
13 #include <drm/drm_damage_helper.h>
14 #include <drm/drm_drv.h>
15 #include <drm/drm_edid.h>
16 #include <drm/drm_fbdev_shmem.h>
17 #include <drm/drm_file.h>
18 #include <drm/drm_format_helper.h>
19 #include <drm/drm_fourcc.h>
20 #include <drm/drm_framebuffer.h>
21 #include <drm/drm_gem_atomic_helper.h>
22 #include <drm/drm_gem_framebuffer_helper.h>
23 #include <drm/drm_gem_shmem_helper.h>
24 #include <drm/drm_ioctl.h>
25 #include <drm/drm_managed.h>
26 #include <drm/drm_modeset_helper_vtables.h>
27 #include <drm/drm_probe_helper.h>
28 #include <drm/drm_simple_kms_helper.h>
29 
30 static bool eco_mode;
31 module_param(eco_mode, bool, 0644);
32 MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
33 
34 #define DRIVER_NAME		"gm12u320"
35 #define DRIVER_DESC		"Grain Media GM12U320 USB projector display"
36 #define DRIVER_DATE		"2019"
37 #define DRIVER_MAJOR		1
38 #define DRIVER_MINOR		0
39 
40 /*
41  * The DLP has an actual width of 854 pixels, but that is not a multiple
42  * of 8, breaking things left and right, so we export a width of 848.
43  */
44 #define GM12U320_USER_WIDTH		848
45 #define GM12U320_REAL_WIDTH		854
46 #define GM12U320_HEIGHT			480
47 
48 #define GM12U320_BLOCK_COUNT		20
49 
50 #define GM12U320_ERR(fmt, ...) \
51 	DRM_DEV_ERROR(gm12u320->dev.dev, fmt, ##__VA_ARGS__)
52 
53 #define MISC_RCV_EPT			1
54 #define DATA_RCV_EPT			2
55 #define DATA_SND_EPT			3
56 #define MISC_SND_EPT			4
57 
58 #define DATA_BLOCK_HEADER_SIZE		84
59 #define DATA_BLOCK_CONTENT_SIZE		64512
60 #define DATA_BLOCK_FOOTER_SIZE		20
61 #define DATA_BLOCK_SIZE			(DATA_BLOCK_HEADER_SIZE + \
62 					 DATA_BLOCK_CONTENT_SIZE + \
63 					 DATA_BLOCK_FOOTER_SIZE)
64 #define DATA_LAST_BLOCK_CONTENT_SIZE	4032
65 #define DATA_LAST_BLOCK_SIZE		(DATA_BLOCK_HEADER_SIZE + \
66 					 DATA_LAST_BLOCK_CONTENT_SIZE + \
67 					 DATA_BLOCK_FOOTER_SIZE)
68 
69 #define CMD_SIZE			31
70 #define READ_STATUS_SIZE		13
71 #define MISC_VALUE_SIZE			4
72 
73 #define CMD_TIMEOUT			200
74 #define DATA_TIMEOUT			1000
75 #define IDLE_TIMEOUT			2000
76 #define FIRST_FRAME_TIMEOUT		2000
77 
78 #define MISC_REQ_GET_SET_ECO_A		0xff
79 #define MISC_REQ_GET_SET_ECO_B		0x35
80 /* Windows driver does once every second, with arg d = 1, other args 0 */
81 #define MISC_REQ_UNKNOWN1_A		0xff
82 #define MISC_REQ_UNKNOWN1_B		0x38
83 /* Windows driver does this on init, with arg a, b = 0, c = 0xa0, d = 4 */
84 #define MISC_REQ_UNKNOWN2_A		0xa5
85 #define MISC_REQ_UNKNOWN2_B		0x00
86 
87 struct gm12u320_device {
88 	struct drm_device	         dev;
89 	struct device                   *dmadev;
90 	struct drm_simple_display_pipe   pipe;
91 	struct drm_connector	         conn;
92 	unsigned char                   *cmd_buf;
93 	unsigned char                   *data_buf[GM12U320_BLOCK_COUNT];
94 	struct {
95 		struct delayed_work       work;
96 		struct mutex             lock;
97 		struct drm_framebuffer  *fb;
98 		struct drm_rect          rect;
99 		int frame;
100 		int draw_status_timeout;
101 		struct iosys_map src_map;
102 	} fb_update;
103 };
104 
105 #define to_gm12u320(__dev) container_of(__dev, struct gm12u320_device, dev)
106 
107 static const char cmd_data[CMD_SIZE] = {
108 	0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
109 	0x68, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff,
110 	0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80, 0x00,
111 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
112 };
113 
114 static const char cmd_draw[CMD_SIZE] = {
115 	0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
116 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xfe,
117 	0x00, 0x00, 0x00, 0xc0, 0xd1, 0x05, 0x00, 0x40,
118 	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
119 };
120 
121 static const char cmd_misc[CMD_SIZE] = {
122 	0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
123 	0x04, 0x00, 0x00, 0x00, 0x80, 0x01, 0x10, 0xfd,
124 	0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
125 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
126 };
127 
128 static const char data_block_header[DATA_BLOCK_HEADER_SIZE] = {
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 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 	0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 	0x00, 0x04, 0x15, 0x00, 0x00, 0xfc, 0x00, 0x00,
139 	0x01, 0x00, 0x00, 0xdb
140 };
141 
142 static const char data_last_block_header[DATA_BLOCK_HEADER_SIZE] = {
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 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 	0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 	0x2a, 0x00, 0x20, 0x00, 0xc0, 0x0f, 0x00, 0x00,
153 	0x01, 0x00, 0x00, 0xd7
154 };
155 
156 static const char data_block_footer[DATA_BLOCK_FOOTER_SIZE] = {
157 	0xfb, 0x14, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
158 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 	0x80, 0x00, 0x00, 0x4f
160 };
161 
162 static inline struct usb_device *gm12u320_to_usb_device(struct gm12u320_device *gm12u320)
163 {
164 	return interface_to_usbdev(to_usb_interface(gm12u320->dev.dev));
165 }
166 
167 static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
168 {
169 	int i, block_size;
170 	const char *hdr;
171 
172 	gm12u320->cmd_buf = drmm_kmalloc(&gm12u320->dev, CMD_SIZE, GFP_KERNEL);
173 	if (!gm12u320->cmd_buf)
174 		return -ENOMEM;
175 
176 	for (i = 0; i < GM12U320_BLOCK_COUNT; i++) {
177 		if (i == GM12U320_BLOCK_COUNT - 1) {
178 			block_size = DATA_LAST_BLOCK_SIZE;
179 			hdr = data_last_block_header;
180 		} else {
181 			block_size = DATA_BLOCK_SIZE;
182 			hdr = data_block_header;
183 		}
184 
185 		gm12u320->data_buf[i] = drmm_kzalloc(&gm12u320->dev,
186 						     block_size, GFP_KERNEL);
187 		if (!gm12u320->data_buf[i])
188 			return -ENOMEM;
189 
190 		memcpy(gm12u320->data_buf[i], hdr, DATA_BLOCK_HEADER_SIZE);
191 		memcpy(gm12u320->data_buf[i] +
192 				(block_size - DATA_BLOCK_FOOTER_SIZE),
193 		       data_block_footer, DATA_BLOCK_FOOTER_SIZE);
194 	}
195 
196 	return 0;
197 }
198 
199 static int gm12u320_misc_request(struct gm12u320_device *gm12u320,
200 				 u8 req_a, u8 req_b,
201 				 u8 arg_a, u8 arg_b, u8 arg_c, u8 arg_d)
202 {
203 	struct usb_device *udev = gm12u320_to_usb_device(gm12u320);
204 	int ret, len;
205 
206 	memcpy(gm12u320->cmd_buf, &cmd_misc, CMD_SIZE);
207 	gm12u320->cmd_buf[20] = req_a;
208 	gm12u320->cmd_buf[21] = req_b;
209 	gm12u320->cmd_buf[22] = arg_a;
210 	gm12u320->cmd_buf[23] = arg_b;
211 	gm12u320->cmd_buf[24] = arg_c;
212 	gm12u320->cmd_buf[25] = arg_d;
213 
214 	/* Send request */
215 	ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, MISC_SND_EPT),
216 			   gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
217 	if (ret || len != CMD_SIZE) {
218 		GM12U320_ERR("Misc. req. error %d\n", ret);
219 		return -EIO;
220 	}
221 
222 	/* Read value */
223 	ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, MISC_RCV_EPT),
224 			   gm12u320->cmd_buf, MISC_VALUE_SIZE, &len,
225 			   DATA_TIMEOUT);
226 	if (ret || len != MISC_VALUE_SIZE) {
227 		GM12U320_ERR("Misc. value error %d\n", ret);
228 		return -EIO;
229 	}
230 	/* cmd_buf[0] now contains the read value, which we don't use */
231 
232 	/* Read status */
233 	ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, MISC_RCV_EPT),
234 			   gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
235 			   CMD_TIMEOUT);
236 	if (ret || len != READ_STATUS_SIZE) {
237 		GM12U320_ERR("Misc. status error %d\n", ret);
238 		return -EIO;
239 	}
240 
241 	return 0;
242 }
243 
244 static void gm12u320_32bpp_to_24bpp_packed(u8 *dst, u8 *src, int len)
245 {
246 	while (len--) {
247 		*dst++ = *src++;
248 		*dst++ = *src++;
249 		*dst++ = *src++;
250 		src++;
251 	}
252 }
253 
254 static void gm12u320_copy_fb_to_blocks(struct gm12u320_device *gm12u320)
255 {
256 	int block, dst_offset, len, remain, ret, x1, x2, y1, y2;
257 	struct drm_framebuffer *fb;
258 	void *vaddr;
259 	u8 *src;
260 
261 	mutex_lock(&gm12u320->fb_update.lock);
262 
263 	if (!gm12u320->fb_update.fb)
264 		goto unlock;
265 
266 	fb = gm12u320->fb_update.fb;
267 	x1 = gm12u320->fb_update.rect.x1;
268 	x2 = gm12u320->fb_update.rect.x2;
269 	y1 = gm12u320->fb_update.rect.y1;
270 	y2 = gm12u320->fb_update.rect.y2;
271 	vaddr = gm12u320->fb_update.src_map.vaddr; /* TODO: Use mapping abstraction properly */
272 
273 	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
274 	if (ret) {
275 		GM12U320_ERR("drm_gem_fb_begin_cpu_access err: %d\n", ret);
276 		goto put_fb;
277 	}
278 
279 	src = vaddr + y1 * fb->pitches[0] + x1 * 4;
280 
281 	x1 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
282 	x2 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
283 
284 	for (; y1 < y2; y1++) {
285 		remain = 0;
286 		len = (x2 - x1) * 3;
287 		dst_offset = (y1 * GM12U320_REAL_WIDTH + x1) * 3;
288 		block = dst_offset / DATA_BLOCK_CONTENT_SIZE;
289 		dst_offset %= DATA_BLOCK_CONTENT_SIZE;
290 
291 		if ((dst_offset + len) > DATA_BLOCK_CONTENT_SIZE) {
292 			remain = dst_offset + len - DATA_BLOCK_CONTENT_SIZE;
293 			len = DATA_BLOCK_CONTENT_SIZE - dst_offset;
294 		}
295 
296 		dst_offset += DATA_BLOCK_HEADER_SIZE;
297 		len /= 3;
298 
299 		gm12u320_32bpp_to_24bpp_packed(
300 			gm12u320->data_buf[block] + dst_offset,
301 			src, len);
302 
303 		if (remain) {
304 			block++;
305 			dst_offset = DATA_BLOCK_HEADER_SIZE;
306 			gm12u320_32bpp_to_24bpp_packed(
307 				gm12u320->data_buf[block] + dst_offset,
308 				src + len * 4, remain / 3);
309 		}
310 		src += fb->pitches[0];
311 	}
312 
313 	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
314 put_fb:
315 	drm_framebuffer_put(fb);
316 	gm12u320->fb_update.fb = NULL;
317 unlock:
318 	mutex_unlock(&gm12u320->fb_update.lock);
319 }
320 
321 static void gm12u320_fb_update_work(struct work_struct *work)
322 {
323 	struct gm12u320_device *gm12u320 =
324 		container_of(to_delayed_work(work), struct gm12u320_device,
325 			     fb_update.work);
326 	struct usb_device *udev = gm12u320_to_usb_device(gm12u320);
327 	int block, block_size, len;
328 	int ret = 0;
329 
330 	gm12u320_copy_fb_to_blocks(gm12u320);
331 
332 	for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
333 		if (block == GM12U320_BLOCK_COUNT - 1)
334 			block_size = DATA_LAST_BLOCK_SIZE;
335 		else
336 			block_size = DATA_BLOCK_SIZE;
337 
338 		/* Send data command to device */
339 		memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
340 		gm12u320->cmd_buf[8] = block_size & 0xff;
341 		gm12u320->cmd_buf[9] = block_size >> 8;
342 		gm12u320->cmd_buf[20] = 0xfc - block * 4;
343 		gm12u320->cmd_buf[21] =
344 			block | (gm12u320->fb_update.frame << 7);
345 
346 		ret = usb_bulk_msg(udev,
347 				   usb_sndbulkpipe(udev, DATA_SND_EPT),
348 				   gm12u320->cmd_buf, CMD_SIZE, &len,
349 				   CMD_TIMEOUT);
350 		if (ret || len != CMD_SIZE)
351 			goto err;
352 
353 		/* Send data block to device */
354 		ret = usb_bulk_msg(udev,
355 				   usb_sndbulkpipe(udev, DATA_SND_EPT),
356 				   gm12u320->data_buf[block], block_size,
357 				   &len, DATA_TIMEOUT);
358 		if (ret || len != block_size)
359 			goto err;
360 
361 		/* Read status */
362 		ret = usb_bulk_msg(udev,
363 				   usb_rcvbulkpipe(udev, DATA_RCV_EPT),
364 				   gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
365 				   CMD_TIMEOUT);
366 		if (ret || len != READ_STATUS_SIZE)
367 			goto err;
368 	}
369 
370 	/* Send draw command to device */
371 	memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
372 	ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, DATA_SND_EPT),
373 			   gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
374 	if (ret || len != CMD_SIZE)
375 		goto err;
376 
377 	/* Read status */
378 	ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, DATA_RCV_EPT),
379 			   gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
380 			   gm12u320->fb_update.draw_status_timeout);
381 	if (ret || len != READ_STATUS_SIZE)
382 		goto err;
383 
384 	gm12u320->fb_update.draw_status_timeout = CMD_TIMEOUT;
385 	gm12u320->fb_update.frame = !gm12u320->fb_update.frame;
386 
387 	/*
388 	 * We must draw a frame every 2s otherwise the projector
389 	 * switches back to showing its logo.
390 	 */
391 	queue_delayed_work(system_long_wq, &gm12u320->fb_update.work,
392 			   msecs_to_jiffies(IDLE_TIMEOUT));
393 
394 	return;
395 err:
396 	/* Do not log errors caused by module unload or device unplug */
397 	if (ret != -ENODEV && ret != -ECONNRESET && ret != -ESHUTDOWN)
398 		GM12U320_ERR("Frame update error: %d\n", ret);
399 }
400 
401 static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb,
402 				   const struct iosys_map *map,
403 				   struct drm_rect *dirty)
404 {
405 	struct gm12u320_device *gm12u320 = to_gm12u320(fb->dev);
406 	struct drm_framebuffer *old_fb = NULL;
407 	bool wakeup = false;
408 
409 	mutex_lock(&gm12u320->fb_update.lock);
410 
411 	if (gm12u320->fb_update.fb != fb) {
412 		old_fb = gm12u320->fb_update.fb;
413 		drm_framebuffer_get(fb);
414 		gm12u320->fb_update.fb = fb;
415 		gm12u320->fb_update.rect = *dirty;
416 		gm12u320->fb_update.src_map = *map;
417 		wakeup = true;
418 	} else {
419 		struct drm_rect *rect = &gm12u320->fb_update.rect;
420 
421 		rect->x1 = min(rect->x1, dirty->x1);
422 		rect->y1 = min(rect->y1, dirty->y1);
423 		rect->x2 = max(rect->x2, dirty->x2);
424 		rect->y2 = max(rect->y2, dirty->y2);
425 	}
426 
427 	mutex_unlock(&gm12u320->fb_update.lock);
428 
429 	if (wakeup)
430 		mod_delayed_work(system_long_wq, &gm12u320->fb_update.work, 0);
431 
432 	if (old_fb)
433 		drm_framebuffer_put(old_fb);
434 }
435 
436 static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320)
437 {
438 	struct drm_framebuffer *old_fb;
439 
440 	cancel_delayed_work_sync(&gm12u320->fb_update.work);
441 
442 	mutex_lock(&gm12u320->fb_update.lock);
443 	old_fb = gm12u320->fb_update.fb;
444 	gm12u320->fb_update.fb = NULL;
445 	iosys_map_clear(&gm12u320->fb_update.src_map);
446 	mutex_unlock(&gm12u320->fb_update.lock);
447 
448 	drm_framebuffer_put(old_fb);
449 }
450 
451 static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320)
452 {
453 	return gm12u320_misc_request(gm12u320, MISC_REQ_GET_SET_ECO_A,
454 				     MISC_REQ_GET_SET_ECO_B, 0x01 /* set */,
455 				     eco_mode ? 0x01 : 0x00, 0x00, 0x01);
456 }
457 
458 /* ------------------------------------------------------------------ */
459 /* gm12u320 connector						      */
460 
461 /*
462  * We use fake EDID info so that userspace know that it is dealing with
463  * an Acer projector, rather then listing this as an "unknown" monitor.
464  * Note this assumes this driver is only ever used with the Acer C120, if we
465  * add support for other devices the vendor and model should be parameterized.
466  */
467 static const struct edid gm12u320_edid = {
468 	.header		= { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 },
469 	.mfg_id		= { 0x04, 0x72 },	/* "ACR" */
470 	.prod_code	= { 0x20, 0xc1 },	/* C120h */
471 	.serial		= 0xaa55aa55,
472 	.mfg_week	= 1,
473 	.mfg_year	= 16,
474 	.version	= 1,			/* EDID 1.3 */
475 	.revision	= 3,			/* EDID 1.3 */
476 	.input		= 0x08,			/* Analog input */
477 	.features	= 0x0a,			/* Pref timing in DTD 1 */
478 	.standard_timings = { { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
479 			      { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 } },
480 	.detailed_timings = { {
481 		.pixel_clock = 3383,
482 		/* hactive = 848, hblank = 256 */
483 		.data.pixel_data.hactive_lo = 0x50,
484 		.data.pixel_data.hblank_lo = 0x00,
485 		.data.pixel_data.hactive_hblank_hi = 0x31,
486 		/* vactive = 480, vblank = 28 */
487 		.data.pixel_data.vactive_lo = 0xe0,
488 		.data.pixel_data.vblank_lo = 0x1c,
489 		.data.pixel_data.vactive_vblank_hi = 0x10,
490 		/* hsync offset 40 pw 128, vsync offset 1 pw 4 */
491 		.data.pixel_data.hsync_offset_lo = 0x28,
492 		.data.pixel_data.hsync_pulse_width_lo = 0x80,
493 		.data.pixel_data.vsync_offset_pulse_width_lo = 0x14,
494 		.data.pixel_data.hsync_vsync_offset_pulse_width_hi = 0x00,
495 		/* Digital separate syncs, hsync+, vsync+ */
496 		.data.pixel_data.misc = 0x1e,
497 	}, {
498 		.pixel_clock = 0,
499 		.data.other_data.type = 0xfd, /* Monitor ranges */
500 		.data.other_data.data.range.min_vfreq = 59,
501 		.data.other_data.data.range.max_vfreq = 61,
502 		.data.other_data.data.range.min_hfreq_khz = 29,
503 		.data.other_data.data.range.max_hfreq_khz = 32,
504 		.data.other_data.data.range.pixel_clock_mhz = 4, /* 40 MHz */
505 		.data.other_data.data.range.flags = 0,
506 		.data.other_data.data.range.formula.cvt = {
507 			0xa0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
508 	}, {
509 		.pixel_clock = 0,
510 		.data.other_data.type = 0xfc, /* Model string */
511 		.data.other_data.data.str.str = {
512 			'P', 'r', 'o', 'j', 'e', 'c', 't', 'o', 'r', '\n',
513 			' ', ' ',  ' ' },
514 	}, {
515 		.pixel_clock = 0,
516 		.data.other_data.type = 0xfe, /* Unspecified text / padding */
517 		.data.other_data.data.str.str = {
518 			'\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
519 			' ', ' ',  ' ' },
520 	} },
521 	.checksum = 0x13,
522 };
523 
524 static int gm12u320_conn_get_modes(struct drm_connector *connector)
525 {
526 	const struct drm_edid *drm_edid;
527 	int count;
528 
529 	drm_edid = drm_edid_alloc(&gm12u320_edid, sizeof(gm12u320_edid));
530 	drm_edid_connector_update(connector, drm_edid);
531 	count = drm_edid_connector_add_modes(connector);
532 	drm_edid_free(drm_edid);
533 
534 	return count;
535 }
536 
537 static const struct drm_connector_helper_funcs gm12u320_conn_helper_funcs = {
538 	.get_modes = gm12u320_conn_get_modes,
539 };
540 
541 static const struct drm_connector_funcs gm12u320_conn_funcs = {
542 	.fill_modes = drm_helper_probe_single_connector_modes,
543 	.destroy = drm_connector_cleanup,
544 	.reset = drm_atomic_helper_connector_reset,
545 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
546 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
547 };
548 
549 static int gm12u320_conn_init(struct gm12u320_device *gm12u320)
550 {
551 	drm_connector_helper_add(&gm12u320->conn, &gm12u320_conn_helper_funcs);
552 	return drm_connector_init(&gm12u320->dev, &gm12u320->conn,
553 				  &gm12u320_conn_funcs, DRM_MODE_CONNECTOR_VGA);
554 }
555 
556 /* ------------------------------------------------------------------ */
557 /* gm12u320 (simple) display pipe				      */
558 
559 static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
560 				 struct drm_crtc_state *crtc_state,
561 				 struct drm_plane_state *plane_state)
562 {
563 	struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT };
564 	struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
565 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
566 
567 	gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT;
568 	gm12u320_fb_mark_dirty(plane_state->fb, &shadow_plane_state->data[0], &rect);
569 }
570 
571 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
572 {
573 	struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
574 
575 	gm12u320_stop_fb_update(gm12u320);
576 }
577 
578 static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
579 				 struct drm_plane_state *old_state)
580 {
581 	struct drm_plane_state *state = pipe->plane.state;
582 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
583 	struct drm_rect rect;
584 
585 	if (drm_atomic_helper_damage_merged(old_state, state, &rect))
586 		gm12u320_fb_mark_dirty(state->fb, &shadow_plane_state->data[0], &rect);
587 }
588 
589 static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = {
590 	.enable	    = gm12u320_pipe_enable,
591 	.disable    = gm12u320_pipe_disable,
592 	.update	    = gm12u320_pipe_update,
593 	DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
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_shmem_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 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 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 	.suspend = pm_ptr(gm12u320_suspend),
759 	.resume = pm_ptr(gm12u320_resume),
760 	.reset_resume = pm_ptr(gm12u320_resume),
761 };
762 
763 module_usb_driver(gm12u320_usb_driver);
764 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
765 MODULE_DESCRIPTION("GM12U320 driver for USB projectors");
766 MODULE_LICENSE("GPL");
767