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