drm_plane.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. /*
  2. * Copyright (c) 2016 Intel Corporation
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that copyright
  7. * notice and this permission notice appear in supporting documentation, and
  8. * that the name of the copyright holders not be used in advertising or
  9. * publicity pertaining to distribution of the software without specific,
  10. * written prior permission. The copyright holders make no representations
  11. * about the suitability of this software for any purpose. It is provided "as
  12. * is" without express or implied warranty.
  13. *
  14. * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  20. * OF THIS SOFTWARE.
  21. */
  22. #include <linux/slab.h>
  23. #include <linux/uaccess.h>
  24. #include <drm/drm_plane.h>
  25. #include <drm/drm_drv.h>
  26. #include <drm/drm_print.h>
  27. #include <drm/drm_framebuffer.h>
  28. #include <drm/drm_file.h>
  29. #include <drm/drm_crtc.h>
  30. #include <drm/drm_fourcc.h>
  31. #include <drm/drm_vblank.h>
  32. #include "drm_crtc_internal.h"
  33. /**
  34. * DOC: overview
  35. *
  36. * A plane represents an image source that can be blended with or overlayed on
  37. * top of a CRTC during the scanout process. Planes take their input data from a
  38. * &drm_framebuffer object. The plane itself specifies the cropping and scaling
  39. * of that image, and where it is placed on the visible are of a display
  40. * pipeline, represented by &drm_crtc. A plane can also have additional
  41. * properties that specify how the pixels are positioned and blended, like
  42. * rotation or Z-position. All these properties are stored in &drm_plane_state.
  43. *
  44. * To create a plane, a KMS drivers allocates and zeroes an instances of
  45. * &struct drm_plane (possibly as part of a larger structure) and registers it
  46. * with a call to drm_universal_plane_init().
  47. *
  48. * Cursor and overlay planes are optional. All drivers should provide one
  49. * primary plane per CRTC to avoid surprising userspace too much. See enum
  50. * drm_plane_type for a more in-depth discussion of these special uapi-relevant
  51. * plane types. Special planes are associated with their CRTC by calling
  52. * drm_crtc_init_with_planes().
  53. *
  54. * The type of a plane is exposed in the immutable "type" enumeration property,
  55. * which has one of the following values: "Overlay", "Primary", "Cursor".
  56. */
  57. static unsigned int drm_num_planes(struct drm_device *dev)
  58. {
  59. unsigned int num = 0;
  60. struct drm_plane *tmp;
  61. drm_for_each_plane(tmp, dev) {
  62. num++;
  63. }
  64. return num;
  65. }
  66. static inline u32 *
  67. formats_ptr(struct drm_format_modifier_blob *blob)
  68. {
  69. return (u32 *)(((char *)blob) + blob->formats_offset);
  70. }
  71. static inline struct drm_format_modifier *
  72. modifiers_ptr(struct drm_format_modifier_blob *blob)
  73. {
  74. return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
  75. }
  76. static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane)
  77. {
  78. const struct drm_mode_config *config = &dev->mode_config;
  79. struct drm_property_blob *blob;
  80. struct drm_format_modifier *mod;
  81. size_t blob_size, formats_size, modifiers_size;
  82. struct drm_format_modifier_blob *blob_data;
  83. unsigned int i, j;
  84. formats_size = sizeof(__u32) * plane->format_count;
  85. if (WARN_ON(!formats_size)) {
  86. /* 0 formats are never expected */
  87. return 0;
  88. }
  89. modifiers_size =
  90. sizeof(struct drm_format_modifier) * plane->modifier_count;
  91. blob_size = sizeof(struct drm_format_modifier_blob);
  92. /* Modifiers offset is a pointer to a struct with a 64 bit field so it
  93. * should be naturally aligned to 8B.
  94. */
  95. BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8);
  96. blob_size += ALIGN(formats_size, 8);
  97. blob_size += modifiers_size;
  98. blob = drm_property_create_blob(dev, blob_size, NULL);
  99. if (IS_ERR(blob))
  100. return -1;
  101. blob_data = blob->data;
  102. blob_data->version = FORMAT_BLOB_CURRENT;
  103. blob_data->count_formats = plane->format_count;
  104. blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
  105. blob_data->count_modifiers = plane->modifier_count;
  106. blob_data->modifiers_offset =
  107. ALIGN(blob_data->formats_offset + formats_size, 8);
  108. memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
  109. /* If we can't determine support, just bail */
  110. if (!plane->funcs->format_mod_supported)
  111. goto done;
  112. mod = modifiers_ptr(blob_data);
  113. for (i = 0; i < plane->modifier_count; i++) {
  114. for (j = 0; j < plane->format_count; j++) {
  115. if (plane->funcs->format_mod_supported(plane,
  116. plane->format_types[j],
  117. plane->modifiers[i])) {
  118. mod->formats |= 1ULL << j;
  119. }
  120. }
  121. mod->modifier = plane->modifiers[i];
  122. mod->offset = 0;
  123. mod->pad = 0;
  124. mod++;
  125. }
  126. done:
  127. drm_object_attach_property(&plane->base, config->modifiers_property,
  128. blob->base.id);
  129. return 0;
  130. }
  131. /**
  132. * drm_universal_plane_init - Initialize a new universal plane object
  133. * @dev: DRM device
  134. * @plane: plane object to init
  135. * @possible_crtcs: bitmask of possible CRTCs
  136. * @funcs: callbacks for the new plane
  137. * @formats: array of supported formats (DRM_FORMAT\_\*)
  138. * @format_count: number of elements in @formats
  139. * @format_modifiers: array of struct drm_format modifiers terminated by
  140. * DRM_FORMAT_MOD_INVALID
  141. * @type: type of plane (overlay, primary, cursor)
  142. * @name: printf style format string for the plane name, or NULL for default name
  143. *
  144. * Initializes a plane object of type @type.
  145. *
  146. * Returns:
  147. * Zero on success, error code on failure.
  148. */
  149. int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
  150. uint32_t possible_crtcs,
  151. const struct drm_plane_funcs *funcs,
  152. const uint32_t *formats, unsigned int format_count,
  153. const uint64_t *format_modifiers,
  154. enum drm_plane_type type,
  155. const char *name, ...)
  156. {
  157. struct drm_mode_config *config = &dev->mode_config;
  158. unsigned int format_modifier_count = 0;
  159. int ret;
  160. /* plane index is used with 32bit bitmasks */
  161. if (WARN_ON(config->num_total_plane >= 32))
  162. return -EINVAL;
  163. WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
  164. (!funcs->atomic_destroy_state ||
  165. !funcs->atomic_duplicate_state));
  166. ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
  167. if (ret)
  168. return ret;
  169. drm_modeset_lock_init(&plane->mutex);
  170. plane->base.properties = &plane->properties;
  171. plane->dev = dev;
  172. plane->funcs = funcs;
  173. plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
  174. GFP_KERNEL);
  175. if (!plane->format_types) {
  176. DRM_DEBUG_KMS("out of memory when allocating plane\n");
  177. drm_mode_object_unregister(dev, &plane->base);
  178. return -ENOMEM;
  179. }
  180. /*
  181. * First driver to need more than 64 formats needs to fix this. Each
  182. * format is encoded as a bit and the current code only supports a u64.
  183. */
  184. if (WARN_ON(format_count > 64))
  185. return -EINVAL;
  186. if (format_modifiers) {
  187. const uint64_t *temp_modifiers = format_modifiers;
  188. while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
  189. format_modifier_count++;
  190. }
  191. plane->modifier_count = format_modifier_count;
  192. plane->modifiers = kmalloc_array(format_modifier_count,
  193. sizeof(format_modifiers[0]),
  194. GFP_KERNEL);
  195. if (format_modifier_count && !plane->modifiers) {
  196. DRM_DEBUG_KMS("out of memory when allocating plane\n");
  197. kfree(plane->format_types);
  198. drm_mode_object_unregister(dev, &plane->base);
  199. return -ENOMEM;
  200. }
  201. if (name) {
  202. va_list ap;
  203. va_start(ap, name);
  204. plane->name = kvasprintf(GFP_KERNEL, name, ap);
  205. va_end(ap);
  206. } else {
  207. plane->name = kasprintf(GFP_KERNEL, "plane-%d",
  208. drm_num_planes(dev));
  209. }
  210. if (!plane->name) {
  211. kfree(plane->format_types);
  212. kfree(plane->modifiers);
  213. drm_mode_object_unregister(dev, &plane->base);
  214. return -ENOMEM;
  215. }
  216. memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
  217. plane->format_count = format_count;
  218. memcpy(plane->modifiers, format_modifiers,
  219. format_modifier_count * sizeof(format_modifiers[0]));
  220. plane->possible_crtcs = possible_crtcs;
  221. plane->type = type;
  222. list_add_tail(&plane->head, &config->plane_list);
  223. plane->index = config->num_total_plane++;
  224. drm_object_attach_property(&plane->base,
  225. config->plane_type_property,
  226. plane->type);
  227. if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
  228. drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
  229. drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1);
  230. drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
  231. drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
  232. drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
  233. drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
  234. drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
  235. drm_object_attach_property(&plane->base, config->prop_src_x, 0);
  236. drm_object_attach_property(&plane->base, config->prop_src_y, 0);
  237. drm_object_attach_property(&plane->base, config->prop_src_w, 0);
  238. drm_object_attach_property(&plane->base, config->prop_src_h, 0);
  239. }
  240. if (config->allow_fb_modifiers)
  241. create_in_format_blob(dev, plane);
  242. return 0;
  243. }
  244. EXPORT_SYMBOL(drm_universal_plane_init);
  245. int drm_plane_register_all(struct drm_device *dev)
  246. {
  247. struct drm_plane *plane;
  248. int ret = 0;
  249. drm_for_each_plane(plane, dev) {
  250. if (plane->funcs->late_register)
  251. ret = plane->funcs->late_register(plane);
  252. if (ret)
  253. return ret;
  254. }
  255. return 0;
  256. }
  257. void drm_plane_unregister_all(struct drm_device *dev)
  258. {
  259. struct drm_plane *plane;
  260. drm_for_each_plane(plane, dev) {
  261. if (plane->funcs->early_unregister)
  262. plane->funcs->early_unregister(plane);
  263. }
  264. }
  265. /**
  266. * drm_plane_init - Initialize a legacy plane
  267. * @dev: DRM device
  268. * @plane: plane object to init
  269. * @possible_crtcs: bitmask of possible CRTCs
  270. * @funcs: callbacks for the new plane
  271. * @formats: array of supported formats (DRM_FORMAT\_\*)
  272. * @format_count: number of elements in @formats
  273. * @is_primary: plane type (primary vs overlay)
  274. *
  275. * Legacy API to initialize a DRM plane.
  276. *
  277. * New drivers should call drm_universal_plane_init() instead.
  278. *
  279. * Returns:
  280. * Zero on success, error code on failure.
  281. */
  282. int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
  283. uint32_t possible_crtcs,
  284. const struct drm_plane_funcs *funcs,
  285. const uint32_t *formats, unsigned int format_count,
  286. bool is_primary)
  287. {
  288. enum drm_plane_type type;
  289. type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
  290. return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
  291. formats, format_count,
  292. NULL, type, NULL);
  293. }
  294. EXPORT_SYMBOL(drm_plane_init);
  295. /**
  296. * drm_plane_cleanup - Clean up the core plane usage
  297. * @plane: plane to cleanup
  298. *
  299. * This function cleans up @plane and removes it from the DRM mode setting
  300. * core. Note that the function does *not* free the plane structure itself,
  301. * this is the responsibility of the caller.
  302. */
  303. void drm_plane_cleanup(struct drm_plane *plane)
  304. {
  305. struct drm_device *dev = plane->dev;
  306. drm_modeset_lock_fini(&plane->mutex);
  307. kfree(plane->format_types);
  308. kfree(plane->modifiers);
  309. drm_mode_object_unregister(dev, &plane->base);
  310. BUG_ON(list_empty(&plane->head));
  311. /* Note that the plane_list is considered to be static; should we
  312. * remove the drm_plane at runtime we would have to decrement all
  313. * the indices on the drm_plane after us in the plane_list.
  314. */
  315. list_del(&plane->head);
  316. dev->mode_config.num_total_plane--;
  317. WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
  318. if (plane->state && plane->funcs->atomic_destroy_state)
  319. plane->funcs->atomic_destroy_state(plane, plane->state);
  320. kfree(plane->name);
  321. memset(plane, 0, sizeof(*plane));
  322. }
  323. EXPORT_SYMBOL(drm_plane_cleanup);
  324. /**
  325. * drm_plane_from_index - find the registered plane at an index
  326. * @dev: DRM device
  327. * @idx: index of registered plane to find for
  328. *
  329. * Given a plane index, return the registered plane from DRM device's
  330. * list of planes with matching index. This is the inverse of drm_plane_index().
  331. */
  332. struct drm_plane *
  333. drm_plane_from_index(struct drm_device *dev, int idx)
  334. {
  335. struct drm_plane *plane;
  336. drm_for_each_plane(plane, dev)
  337. if (idx == plane->index)
  338. return plane;
  339. return NULL;
  340. }
  341. EXPORT_SYMBOL(drm_plane_from_index);
  342. /**
  343. * drm_plane_force_disable - Forcibly disable a plane
  344. * @plane: plane to disable
  345. *
  346. * Forces the plane to be disabled.
  347. *
  348. * Used when the plane's current framebuffer is destroyed,
  349. * and when restoring fbdev mode.
  350. *
  351. * Note that this function is not suitable for atomic drivers, since it doesn't
  352. * wire through the lock acquisition context properly and hence can't handle
  353. * retries or driver private locks. You probably want to use
  354. * drm_atomic_helper_disable_plane() or
  355. * drm_atomic_helper_disable_planes_on_crtc() instead.
  356. */
  357. void drm_plane_force_disable(struct drm_plane *plane)
  358. {
  359. int ret;
  360. if (!plane->fb)
  361. return;
  362. WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
  363. plane->old_fb = plane->fb;
  364. ret = plane->funcs->disable_plane(plane, NULL);
  365. if (ret) {
  366. DRM_ERROR("failed to disable plane with busy fb\n");
  367. plane->old_fb = NULL;
  368. return;
  369. }
  370. /* disconnect the plane from the fb and crtc: */
  371. drm_framebuffer_put(plane->old_fb);
  372. plane->old_fb = NULL;
  373. plane->fb = NULL;
  374. plane->crtc = NULL;
  375. }
  376. EXPORT_SYMBOL(drm_plane_force_disable);
  377. /**
  378. * drm_mode_plane_set_obj_prop - set the value of a property
  379. * @plane: drm plane object to set property value for
  380. * @property: property to set
  381. * @value: value the property should be set to
  382. *
  383. * This functions sets a given property on a given plane object. This function
  384. * calls the driver's ->set_property callback and changes the software state of
  385. * the property if the callback succeeds.
  386. *
  387. * Returns:
  388. * Zero on success, error code on failure.
  389. */
  390. int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
  391. struct drm_property *property,
  392. uint64_t value)
  393. {
  394. int ret = -EINVAL;
  395. struct drm_mode_object *obj = &plane->base;
  396. if (plane->funcs->set_property)
  397. ret = plane->funcs->set_property(plane, property, value);
  398. if (!ret)
  399. drm_object_property_set_value(obj, property, value);
  400. return ret;
  401. }
  402. EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
  403. int drm_mode_getplane_res(struct drm_device *dev, void *data,
  404. struct drm_file *file_priv)
  405. {
  406. struct drm_mode_get_plane_res *plane_resp = data;
  407. struct drm_plane *plane;
  408. uint32_t __user *plane_ptr;
  409. int count = 0;
  410. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  411. return -EOPNOTSUPP;
  412. plane_ptr = u64_to_user_ptr(plane_resp->plane_id_ptr);
  413. /*
  414. * This ioctl is called twice, once to determine how much space is
  415. * needed, and the 2nd time to fill it.
  416. */
  417. drm_for_each_plane(plane, dev) {
  418. /*
  419. * Unless userspace set the 'universal planes'
  420. * capability bit, only advertise overlays.
  421. */
  422. if (plane->type != DRM_PLANE_TYPE_OVERLAY &&
  423. !file_priv->universal_planes)
  424. continue;
  425. if (drm_lease_held(file_priv, plane->base.id)) {
  426. if (count < plane_resp->count_planes &&
  427. put_user(plane->base.id, plane_ptr + count))
  428. return -EFAULT;
  429. count++;
  430. }
  431. }
  432. plane_resp->count_planes = count;
  433. return 0;
  434. }
  435. int drm_mode_getplane(struct drm_device *dev, void *data,
  436. struct drm_file *file_priv)
  437. {
  438. struct drm_mode_get_plane *plane_resp = data;
  439. struct drm_plane *plane;
  440. uint32_t __user *format_ptr;
  441. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  442. return -EOPNOTSUPP;
  443. plane = drm_plane_find(dev, file_priv, plane_resp->plane_id);
  444. if (!plane)
  445. return -ENOENT;
  446. drm_modeset_lock(&plane->mutex, NULL);
  447. if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id))
  448. plane_resp->crtc_id = plane->state->crtc->base.id;
  449. else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id))
  450. plane_resp->crtc_id = plane->crtc->base.id;
  451. else
  452. plane_resp->crtc_id = 0;
  453. if (plane->state && plane->state->fb)
  454. plane_resp->fb_id = plane->state->fb->base.id;
  455. else if (!plane->state && plane->fb)
  456. plane_resp->fb_id = plane->fb->base.id;
  457. else
  458. plane_resp->fb_id = 0;
  459. drm_modeset_unlock(&plane->mutex);
  460. plane_resp->plane_id = plane->base.id;
  461. plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
  462. plane->possible_crtcs);
  463. plane_resp->gamma_size = 0;
  464. /*
  465. * This ioctl is called twice, once to determine how much space is
  466. * needed, and the 2nd time to fill it.
  467. */
  468. if (plane->format_count &&
  469. (plane_resp->count_format_types >= plane->format_count)) {
  470. format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
  471. if (copy_to_user(format_ptr,
  472. plane->format_types,
  473. sizeof(uint32_t) * plane->format_count)) {
  474. return -EFAULT;
  475. }
  476. }
  477. plane_resp->count_format_types = plane->format_count;
  478. return 0;
  479. }
  480. int drm_plane_check_pixel_format(struct drm_plane *plane,
  481. u32 format, u64 modifier)
  482. {
  483. unsigned int i;
  484. for (i = 0; i < plane->format_count; i++) {
  485. if (format == plane->format_types[i])
  486. break;
  487. }
  488. if (i == plane->format_count)
  489. return -EINVAL;
  490. if (plane->funcs->format_mod_supported) {
  491. if (!plane->funcs->format_mod_supported(plane, format, modifier))
  492. return -EINVAL;
  493. } else {
  494. if (!plane->modifier_count)
  495. return 0;
  496. for (i = 0; i < plane->modifier_count; i++) {
  497. if (modifier == plane->modifiers[i])
  498. break;
  499. }
  500. if (i == plane->modifier_count)
  501. return -EINVAL;
  502. }
  503. return 0;
  504. }
  505. static int __setplane_check(struct drm_plane *plane,
  506. struct drm_crtc *crtc,
  507. struct drm_framebuffer *fb,
  508. int32_t crtc_x, int32_t crtc_y,
  509. uint32_t crtc_w, uint32_t crtc_h,
  510. uint32_t src_x, uint32_t src_y,
  511. uint32_t src_w, uint32_t src_h)
  512. {
  513. int ret;
  514. /* Check whether this plane is usable on this CRTC */
  515. if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
  516. DRM_DEBUG_KMS("Invalid crtc for plane\n");
  517. return -EINVAL;
  518. }
  519. /* Check whether this plane supports the fb pixel format. */
  520. ret = drm_plane_check_pixel_format(plane, fb->format->format,
  521. fb->modifier);
  522. if (ret) {
  523. struct drm_format_name_buf format_name;
  524. DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
  525. drm_get_format_name(fb->format->format,
  526. &format_name),
  527. fb->modifier);
  528. return ret;
  529. }
  530. /* Give drivers some help against integer overflows */
  531. if (crtc_w > INT_MAX ||
  532. crtc_x > INT_MAX - (int32_t) crtc_w ||
  533. crtc_h > INT_MAX ||
  534. crtc_y > INT_MAX - (int32_t) crtc_h) {
  535. DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
  536. crtc_w, crtc_h, crtc_x, crtc_y);
  537. return -ERANGE;
  538. }
  539. ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb);
  540. if (ret)
  541. return ret;
  542. return 0;
  543. }
  544. /*
  545. * __setplane_internal - setplane handler for internal callers
  546. *
  547. * This function will take a reference on the new fb for the plane
  548. * on success.
  549. *
  550. * src_{x,y,w,h} are provided in 16.16 fixed point format
  551. */
  552. static int __setplane_internal(struct drm_plane *plane,
  553. struct drm_crtc *crtc,
  554. struct drm_framebuffer *fb,
  555. int32_t crtc_x, int32_t crtc_y,
  556. uint32_t crtc_w, uint32_t crtc_h,
  557. /* src_{x,y,w,h} values are 16.16 fixed point */
  558. uint32_t src_x, uint32_t src_y,
  559. uint32_t src_w, uint32_t src_h,
  560. struct drm_modeset_acquire_ctx *ctx)
  561. {
  562. int ret = 0;
  563. WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
  564. /* No fb means shut it down */
  565. if (!fb) {
  566. plane->old_fb = plane->fb;
  567. ret = plane->funcs->disable_plane(plane, ctx);
  568. if (!ret) {
  569. plane->crtc = NULL;
  570. plane->fb = NULL;
  571. } else {
  572. plane->old_fb = NULL;
  573. }
  574. goto out;
  575. }
  576. ret = __setplane_check(plane, crtc, fb,
  577. crtc_x, crtc_y, crtc_w, crtc_h,
  578. src_x, src_y, src_w, src_h);
  579. if (ret)
  580. goto out;
  581. plane->old_fb = plane->fb;
  582. ret = plane->funcs->update_plane(plane, crtc, fb,
  583. crtc_x, crtc_y, crtc_w, crtc_h,
  584. src_x, src_y, src_w, src_h, ctx);
  585. if (!ret) {
  586. plane->crtc = crtc;
  587. plane->fb = fb;
  588. drm_framebuffer_get(plane->fb);
  589. } else {
  590. plane->old_fb = NULL;
  591. }
  592. out:
  593. if (plane->old_fb)
  594. drm_framebuffer_put(plane->old_fb);
  595. plane->old_fb = NULL;
  596. return ret;
  597. }
  598. static int __setplane_atomic(struct drm_plane *plane,
  599. struct drm_crtc *crtc,
  600. struct drm_framebuffer *fb,
  601. int32_t crtc_x, int32_t crtc_y,
  602. uint32_t crtc_w, uint32_t crtc_h,
  603. uint32_t src_x, uint32_t src_y,
  604. uint32_t src_w, uint32_t src_h,
  605. struct drm_modeset_acquire_ctx *ctx)
  606. {
  607. int ret;
  608. WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
  609. /* No fb means shut it down */
  610. if (!fb)
  611. return plane->funcs->disable_plane(plane, ctx);
  612. /*
  613. * FIXME: This is redundant with drm_atomic_plane_check(),
  614. * but the legacy cursor/"async" .update_plane() tricks
  615. * don't call that so we still need this here. Should remove
  616. * this when all .update_plane() implementations have been
  617. * fixed to call drm_atomic_plane_check().
  618. */
  619. ret = __setplane_check(plane, crtc, fb,
  620. crtc_x, crtc_y, crtc_w, crtc_h,
  621. src_x, src_y, src_w, src_h);
  622. if (ret)
  623. return ret;
  624. return plane->funcs->update_plane(plane, crtc, fb,
  625. crtc_x, crtc_y, crtc_w, crtc_h,
  626. src_x, src_y, src_w, src_h, ctx);
  627. }
  628. static int setplane_internal(struct drm_plane *plane,
  629. struct drm_crtc *crtc,
  630. struct drm_framebuffer *fb,
  631. int32_t crtc_x, int32_t crtc_y,
  632. uint32_t crtc_w, uint32_t crtc_h,
  633. /* src_{x,y,w,h} values are 16.16 fixed point */
  634. uint32_t src_x, uint32_t src_y,
  635. uint32_t src_w, uint32_t src_h)
  636. {
  637. struct drm_modeset_acquire_ctx ctx;
  638. int ret;
  639. drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
  640. retry:
  641. ret = drm_modeset_lock_all_ctx(plane->dev, &ctx);
  642. if (ret)
  643. goto fail;
  644. if (drm_drv_uses_atomic_modeset(plane->dev))
  645. ret = __setplane_atomic(plane, crtc, fb,
  646. crtc_x, crtc_y, crtc_w, crtc_h,
  647. src_x, src_y, src_w, src_h, &ctx);
  648. else
  649. ret = __setplane_internal(plane, crtc, fb,
  650. crtc_x, crtc_y, crtc_w, crtc_h,
  651. src_x, src_y, src_w, src_h, &ctx);
  652. fail:
  653. if (ret == -EDEADLK) {
  654. ret = drm_modeset_backoff(&ctx);
  655. if (!ret)
  656. goto retry;
  657. }
  658. drm_modeset_drop_locks(&ctx);
  659. drm_modeset_acquire_fini(&ctx);
  660. return ret;
  661. }
  662. int drm_mode_setplane(struct drm_device *dev, void *data,
  663. struct drm_file *file_priv)
  664. {
  665. struct drm_mode_set_plane *plane_req = data;
  666. struct drm_plane *plane;
  667. struct drm_crtc *crtc = NULL;
  668. struct drm_framebuffer *fb = NULL;
  669. int ret;
  670. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  671. return -EOPNOTSUPP;
  672. /*
  673. * First, find the plane, crtc, and fb objects. If not available,
  674. * we don't bother to call the driver.
  675. */
  676. plane = drm_plane_find(dev, file_priv, plane_req->plane_id);
  677. if (!plane) {
  678. DRM_DEBUG_KMS("Unknown plane ID %d\n",
  679. plane_req->plane_id);
  680. return -ENOENT;
  681. }
  682. if (plane_req->fb_id) {
  683. fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id);
  684. if (!fb) {
  685. DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
  686. plane_req->fb_id);
  687. return -ENOENT;
  688. }
  689. crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id);
  690. if (!crtc) {
  691. drm_framebuffer_put(fb);
  692. DRM_DEBUG_KMS("Unknown crtc ID %d\n",
  693. plane_req->crtc_id);
  694. return -ENOENT;
  695. }
  696. }
  697. ret = setplane_internal(plane, crtc, fb,
  698. plane_req->crtc_x, plane_req->crtc_y,
  699. plane_req->crtc_w, plane_req->crtc_h,
  700. plane_req->src_x, plane_req->src_y,
  701. plane_req->src_w, plane_req->src_h);
  702. if (fb)
  703. drm_framebuffer_put(fb);
  704. return ret;
  705. }
  706. static int drm_mode_cursor_universal(struct drm_crtc *crtc,
  707. struct drm_mode_cursor2 *req,
  708. struct drm_file *file_priv,
  709. struct drm_modeset_acquire_ctx *ctx)
  710. {
  711. struct drm_device *dev = crtc->dev;
  712. struct drm_plane *plane = crtc->cursor;
  713. struct drm_framebuffer *fb = NULL;
  714. struct drm_mode_fb_cmd2 fbreq = {
  715. .width = req->width,
  716. .height = req->height,
  717. .pixel_format = DRM_FORMAT_ARGB8888,
  718. .pitches = { req->width * 4 },
  719. .handles = { req->handle },
  720. };
  721. int32_t crtc_x, crtc_y;
  722. uint32_t crtc_w = 0, crtc_h = 0;
  723. uint32_t src_w = 0, src_h = 0;
  724. int ret = 0;
  725. BUG_ON(!plane);
  726. WARN_ON(plane->crtc != crtc && plane->crtc != NULL);
  727. /*
  728. * Obtain fb we'll be using (either new or existing) and take an extra
  729. * reference to it if fb != null. setplane will take care of dropping
  730. * the reference if the plane update fails.
  731. */
  732. if (req->flags & DRM_MODE_CURSOR_BO) {
  733. if (req->handle) {
  734. fb = drm_internal_framebuffer_create(dev, &fbreq, file_priv);
  735. if (IS_ERR(fb)) {
  736. DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
  737. return PTR_ERR(fb);
  738. }
  739. fb->hot_x = req->hot_x;
  740. fb->hot_y = req->hot_y;
  741. } else {
  742. fb = NULL;
  743. }
  744. } else {
  745. if (plane->state)
  746. fb = plane->state->fb;
  747. else
  748. fb = plane->fb;
  749. if (fb)
  750. drm_framebuffer_get(fb);
  751. }
  752. if (req->flags & DRM_MODE_CURSOR_MOVE) {
  753. crtc_x = req->x;
  754. crtc_y = req->y;
  755. } else {
  756. crtc_x = crtc->cursor_x;
  757. crtc_y = crtc->cursor_y;
  758. }
  759. if (fb) {
  760. crtc_w = fb->width;
  761. crtc_h = fb->height;
  762. src_w = fb->width << 16;
  763. src_h = fb->height << 16;
  764. }
  765. if (drm_drv_uses_atomic_modeset(dev))
  766. ret = __setplane_atomic(plane, crtc, fb,
  767. crtc_x, crtc_y, crtc_w, crtc_h,
  768. 0, 0, src_w, src_h, ctx);
  769. else
  770. ret = __setplane_internal(plane, crtc, fb,
  771. crtc_x, crtc_y, crtc_w, crtc_h,
  772. 0, 0, src_w, src_h, ctx);
  773. if (fb)
  774. drm_framebuffer_put(fb);
  775. /* Update successful; save new cursor position, if necessary */
  776. if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) {
  777. crtc->cursor_x = req->x;
  778. crtc->cursor_y = req->y;
  779. }
  780. return ret;
  781. }
  782. static int drm_mode_cursor_common(struct drm_device *dev,
  783. struct drm_mode_cursor2 *req,
  784. struct drm_file *file_priv)
  785. {
  786. struct drm_crtc *crtc;
  787. struct drm_modeset_acquire_ctx ctx;
  788. int ret = 0;
  789. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  790. return -EOPNOTSUPP;
  791. if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
  792. return -EINVAL;
  793. crtc = drm_crtc_find(dev, file_priv, req->crtc_id);
  794. if (!crtc) {
  795. DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
  796. return -ENOENT;
  797. }
  798. drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
  799. retry:
  800. ret = drm_modeset_lock(&crtc->mutex, &ctx);
  801. if (ret)
  802. goto out;
  803. /*
  804. * If this crtc has a universal cursor plane, call that plane's update
  805. * handler rather than using legacy cursor handlers.
  806. */
  807. if (crtc->cursor) {
  808. ret = drm_modeset_lock(&crtc->cursor->mutex, &ctx);
  809. if (ret)
  810. goto out;
  811. ret = drm_mode_cursor_universal(crtc, req, file_priv, &ctx);
  812. goto out;
  813. }
  814. if (req->flags & DRM_MODE_CURSOR_BO) {
  815. if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
  816. ret = -ENXIO;
  817. goto out;
  818. }
  819. /* Turns off the cursor if handle is 0 */
  820. if (crtc->funcs->cursor_set2)
  821. ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
  822. req->width, req->height, req->hot_x, req->hot_y);
  823. else
  824. ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
  825. req->width, req->height);
  826. }
  827. if (req->flags & DRM_MODE_CURSOR_MOVE) {
  828. if (crtc->funcs->cursor_move) {
  829. ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
  830. } else {
  831. ret = -EFAULT;
  832. goto out;
  833. }
  834. }
  835. out:
  836. if (ret == -EDEADLK) {
  837. ret = drm_modeset_backoff(&ctx);
  838. if (!ret)
  839. goto retry;
  840. }
  841. drm_modeset_drop_locks(&ctx);
  842. drm_modeset_acquire_fini(&ctx);
  843. return ret;
  844. }
  845. int drm_mode_cursor_ioctl(struct drm_device *dev,
  846. void *data, struct drm_file *file_priv)
  847. {
  848. struct drm_mode_cursor *req = data;
  849. struct drm_mode_cursor2 new_req;
  850. memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
  851. new_req.hot_x = new_req.hot_y = 0;
  852. return drm_mode_cursor_common(dev, &new_req, file_priv);
  853. }
  854. /*
  855. * Set the cursor configuration based on user request. This implements the 2nd
  856. * version of the cursor ioctl, which allows userspace to additionally specify
  857. * the hotspot of the pointer.
  858. */
  859. int drm_mode_cursor2_ioctl(struct drm_device *dev,
  860. void *data, struct drm_file *file_priv)
  861. {
  862. struct drm_mode_cursor2 *req = data;
  863. return drm_mode_cursor_common(dev, req, file_priv);
  864. }
  865. int drm_mode_page_flip_ioctl(struct drm_device *dev,
  866. void *data, struct drm_file *file_priv)
  867. {
  868. struct drm_mode_crtc_page_flip_target *page_flip = data;
  869. struct drm_crtc *crtc;
  870. struct drm_plane *plane;
  871. struct drm_framebuffer *fb = NULL, *old_fb;
  872. struct drm_pending_vblank_event *e = NULL;
  873. u32 target_vblank = page_flip->sequence;
  874. struct drm_modeset_acquire_ctx ctx;
  875. int ret = -EINVAL;
  876. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  877. return -EOPNOTSUPP;
  878. if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS)
  879. return -EINVAL;
  880. if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET))
  881. return -EINVAL;
  882. /* Only one of the DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags
  883. * can be specified
  884. */
  885. if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET)
  886. return -EINVAL;
  887. if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
  888. return -EINVAL;
  889. crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id);
  890. if (!crtc)
  891. return -ENOENT;
  892. plane = crtc->primary;
  893. if (crtc->funcs->page_flip_target) {
  894. u32 current_vblank;
  895. int r;
  896. r = drm_crtc_vblank_get(crtc);
  897. if (r)
  898. return r;
  899. current_vblank = (u32)drm_crtc_vblank_count(crtc);
  900. switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) {
  901. case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE:
  902. if ((int)(target_vblank - current_vblank) > 1) {
  903. DRM_DEBUG("Invalid absolute flip target %u, "
  904. "must be <= %u\n", target_vblank,
  905. current_vblank + 1);
  906. drm_crtc_vblank_put(crtc);
  907. return -EINVAL;
  908. }
  909. break;
  910. case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE:
  911. if (target_vblank != 0 && target_vblank != 1) {
  912. DRM_DEBUG("Invalid relative flip target %u, "
  913. "must be 0 or 1\n", target_vblank);
  914. drm_crtc_vblank_put(crtc);
  915. return -EINVAL;
  916. }
  917. target_vblank += current_vblank;
  918. break;
  919. default:
  920. target_vblank = current_vblank +
  921. !(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC);
  922. break;
  923. }
  924. } else if (crtc->funcs->page_flip == NULL ||
  925. (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) {
  926. return -EINVAL;
  927. }
  928. drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
  929. retry:
  930. ret = drm_modeset_lock(&crtc->mutex, &ctx);
  931. if (ret)
  932. goto out;
  933. ret = drm_modeset_lock(&plane->mutex, &ctx);
  934. if (ret)
  935. goto out;
  936. if (plane->state)
  937. old_fb = plane->state->fb;
  938. else
  939. old_fb = plane->fb;
  940. if (old_fb == NULL) {
  941. /* The framebuffer is currently unbound, presumably
  942. * due to a hotplug event, that userspace has not
  943. * yet discovered.
  944. */
  945. ret = -EBUSY;
  946. goto out;
  947. }
  948. fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
  949. if (!fb) {
  950. ret = -ENOENT;
  951. goto out;
  952. }
  953. if (plane->state) {
  954. const struct drm_plane_state *state = plane->state;
  955. ret = drm_framebuffer_check_src_coords(state->src_x,
  956. state->src_y,
  957. state->src_w,
  958. state->src_h,
  959. fb);
  960. } else {
  961. ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y,
  962. &crtc->mode, fb);
  963. }
  964. if (ret)
  965. goto out;
  966. if (old_fb->format != fb->format) {
  967. DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
  968. ret = -EINVAL;
  969. goto out;
  970. }
  971. if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
  972. e = kzalloc(sizeof *e, GFP_KERNEL);
  973. if (!e) {
  974. ret = -ENOMEM;
  975. goto out;
  976. }
  977. e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
  978. e->event.base.length = sizeof(e->event);
  979. e->event.vbl.user_data = page_flip->user_data;
  980. e->event.vbl.crtc_id = crtc->base.id;
  981. ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
  982. if (ret) {
  983. kfree(e);
  984. e = NULL;
  985. goto out;
  986. }
  987. }
  988. plane->old_fb = plane->fb;
  989. if (crtc->funcs->page_flip_target)
  990. ret = crtc->funcs->page_flip_target(crtc, fb, e,
  991. page_flip->flags,
  992. target_vblank,
  993. &ctx);
  994. else
  995. ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags,
  996. &ctx);
  997. if (ret) {
  998. if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
  999. drm_event_cancel_free(dev, &e->base);
  1000. /* Keep the old fb, don't unref it. */
  1001. plane->old_fb = NULL;
  1002. } else {
  1003. if (!plane->state) {
  1004. plane->fb = fb;
  1005. drm_framebuffer_get(fb);
  1006. }
  1007. }
  1008. out:
  1009. if (fb)
  1010. drm_framebuffer_put(fb);
  1011. if (plane->old_fb)
  1012. drm_framebuffer_put(plane->old_fb);
  1013. plane->old_fb = NULL;
  1014. if (ret == -EDEADLK) {
  1015. ret = drm_modeset_backoff(&ctx);
  1016. if (!ret)
  1017. goto retry;
  1018. }
  1019. drm_modeset_drop_locks(&ctx);
  1020. drm_modeset_acquire_fini(&ctx);
  1021. if (ret && crtc->funcs->page_flip_target)
  1022. drm_crtc_vblank_put(crtc);
  1023. return ret;
  1024. }