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