appletbdrm.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Apple Touch Bar DRM Driver
  4. *
  5. * Copyright (c) 2023 Kerem Karabay <kekrby@gmail.com>
  6. */
  7. #include <linux/align.h>
  8. #include <linux/array_size.h>
  9. #include <linux/bitops.h>
  10. #include <linux/bug.h>
  11. #include <linux/container_of.h>
  12. #include <linux/err.h>
  13. #include <linux/module.h>
  14. #include <linux/overflow.h>
  15. #include <linux/slab.h>
  16. #include <linux/types.h>
  17. #include <linux/unaligned.h>
  18. #include <linux/usb.h>
  19. #include <drm/drm_atomic.h>
  20. #include <drm/drm_atomic_helper.h>
  21. #include <drm/drm_crtc.h>
  22. #include <drm/drm_damage_helper.h>
  23. #include <drm/drm_drv.h>
  24. #include <drm/drm_encoder.h>
  25. #include <drm/drm_format_helper.h>
  26. #include <drm/drm_fourcc.h>
  27. #include <drm/drm_framebuffer.h>
  28. #include <drm/drm_gem_atomic_helper.h>
  29. #include <drm/drm_gem_framebuffer_helper.h>
  30. #include <drm/drm_gem_shmem_helper.h>
  31. #include <drm/drm_plane.h>
  32. #include <drm/drm_print.h>
  33. #include <drm/drm_probe_helper.h>
  34. #define APPLETBDRM_PIXEL_FORMAT cpu_to_le32(0x52474241) /* RGBA, the actual format is BGR888 */
  35. #define APPLETBDRM_BITS_PER_PIXEL 24
  36. #define APPLETBDRM_MSG_CLEAR_DISPLAY cpu_to_le32(0x434c5244) /* CLRD */
  37. #define APPLETBDRM_MSG_GET_INFORMATION cpu_to_le32(0x47494e46) /* GINF */
  38. #define APPLETBDRM_MSG_UPDATE_COMPLETE cpu_to_le32(0x5544434c) /* UDCL */
  39. #define APPLETBDRM_MSG_SIGNAL_READINESS cpu_to_le32(0x52454459) /* REDY */
  40. #define APPLETBDRM_BULK_MSG_TIMEOUT 1000
  41. #define drm_to_adev(_drm) container_of(_drm, struct appletbdrm_device, drm)
  42. #define adev_to_udev(adev) interface_to_usbdev(to_usb_interface((adev)->drm.dev))
  43. struct appletbdrm_msg_request_header {
  44. __le16 unk_00;
  45. __le16 unk_02;
  46. __le32 unk_04;
  47. __le32 unk_08;
  48. __le32 size;
  49. } __packed;
  50. struct appletbdrm_msg_response_header {
  51. u8 unk_00[16];
  52. __le32 msg;
  53. } __packed;
  54. struct appletbdrm_msg_simple_request {
  55. struct appletbdrm_msg_request_header header;
  56. __le32 msg;
  57. u8 unk_14[8];
  58. __le32 size;
  59. } __packed;
  60. struct appletbdrm_msg_information {
  61. struct appletbdrm_msg_response_header header;
  62. u8 unk_14[12];
  63. __le32 width;
  64. __le32 height;
  65. u8 bits_per_pixel;
  66. __le32 bytes_per_row;
  67. __le32 orientation;
  68. __le32 bitmap_info;
  69. __le32 pixel_format;
  70. __le32 width_inches; /* floating point */
  71. __le32 height_inches; /* floating point */
  72. } __packed;
  73. struct appletbdrm_frame {
  74. __le16 begin_x;
  75. __le16 begin_y;
  76. __le16 width;
  77. __le16 height;
  78. __le32 buf_size;
  79. u8 buf[];
  80. } __packed;
  81. struct appletbdrm_fb_request_footer {
  82. u8 unk_00[12];
  83. __le32 unk_0c;
  84. u8 unk_10[12];
  85. __le32 unk_1c;
  86. __le64 timestamp;
  87. u8 unk_28[12];
  88. __le32 unk_34;
  89. u8 unk_38[20];
  90. __le32 unk_4c;
  91. } __packed;
  92. struct appletbdrm_fb_request {
  93. struct appletbdrm_msg_request_header header;
  94. __le16 unk_10;
  95. u8 msg_id;
  96. u8 unk_13[29];
  97. /*
  98. * Contents of `data`:
  99. * - struct appletbdrm_frame frames[];
  100. * - struct appletbdrm_fb_request_footer footer;
  101. * - padding to make the total size a multiple of 16
  102. */
  103. u8 data[];
  104. } __packed;
  105. struct appletbdrm_fb_request_response {
  106. struct appletbdrm_msg_response_header header;
  107. u8 unk_14[12];
  108. __le64 timestamp;
  109. } __packed;
  110. struct appletbdrm_device {
  111. unsigned int in_ep;
  112. unsigned int out_ep;
  113. unsigned int width;
  114. unsigned int height;
  115. struct drm_device drm;
  116. struct drm_display_mode mode;
  117. struct drm_connector connector;
  118. struct drm_plane primary_plane;
  119. struct drm_crtc crtc;
  120. struct drm_encoder encoder;
  121. };
  122. struct appletbdrm_plane_state {
  123. struct drm_shadow_plane_state base;
  124. struct appletbdrm_fb_request *request;
  125. struct appletbdrm_fb_request_response *response;
  126. size_t request_size;
  127. size_t frames_size;
  128. };
  129. static inline struct appletbdrm_plane_state *to_appletbdrm_plane_state(struct drm_plane_state *state)
  130. {
  131. return container_of(state, struct appletbdrm_plane_state, base.base);
  132. }
  133. static int appletbdrm_send_request(struct appletbdrm_device *adev,
  134. struct appletbdrm_msg_request_header *request, size_t size)
  135. {
  136. struct usb_device *udev = adev_to_udev(adev);
  137. struct drm_device *drm = &adev->drm;
  138. int ret, actual_size;
  139. ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, adev->out_ep),
  140. request, size, &actual_size, APPLETBDRM_BULK_MSG_TIMEOUT);
  141. if (ret) {
  142. drm_err(drm, "Failed to send message (%d)\n", ret);
  143. return ret;
  144. }
  145. if (actual_size != size) {
  146. drm_err(drm, "Actual size (%d) doesn't match expected size (%zu)\n",
  147. actual_size, size);
  148. return -EIO;
  149. }
  150. return 0;
  151. }
  152. static int appletbdrm_read_response(struct appletbdrm_device *adev,
  153. struct appletbdrm_msg_response_header *response,
  154. size_t size, __le32 expected_response)
  155. {
  156. struct usb_device *udev = adev_to_udev(adev);
  157. struct drm_device *drm = &adev->drm;
  158. int ret, actual_size;
  159. bool readiness_signal_received = false;
  160. retry:
  161. ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, adev->in_ep),
  162. response, size, &actual_size, APPLETBDRM_BULK_MSG_TIMEOUT);
  163. if (ret) {
  164. drm_err(drm, "Failed to read response (%d)\n", ret);
  165. return ret;
  166. }
  167. /*
  168. * The device responds to the first request sent in a particular
  169. * timeframe after the USB device configuration is set with a readiness
  170. * signal, in which case the response should be read again
  171. */
  172. if (response->msg == APPLETBDRM_MSG_SIGNAL_READINESS) {
  173. if (!readiness_signal_received) {
  174. readiness_signal_received = true;
  175. goto retry;
  176. }
  177. drm_err(drm, "Encountered unexpected readiness signal\n");
  178. return -EINTR;
  179. }
  180. if (actual_size != size) {
  181. drm_err(drm, "Actual size (%d) doesn't match expected size (%zu)\n",
  182. actual_size, size);
  183. return -EBADMSG;
  184. }
  185. if (response->msg != expected_response) {
  186. drm_err(drm, "Unexpected response from device (expected %p4cl found %p4cl)\n",
  187. &expected_response, &response->msg);
  188. return -EIO;
  189. }
  190. return 0;
  191. }
  192. static int appletbdrm_send_msg(struct appletbdrm_device *adev, __le32 msg)
  193. {
  194. struct appletbdrm_msg_simple_request *request;
  195. int ret;
  196. request = kzalloc_obj(*request);
  197. if (!request)
  198. return -ENOMEM;
  199. request->header.unk_00 = cpu_to_le16(2);
  200. request->header.unk_02 = cpu_to_le16(0x1512);
  201. request->header.size = cpu_to_le32(sizeof(*request) - sizeof(request->header));
  202. request->msg = msg;
  203. request->size = request->header.size;
  204. ret = appletbdrm_send_request(adev, &request->header, sizeof(*request));
  205. kfree(request);
  206. return ret;
  207. }
  208. static int appletbdrm_clear_display(struct appletbdrm_device *adev)
  209. {
  210. return appletbdrm_send_msg(adev, APPLETBDRM_MSG_CLEAR_DISPLAY);
  211. }
  212. static int appletbdrm_signal_readiness(struct appletbdrm_device *adev)
  213. {
  214. return appletbdrm_send_msg(adev, APPLETBDRM_MSG_SIGNAL_READINESS);
  215. }
  216. static int appletbdrm_get_information(struct appletbdrm_device *adev)
  217. {
  218. struct appletbdrm_msg_information *info;
  219. struct drm_device *drm = &adev->drm;
  220. u8 bits_per_pixel;
  221. __le32 pixel_format;
  222. int ret;
  223. info = kzalloc_obj(*info);
  224. if (!info)
  225. return -ENOMEM;
  226. ret = appletbdrm_send_msg(adev, APPLETBDRM_MSG_GET_INFORMATION);
  227. if (ret)
  228. return ret;
  229. ret = appletbdrm_read_response(adev, &info->header, sizeof(*info),
  230. APPLETBDRM_MSG_GET_INFORMATION);
  231. if (ret)
  232. goto free_info;
  233. bits_per_pixel = info->bits_per_pixel;
  234. pixel_format = get_unaligned(&info->pixel_format);
  235. adev->width = get_unaligned_le32(&info->width);
  236. adev->height = get_unaligned_le32(&info->height);
  237. if (bits_per_pixel != APPLETBDRM_BITS_PER_PIXEL) {
  238. drm_err(drm, "Encountered unexpected bits per pixel value (%d)\n", bits_per_pixel);
  239. ret = -EINVAL;
  240. goto free_info;
  241. }
  242. if (pixel_format != APPLETBDRM_PIXEL_FORMAT) {
  243. drm_err(drm, "Encountered unknown pixel format (%p4cl)\n", &pixel_format);
  244. ret = -EINVAL;
  245. goto free_info;
  246. }
  247. free_info:
  248. kfree(info);
  249. return ret;
  250. }
  251. static u32 rect_size(struct drm_rect *rect)
  252. {
  253. return drm_rect_width(rect) * drm_rect_height(rect) *
  254. (BITS_TO_BYTES(APPLETBDRM_BITS_PER_PIXEL));
  255. }
  256. static int appletbdrm_connector_helper_get_modes(struct drm_connector *connector)
  257. {
  258. struct appletbdrm_device *adev = drm_to_adev(connector->dev);
  259. return drm_connector_helper_get_modes_fixed(connector, &adev->mode);
  260. }
  261. static const u32 appletbdrm_primary_plane_formats[] = {
  262. DRM_FORMAT_BGR888,
  263. DRM_FORMAT_XRGB8888, /* emulated */
  264. };
  265. static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
  266. struct drm_atomic_state *state)
  267. {
  268. struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
  269. struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
  270. struct drm_crtc *new_crtc = new_plane_state->crtc;
  271. struct drm_crtc_state *new_crtc_state = NULL;
  272. struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(new_plane_state);
  273. struct drm_atomic_helper_damage_iter iter;
  274. struct drm_rect damage;
  275. size_t frames_size = 0;
  276. size_t request_size;
  277. int ret;
  278. if (new_crtc)
  279. new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
  280. ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
  281. DRM_PLANE_NO_SCALING,
  282. DRM_PLANE_NO_SCALING,
  283. false, false);
  284. if (ret)
  285. return ret;
  286. else if (!new_plane_state->visible)
  287. return 0;
  288. drm_atomic_helper_damage_iter_init(&iter, old_plane_state, new_plane_state);
  289. drm_atomic_for_each_plane_damage(&iter, &damage) {
  290. frames_size += struct_size((struct appletbdrm_frame *)0, buf, rect_size(&damage));
  291. }
  292. if (!frames_size)
  293. return 0;
  294. request_size = ALIGN(sizeof(struct appletbdrm_fb_request) +
  295. frames_size +
  296. sizeof(struct appletbdrm_fb_request_footer), 16);
  297. appletbdrm_state->request = kzalloc(request_size, GFP_KERNEL);
  298. if (!appletbdrm_state->request)
  299. return -ENOMEM;
  300. appletbdrm_state->response = kzalloc_obj(*appletbdrm_state->response);
  301. if (!appletbdrm_state->response)
  302. return -ENOMEM;
  303. appletbdrm_state->request_size = request_size;
  304. appletbdrm_state->frames_size = frames_size;
  305. return 0;
  306. }
  307. static int appletbdrm_flush_damage(struct appletbdrm_device *adev,
  308. struct drm_plane_state *old_state,
  309. struct drm_plane_state *state)
  310. {
  311. struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(state);
  312. struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
  313. struct appletbdrm_fb_request_response *response = appletbdrm_state->response;
  314. struct appletbdrm_fb_request_footer *footer;
  315. struct drm_atomic_helper_damage_iter iter;
  316. struct drm_framebuffer *fb = state->fb;
  317. struct appletbdrm_fb_request *request = appletbdrm_state->request;
  318. struct drm_device *drm = &adev->drm;
  319. struct appletbdrm_frame *frame;
  320. u64 timestamp = ktime_get_ns();
  321. struct drm_rect damage;
  322. size_t frames_size = appletbdrm_state->frames_size;
  323. size_t request_size = appletbdrm_state->request_size;
  324. int ret;
  325. if (!frames_size)
  326. return 0;
  327. ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
  328. if (ret) {
  329. drm_err(drm, "Failed to start CPU framebuffer access (%d)\n", ret);
  330. goto end_fb_cpu_access;
  331. }
  332. request->header.unk_00 = cpu_to_le16(2);
  333. request->header.unk_02 = cpu_to_le16(0x12);
  334. request->header.unk_04 = cpu_to_le32(9);
  335. request->header.size = cpu_to_le32(request_size - sizeof(request->header));
  336. request->unk_10 = cpu_to_le16(1);
  337. request->msg_id = timestamp;
  338. frame = (struct appletbdrm_frame *)request->data;
  339. drm_atomic_helper_damage_iter_init(&iter, old_state, state);
  340. drm_atomic_for_each_plane_damage(&iter, &damage) {
  341. struct drm_rect dst_clip = state->dst;
  342. struct iosys_map dst = IOSYS_MAP_INIT_VADDR(frame->buf);
  343. u32 buf_size = rect_size(&damage);
  344. if (!drm_rect_intersect(&dst_clip, &damage))
  345. continue;
  346. /*
  347. * The coordinates need to be translated to the coordinate
  348. * system the device expects, see the comment in
  349. * appletbdrm_setup_mode_config
  350. */
  351. frame->begin_x = cpu_to_le16(damage.y1);
  352. frame->begin_y = cpu_to_le16(adev->height - damage.x2);
  353. frame->width = cpu_to_le16(drm_rect_height(&damage));
  354. frame->height = cpu_to_le16(drm_rect_width(&damage));
  355. frame->buf_size = cpu_to_le32(buf_size);
  356. switch (fb->format->format) {
  357. case DRM_FORMAT_XRGB8888:
  358. drm_fb_xrgb8888_to_bgr888(&dst, NULL, &shadow_plane_state->data[0], fb, &damage, &shadow_plane_state->fmtcnv_state);
  359. break;
  360. default:
  361. drm_fb_memcpy(&dst, NULL, &shadow_plane_state->data[0], fb, &damage);
  362. break;
  363. }
  364. frame = (void *)frame + struct_size(frame, buf, buf_size);
  365. }
  366. footer = (struct appletbdrm_fb_request_footer *)&request->data[frames_size];
  367. footer->unk_0c = cpu_to_le32(0xfffe);
  368. footer->unk_1c = cpu_to_le32(0x80001);
  369. footer->unk_34 = cpu_to_le32(0x80002);
  370. footer->unk_4c = cpu_to_le32(0xffff);
  371. footer->timestamp = cpu_to_le64(timestamp);
  372. ret = appletbdrm_send_request(adev, &request->header, request_size);
  373. if (ret)
  374. goto end_fb_cpu_access;
  375. ret = appletbdrm_read_response(adev, &response->header, sizeof(*response),
  376. APPLETBDRM_MSG_UPDATE_COMPLETE);
  377. if (ret)
  378. goto end_fb_cpu_access;
  379. if (response->timestamp != footer->timestamp) {
  380. drm_err(drm, "Response timestamp (%llu) doesn't match request timestamp (%llu)\n",
  381. le64_to_cpu(response->timestamp), timestamp);
  382. goto end_fb_cpu_access;
  383. }
  384. end_fb_cpu_access:
  385. drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
  386. return ret;
  387. }
  388. static void appletbdrm_primary_plane_helper_atomic_update(struct drm_plane *plane,
  389. struct drm_atomic_state *old_state)
  390. {
  391. struct appletbdrm_device *adev = drm_to_adev(plane->dev);
  392. struct drm_device *drm = plane->dev;
  393. struct drm_plane_state *plane_state = plane->state;
  394. struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(old_state, plane);
  395. int idx;
  396. if (!drm_dev_enter(drm, &idx))
  397. return;
  398. appletbdrm_flush_damage(adev, old_plane_state, plane_state);
  399. drm_dev_exit(idx);
  400. }
  401. static void appletbdrm_primary_plane_helper_atomic_disable(struct drm_plane *plane,
  402. struct drm_atomic_state *state)
  403. {
  404. struct drm_device *dev = plane->dev;
  405. struct appletbdrm_device *adev = drm_to_adev(dev);
  406. int idx;
  407. if (!drm_dev_enter(dev, &idx))
  408. return;
  409. appletbdrm_clear_display(adev);
  410. drm_dev_exit(idx);
  411. }
  412. static void appletbdrm_primary_plane_reset(struct drm_plane *plane)
  413. {
  414. struct appletbdrm_plane_state *appletbdrm_state;
  415. WARN_ON(plane->state);
  416. appletbdrm_state = kzalloc_obj(*appletbdrm_state);
  417. if (!appletbdrm_state)
  418. return;
  419. __drm_gem_reset_shadow_plane(plane, &appletbdrm_state->base);
  420. }
  421. static struct drm_plane_state *appletbdrm_primary_plane_duplicate_state(struct drm_plane *plane)
  422. {
  423. struct drm_shadow_plane_state *new_shadow_plane_state;
  424. struct appletbdrm_plane_state *appletbdrm_state;
  425. if (WARN_ON(!plane->state))
  426. return NULL;
  427. appletbdrm_state = kzalloc_obj(*appletbdrm_state);
  428. if (!appletbdrm_state)
  429. return NULL;
  430. /* Request and response are not duplicated and are allocated in .atomic_check */
  431. appletbdrm_state->request = NULL;
  432. appletbdrm_state->response = NULL;
  433. appletbdrm_state->request_size = 0;
  434. appletbdrm_state->frames_size = 0;
  435. new_shadow_plane_state = &appletbdrm_state->base;
  436. __drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state);
  437. return &new_shadow_plane_state->base;
  438. }
  439. static void appletbdrm_primary_plane_destroy_state(struct drm_plane *plane,
  440. struct drm_plane_state *state)
  441. {
  442. struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(state);
  443. kfree(appletbdrm_state->request);
  444. kfree(appletbdrm_state->response);
  445. __drm_gem_destroy_shadow_plane_state(&appletbdrm_state->base);
  446. kfree(appletbdrm_state);
  447. }
  448. static const struct drm_plane_helper_funcs appletbdrm_primary_plane_helper_funcs = {
  449. DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
  450. .atomic_check = appletbdrm_primary_plane_helper_atomic_check,
  451. .atomic_update = appletbdrm_primary_plane_helper_atomic_update,
  452. .atomic_disable = appletbdrm_primary_plane_helper_atomic_disable,
  453. };
  454. static const struct drm_plane_funcs appletbdrm_primary_plane_funcs = {
  455. .update_plane = drm_atomic_helper_update_plane,
  456. .disable_plane = drm_atomic_helper_disable_plane,
  457. .reset = appletbdrm_primary_plane_reset,
  458. .atomic_duplicate_state = appletbdrm_primary_plane_duplicate_state,
  459. .atomic_destroy_state = appletbdrm_primary_plane_destroy_state,
  460. .destroy = drm_plane_cleanup,
  461. };
  462. static enum drm_mode_status appletbdrm_crtc_helper_mode_valid(struct drm_crtc *crtc,
  463. const struct drm_display_mode *mode)
  464. {
  465. struct appletbdrm_device *adev = drm_to_adev(crtc->dev);
  466. return drm_crtc_helper_mode_valid_fixed(crtc, mode, &adev->mode);
  467. }
  468. static const struct drm_mode_config_funcs appletbdrm_mode_config_funcs = {
  469. .fb_create = drm_gem_fb_create_with_dirty,
  470. .atomic_check = drm_atomic_helper_check,
  471. .atomic_commit = drm_atomic_helper_commit,
  472. };
  473. static const struct drm_connector_funcs appletbdrm_connector_funcs = {
  474. .reset = drm_atomic_helper_connector_reset,
  475. .destroy = drm_connector_cleanup,
  476. .fill_modes = drm_helper_probe_single_connector_modes,
  477. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  478. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  479. };
  480. static const struct drm_connector_helper_funcs appletbdrm_connector_helper_funcs = {
  481. .get_modes = appletbdrm_connector_helper_get_modes,
  482. };
  483. static const struct drm_crtc_helper_funcs appletbdrm_crtc_helper_funcs = {
  484. .mode_valid = appletbdrm_crtc_helper_mode_valid,
  485. };
  486. static const struct drm_crtc_funcs appletbdrm_crtc_funcs = {
  487. .reset = drm_atomic_helper_crtc_reset,
  488. .destroy = drm_crtc_cleanup,
  489. .set_config = drm_atomic_helper_set_config,
  490. .page_flip = drm_atomic_helper_page_flip,
  491. .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
  492. .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
  493. };
  494. static const struct drm_encoder_funcs appletbdrm_encoder_funcs = {
  495. .destroy = drm_encoder_cleanup,
  496. };
  497. DEFINE_DRM_GEM_FOPS(appletbdrm_drm_fops);
  498. static const struct drm_driver appletbdrm_drm_driver = {
  499. DRM_GEM_SHMEM_DRIVER_OPS,
  500. .name = "appletbdrm",
  501. .desc = "Apple Touch Bar DRM Driver",
  502. .major = 1,
  503. .minor = 0,
  504. .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
  505. .fops = &appletbdrm_drm_fops,
  506. };
  507. static int appletbdrm_setup_mode_config(struct appletbdrm_device *adev)
  508. {
  509. struct drm_connector *connector = &adev->connector;
  510. struct drm_plane *primary_plane;
  511. struct drm_crtc *crtc;
  512. struct drm_encoder *encoder;
  513. struct drm_device *drm = &adev->drm;
  514. int ret;
  515. ret = drmm_mode_config_init(drm);
  516. if (ret) {
  517. drm_err(drm, "Failed to initialize mode configuration\n");
  518. return ret;
  519. }
  520. primary_plane = &adev->primary_plane;
  521. ret = drm_universal_plane_init(drm, primary_plane, 0,
  522. &appletbdrm_primary_plane_funcs,
  523. appletbdrm_primary_plane_formats,
  524. ARRAY_SIZE(appletbdrm_primary_plane_formats),
  525. NULL,
  526. DRM_PLANE_TYPE_PRIMARY, NULL);
  527. if (ret) {
  528. drm_err(drm, "Failed to initialize universal plane object\n");
  529. return ret;
  530. }
  531. drm_plane_helper_add(primary_plane, &appletbdrm_primary_plane_helper_funcs);
  532. drm_plane_enable_fb_damage_clips(primary_plane);
  533. crtc = &adev->crtc;
  534. ret = drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
  535. &appletbdrm_crtc_funcs, NULL);
  536. if (ret) {
  537. drm_err(drm, "Failed to initialize CRTC object\n");
  538. return ret;
  539. }
  540. drm_crtc_helper_add(crtc, &appletbdrm_crtc_helper_funcs);
  541. encoder = &adev->encoder;
  542. ret = drm_encoder_init(drm, encoder, &appletbdrm_encoder_funcs,
  543. DRM_MODE_ENCODER_DAC, NULL);
  544. if (ret) {
  545. drm_err(drm, "Failed to initialize encoder\n");
  546. return ret;
  547. }
  548. encoder->possible_crtcs = drm_crtc_mask(crtc);
  549. /*
  550. * The coordinate system used by the device is different from the
  551. * coordinate system of the framebuffer in that the x and y axes are
  552. * swapped, and that the y axis is inverted; so what the device reports
  553. * as the height is actually the width of the framebuffer and vice
  554. * versa.
  555. */
  556. drm->mode_config.max_width = max(adev->height, DRM_SHADOW_PLANE_MAX_WIDTH);
  557. drm->mode_config.max_height = max(adev->width, DRM_SHADOW_PLANE_MAX_HEIGHT);
  558. drm->mode_config.preferred_depth = APPLETBDRM_BITS_PER_PIXEL;
  559. drm->mode_config.funcs = &appletbdrm_mode_config_funcs;
  560. adev->mode = (struct drm_display_mode) {
  561. DRM_MODE_INIT(60, adev->height, adev->width,
  562. DRM_MODE_RES_MM(adev->height, 218),
  563. DRM_MODE_RES_MM(adev->width, 218))
  564. };
  565. ret = drm_connector_init(drm, connector,
  566. &appletbdrm_connector_funcs, DRM_MODE_CONNECTOR_USB);
  567. if (ret) {
  568. drm_err(drm, "Failed to initialize connector\n");
  569. return ret;
  570. }
  571. drm_connector_helper_add(connector, &appletbdrm_connector_helper_funcs);
  572. ret = drm_connector_set_panel_orientation(connector,
  573. DRM_MODE_PANEL_ORIENTATION_RIGHT_UP);
  574. if (ret) {
  575. drm_err(drm, "Failed to set panel orientation\n");
  576. return ret;
  577. }
  578. connector->display_info.non_desktop = true;
  579. ret = drm_object_property_set_value(&connector->base,
  580. drm->mode_config.non_desktop_property, true);
  581. if (ret) {
  582. drm_err(drm, "Failed to set non-desktop property\n");
  583. return ret;
  584. }
  585. ret = drm_connector_attach_encoder(connector, encoder);
  586. if (ret) {
  587. drm_err(drm, "Failed to initialize simple display pipe\n");
  588. return ret;
  589. }
  590. drm_mode_config_reset(drm);
  591. return 0;
  592. }
  593. static int appletbdrm_probe(struct usb_interface *intf,
  594. const struct usb_device_id *id)
  595. {
  596. struct usb_endpoint_descriptor *bulk_in, *bulk_out;
  597. struct device *dev = &intf->dev;
  598. struct appletbdrm_device *adev;
  599. struct drm_device *drm = NULL;
  600. struct device *dma_dev;
  601. int ret;
  602. ret = usb_find_common_endpoints(intf->cur_altsetting, &bulk_in, &bulk_out, NULL, NULL);
  603. if (ret) {
  604. drm_err(drm, "appletbdrm: Failed to find bulk endpoints\n");
  605. return ret;
  606. }
  607. adev = devm_drm_dev_alloc(dev, &appletbdrm_drm_driver, struct appletbdrm_device, drm);
  608. if (IS_ERR(adev))
  609. return PTR_ERR(adev);
  610. adev->in_ep = bulk_in->bEndpointAddress;
  611. adev->out_ep = bulk_out->bEndpointAddress;
  612. drm = &adev->drm;
  613. usb_set_intfdata(intf, adev);
  614. dma_dev = usb_intf_get_dma_device(intf);
  615. if (dma_dev) {
  616. drm_dev_set_dma_dev(drm, dma_dev);
  617. put_device(dma_dev);
  618. } else {
  619. drm_warn(drm, "buffer sharing not supported"); /* not an error */
  620. }
  621. ret = appletbdrm_get_information(adev);
  622. if (ret) {
  623. drm_err(drm, "Failed to get display information\n");
  624. return ret;
  625. }
  626. ret = appletbdrm_signal_readiness(adev);
  627. if (ret) {
  628. drm_err(drm, "Failed to signal readiness\n");
  629. return ret;
  630. }
  631. ret = appletbdrm_setup_mode_config(adev);
  632. if (ret) {
  633. drm_err(drm, "Failed to setup mode config\n");
  634. return ret;
  635. }
  636. ret = drm_dev_register(drm, 0);
  637. if (ret) {
  638. drm_err(drm, "Failed to register DRM device\n");
  639. return ret;
  640. }
  641. ret = appletbdrm_clear_display(adev);
  642. if (ret) {
  643. drm_err(drm, "Failed to clear display\n");
  644. return ret;
  645. }
  646. return 0;
  647. }
  648. static void appletbdrm_disconnect(struct usb_interface *intf)
  649. {
  650. struct appletbdrm_device *adev = usb_get_intfdata(intf);
  651. struct drm_device *drm = &adev->drm;
  652. drm_dev_unplug(drm);
  653. drm_atomic_helper_shutdown(drm);
  654. }
  655. static void appletbdrm_shutdown(struct usb_interface *intf)
  656. {
  657. struct appletbdrm_device *adev = usb_get_intfdata(intf);
  658. /*
  659. * The framebuffer needs to be cleared on shutdown since its content
  660. * persists across boots
  661. */
  662. drm_atomic_helper_shutdown(&adev->drm);
  663. }
  664. static const struct usb_device_id appletbdrm_usb_id_table[] = {
  665. { USB_DEVICE_INTERFACE_CLASS(0x05ac, 0x8302, USB_CLASS_AUDIO_VIDEO) },
  666. {}
  667. };
  668. MODULE_DEVICE_TABLE(usb, appletbdrm_usb_id_table);
  669. static struct usb_driver appletbdrm_usb_driver = {
  670. .name = "appletbdrm",
  671. .probe = appletbdrm_probe,
  672. .disconnect = appletbdrm_disconnect,
  673. .shutdown = appletbdrm_shutdown,
  674. .id_table = appletbdrm_usb_id_table,
  675. };
  676. module_usb_driver(appletbdrm_usb_driver);
  677. MODULE_AUTHOR("Kerem Karabay <kekrby@gmail.com>");
  678. MODULE_DESCRIPTION("Apple Touch Bar DRM Driver");
  679. MODULE_LICENSE("GPL");