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