xref: /openbmc/linux/drivers/gpu/drm/tiny/gm12u320.c (revision 2a598d0b)
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_generic.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			msecs_to_jiffies(200)
74 #define DATA_TIMEOUT			msecs_to_jiffies(1000)
75 #define IDLE_TIMEOUT			msecs_to_jiffies(2000)
76 #define FIRST_FRAME_TIMEOUT		msecs_to_jiffies(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 			   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 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 	drm_connector_update_edid_property(connector, &gm12u320_edid);
527 	return drm_add_edid_modes(connector, &gm12u320_edid);
528 }
529 
530 static const struct drm_connector_helper_funcs gm12u320_conn_helper_funcs = {
531 	.get_modes = gm12u320_conn_get_modes,
532 };
533 
534 static const struct drm_connector_funcs gm12u320_conn_funcs = {
535 	.fill_modes = drm_helper_probe_single_connector_modes,
536 	.destroy = drm_connector_cleanup,
537 	.reset = drm_atomic_helper_connector_reset,
538 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
539 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
540 };
541 
542 static int gm12u320_conn_init(struct gm12u320_device *gm12u320)
543 {
544 	drm_connector_helper_add(&gm12u320->conn, &gm12u320_conn_helper_funcs);
545 	return drm_connector_init(&gm12u320->dev, &gm12u320->conn,
546 				  &gm12u320_conn_funcs, DRM_MODE_CONNECTOR_VGA);
547 }
548 
549 /* ------------------------------------------------------------------ */
550 /* gm12u320 (simple) display pipe				      */
551 
552 static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
553 				 struct drm_crtc_state *crtc_state,
554 				 struct drm_plane_state *plane_state)
555 {
556 	struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT };
557 	struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
558 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
559 
560 	gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT;
561 	gm12u320_fb_mark_dirty(plane_state->fb, &shadow_plane_state->data[0], &rect);
562 }
563 
564 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
565 {
566 	struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
567 
568 	gm12u320_stop_fb_update(gm12u320);
569 }
570 
571 static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
572 				 struct drm_plane_state *old_state)
573 {
574 	struct drm_plane_state *state = pipe->plane.state;
575 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
576 	struct drm_rect rect;
577 
578 	if (drm_atomic_helper_damage_merged(old_state, state, &rect))
579 		gm12u320_fb_mark_dirty(state->fb, &shadow_plane_state->data[0], &rect);
580 }
581 
582 static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = {
583 	.enable	    = gm12u320_pipe_enable,
584 	.disable    = gm12u320_pipe_disable,
585 	.update	    = gm12u320_pipe_update,
586 	DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
587 };
588 
589 static const uint32_t gm12u320_pipe_formats[] = {
590 	DRM_FORMAT_XRGB8888,
591 };
592 
593 static const uint64_t gm12u320_pipe_modifiers[] = {
594 	DRM_FORMAT_MOD_LINEAR,
595 	DRM_FORMAT_MOD_INVALID
596 };
597 
598 /*
599  * FIXME: Dma-buf sharing requires DMA support by the importing device.
600  *        This function is a workaround to make USB devices work as well.
601  *        See todo.rst for how to fix the issue in the dma-buf framework.
602  */
603 static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev,
604 							struct dma_buf *dma_buf)
605 {
606 	struct gm12u320_device *gm12u320 = to_gm12u320(dev);
607 
608 	if (!gm12u320->dmadev)
609 		return ERR_PTR(-ENODEV);
610 
611 	return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev);
612 }
613 
614 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
615 
616 static const struct drm_driver gm12u320_drm_driver = {
617 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
618 
619 	.name		 = DRIVER_NAME,
620 	.desc		 = DRIVER_DESC,
621 	.date		 = DRIVER_DATE,
622 	.major		 = DRIVER_MAJOR,
623 	.minor		 = DRIVER_MINOR,
624 
625 	.fops		 = &gm12u320_fops,
626 	DRM_GEM_SHMEM_DRIVER_OPS,
627 	.gem_prime_import = gm12u320_gem_prime_import,
628 };
629 
630 static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = {
631 	.fb_create = drm_gem_fb_create_with_dirty,
632 	.atomic_check = drm_atomic_helper_check,
633 	.atomic_commit = drm_atomic_helper_commit,
634 };
635 
636 static int gm12u320_usb_probe(struct usb_interface *interface,
637 			      const struct usb_device_id *id)
638 {
639 	struct gm12u320_device *gm12u320;
640 	struct drm_device *dev;
641 	int ret;
642 
643 	/*
644 	 * The gm12u320 presents itself to the system as 2 usb mass-storage
645 	 * interfaces, we only care about / need the first one.
646 	 */
647 	if (interface->cur_altsetting->desc.bInterfaceNumber != 0)
648 		return -ENODEV;
649 
650 	gm12u320 = devm_drm_dev_alloc(&interface->dev, &gm12u320_drm_driver,
651 				      struct gm12u320_device, dev);
652 	if (IS_ERR(gm12u320))
653 		return PTR_ERR(gm12u320);
654 	dev = &gm12u320->dev;
655 
656 	gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev));
657 	if (!gm12u320->dmadev)
658 		drm_warn(dev, "buffer sharing not supported"); /* not an error */
659 
660 	INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
661 	mutex_init(&gm12u320->fb_update.lock);
662 
663 	ret = drmm_mode_config_init(dev);
664 	if (ret)
665 		goto err_put_device;
666 
667 	dev->mode_config.min_width = GM12U320_USER_WIDTH;
668 	dev->mode_config.max_width = GM12U320_USER_WIDTH;
669 	dev->mode_config.min_height = GM12U320_HEIGHT;
670 	dev->mode_config.max_height = GM12U320_HEIGHT;
671 	dev->mode_config.funcs = &gm12u320_mode_config_funcs;
672 
673 	ret = gm12u320_usb_alloc(gm12u320);
674 	if (ret)
675 		goto err_put_device;
676 
677 	ret = gm12u320_set_ecomode(gm12u320);
678 	if (ret)
679 		goto err_put_device;
680 
681 	ret = gm12u320_conn_init(gm12u320);
682 	if (ret)
683 		goto err_put_device;
684 
685 	ret = drm_simple_display_pipe_init(&gm12u320->dev,
686 					   &gm12u320->pipe,
687 					   &gm12u320_pipe_funcs,
688 					   gm12u320_pipe_formats,
689 					   ARRAY_SIZE(gm12u320_pipe_formats),
690 					   gm12u320_pipe_modifiers,
691 					   &gm12u320->conn);
692 	if (ret)
693 		goto err_put_device;
694 
695 	drm_mode_config_reset(dev);
696 
697 	usb_set_intfdata(interface, dev);
698 	ret = drm_dev_register(dev, 0);
699 	if (ret)
700 		goto err_put_device;
701 
702 	drm_fbdev_generic_setup(dev, 0);
703 
704 	return 0;
705 
706 err_put_device:
707 	put_device(gm12u320->dmadev);
708 	return ret;
709 }
710 
711 static void gm12u320_usb_disconnect(struct usb_interface *interface)
712 {
713 	struct drm_device *dev = usb_get_intfdata(interface);
714 	struct gm12u320_device *gm12u320 = to_gm12u320(dev);
715 
716 	put_device(gm12u320->dmadev);
717 	gm12u320->dmadev = NULL;
718 	drm_dev_unplug(dev);
719 	drm_atomic_helper_shutdown(dev);
720 }
721 
722 static int gm12u320_suspend(struct usb_interface *interface,
723 			    pm_message_t message)
724 {
725 	struct drm_device *dev = usb_get_intfdata(interface);
726 
727 	return drm_mode_config_helper_suspend(dev);
728 }
729 
730 static int gm12u320_resume(struct usb_interface *interface)
731 {
732 	struct drm_device *dev = usb_get_intfdata(interface);
733 	struct gm12u320_device *gm12u320 = to_gm12u320(dev);
734 
735 	gm12u320_set_ecomode(gm12u320);
736 
737 	return drm_mode_config_helper_resume(dev);
738 }
739 
740 static const struct usb_device_id id_table[] = {
741 	{ USB_DEVICE(0x1de1, 0xc102) },
742 	{},
743 };
744 MODULE_DEVICE_TABLE(usb, id_table);
745 
746 static struct usb_driver gm12u320_usb_driver = {
747 	.name = "gm12u320",
748 	.probe = gm12u320_usb_probe,
749 	.disconnect = gm12u320_usb_disconnect,
750 	.id_table = id_table,
751 	.suspend = pm_ptr(gm12u320_suspend),
752 	.resume = pm_ptr(gm12u320_resume),
753 	.reset_resume = pm_ptr(gm12u320_resume),
754 };
755 
756 module_usb_driver(gm12u320_usb_driver);
757 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
758 MODULE_LICENSE("GPL");
759