gm12u320.c 22 KB

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