drm_gem_vram_helper.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. #include <linux/iosys-map.h>
  3. #include <linux/module.h>
  4. #include <drm/drm_debugfs.h>
  5. #include <drm/drm_device.h>
  6. #include <drm/drm_drv.h>
  7. #include <drm/drm_file.h>
  8. #include <drm/drm_framebuffer.h>
  9. #include <drm/drm_gem_atomic_helper.h>
  10. #include <drm/drm_gem_framebuffer_helper.h>
  11. #include <drm/drm_gem_ttm_helper.h>
  12. #include <drm/drm_gem_vram_helper.h>
  13. #include <drm/drm_managed.h>
  14. #include <drm/drm_mode.h>
  15. #include <drm/drm_plane.h>
  16. #include <drm/drm_prime.h>
  17. #include <drm/drm_simple_kms_helper.h>
  18. #include <drm/ttm/ttm_range_manager.h>
  19. #include <drm/ttm/ttm_tt.h>
  20. static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
  21. /**
  22. * DOC: overview
  23. *
  24. * This library provides &struct drm_gem_vram_object (GEM VRAM), a GEM
  25. * buffer object that is backed by video RAM (VRAM). It can be used for
  26. * framebuffer devices with dedicated memory.
  27. *
  28. * The data structure &struct drm_vram_mm and its helpers implement a memory
  29. * manager for simple framebuffer devices with dedicated video memory. GEM
  30. * VRAM buffer objects are either placed in the video memory or remain evicted
  31. * to system memory.
  32. *
  33. * With the GEM interface userspace applications create, manage and destroy
  34. * graphics buffers, such as an on-screen framebuffer. GEM does not provide
  35. * an implementation of these interfaces. It's up to the DRM driver to
  36. * provide an implementation that suits the hardware. If the hardware device
  37. * contains dedicated video memory, the DRM driver can use the VRAM helper
  38. * library. Each active buffer object is stored in video RAM. Active
  39. * buffer are used for drawing the current frame, typically something like
  40. * the frame's scanout buffer or the cursor image. If there's no more space
  41. * left in VRAM, inactive GEM objects can be moved to system memory.
  42. *
  43. * To initialize the VRAM helper library call drmm_vram_helper_init().
  44. * The function allocates and initializes an instance of &struct drm_vram_mm
  45. * in &struct drm_device.vram_mm . Use &DRM_GEM_VRAM_DRIVER to initialize
  46. * &struct drm_driver and &DRM_VRAM_MM_FILE_OPERATIONS to initialize
  47. * &struct file_operations; as illustrated below.
  48. *
  49. * .. code-block:: c
  50. *
  51. * struct file_operations fops ={
  52. * .owner = THIS_MODULE,
  53. * DRM_VRAM_MM_FILE_OPERATION
  54. * };
  55. * struct drm_driver drv = {
  56. * .driver_feature = DRM_ ... ,
  57. * .fops = &fops,
  58. * DRM_GEM_VRAM_DRIVER
  59. * };
  60. *
  61. * int init_drm_driver()
  62. * {
  63. * struct drm_device *dev;
  64. * uint64_t vram_base;
  65. * unsigned long vram_size;
  66. * int ret;
  67. *
  68. * // setup device, vram base and size
  69. * // ...
  70. *
  71. * ret = drmm_vram_helper_init(dev, vram_base, vram_size);
  72. * if (ret)
  73. * return ret;
  74. * return 0;
  75. * }
  76. *
  77. * This creates an instance of &struct drm_vram_mm, exports DRM userspace
  78. * interfaces for GEM buffer management and initializes file operations to
  79. * allow for accessing created GEM buffers. With this setup, the DRM driver
  80. * manages an area of video RAM with VRAM MM and provides GEM VRAM objects
  81. * to userspace.
  82. *
  83. * You don't have to clean up the instance of VRAM MM.
  84. * drmm_vram_helper_init() is a managed interface that installs a
  85. * clean-up handler to run during the DRM device's release.
  86. *
  87. * For drawing or scanout operations, rsp. buffer objects have to be pinned
  88. * in video RAM. Call drm_gem_vram_pin() with &DRM_GEM_VRAM_PL_FLAG_VRAM or
  89. * &DRM_GEM_VRAM_PL_FLAG_SYSTEM to pin a buffer object in video RAM or system
  90. * memory. Call drm_gem_vram_unpin() to release the pinned object afterwards.
  91. *
  92. * A buffer object that is pinned in video RAM has a fixed address within that
  93. * memory region. Call drm_gem_vram_offset() to retrieve this value. Typically
  94. * it's used to program the hardware's scanout engine for framebuffers, set
  95. * the cursor overlay's image for a mouse cursor, or use it as input to the
  96. * hardware's drawing engine.
  97. *
  98. * To access a buffer object's memory from the DRM driver, call
  99. * drm_gem_vram_vmap(). It maps the buffer into kernel address
  100. * space and returns the memory address. Use drm_gem_vram_vunmap() to
  101. * release the mapping.
  102. */
  103. /*
  104. * Buffer-objects helpers
  105. */
  106. static void drm_gem_vram_cleanup(struct drm_gem_vram_object *gbo)
  107. {
  108. /* We got here via ttm_bo_put(), which means that the
  109. * TTM buffer object in 'bo' has already been cleaned
  110. * up; only release the GEM object.
  111. */
  112. WARN_ON(gbo->vmap_use_count);
  113. WARN_ON(iosys_map_is_set(&gbo->map));
  114. drm_gem_object_release(&gbo->bo.base);
  115. }
  116. static void drm_gem_vram_destroy(struct drm_gem_vram_object *gbo)
  117. {
  118. drm_gem_vram_cleanup(gbo);
  119. kfree(gbo);
  120. }
  121. static void ttm_buffer_object_destroy(struct ttm_buffer_object *bo)
  122. {
  123. struct drm_gem_vram_object *gbo = drm_gem_vram_of_bo(bo);
  124. drm_gem_vram_destroy(gbo);
  125. }
  126. static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
  127. unsigned long pl_flag)
  128. {
  129. u32 invariant_flags = 0;
  130. unsigned int i;
  131. unsigned int c = 0;
  132. if (pl_flag & DRM_GEM_VRAM_PL_FLAG_TOPDOWN)
  133. invariant_flags = TTM_PL_FLAG_TOPDOWN;
  134. gbo->placement.placement = gbo->placements;
  135. if (pl_flag & DRM_GEM_VRAM_PL_FLAG_VRAM) {
  136. gbo->placements[c].mem_type = TTM_PL_VRAM;
  137. gbo->placements[c++].flags = invariant_flags;
  138. }
  139. if (pl_flag & DRM_GEM_VRAM_PL_FLAG_SYSTEM || !c) {
  140. gbo->placements[c].mem_type = TTM_PL_SYSTEM;
  141. gbo->placements[c++].flags = invariant_flags;
  142. }
  143. gbo->placement.num_placement = c;
  144. for (i = 0; i < c; ++i) {
  145. gbo->placements[i].fpfn = 0;
  146. gbo->placements[i].lpfn = 0;
  147. }
  148. }
  149. /**
  150. * drm_gem_vram_create() - Creates a VRAM-backed GEM object
  151. * @dev: the DRM device
  152. * @size: the buffer size in bytes
  153. * @pg_align: the buffer's alignment in multiples of the page size
  154. *
  155. * GEM objects are allocated by calling struct drm_driver.gem_create_object,
  156. * if set. Otherwise kzalloc() will be used. Drivers can set their own GEM
  157. * object functions in struct drm_driver.gem_create_object. If no functions
  158. * are set, the new GEM object will use the default functions from GEM VRAM
  159. * helpers.
  160. *
  161. * Returns:
  162. * A new instance of &struct drm_gem_vram_object on success, or
  163. * an ERR_PTR()-encoded error code otherwise.
  164. */
  165. struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
  166. size_t size,
  167. unsigned long pg_align)
  168. {
  169. struct drm_gem_vram_object *gbo;
  170. struct drm_gem_object *gem;
  171. struct drm_vram_mm *vmm = dev->vram_mm;
  172. struct ttm_device *bdev;
  173. int ret;
  174. if (WARN_ONCE(!vmm, "VRAM MM not initialized"))
  175. return ERR_PTR(-EINVAL);
  176. if (dev->driver->gem_create_object) {
  177. gem = dev->driver->gem_create_object(dev, size);
  178. if (IS_ERR(gem))
  179. return ERR_CAST(gem);
  180. gbo = drm_gem_vram_of_gem(gem);
  181. } else {
  182. gbo = kzalloc(sizeof(*gbo), GFP_KERNEL);
  183. if (!gbo)
  184. return ERR_PTR(-ENOMEM);
  185. gem = &gbo->bo.base;
  186. }
  187. if (!gem->funcs)
  188. gem->funcs = &drm_gem_vram_object_funcs;
  189. ret = drm_gem_object_init(dev, gem, size);
  190. if (ret) {
  191. kfree(gbo);
  192. return ERR_PTR(ret);
  193. }
  194. bdev = &vmm->bdev;
  195. gbo->bo.bdev = bdev;
  196. drm_gem_vram_placement(gbo, DRM_GEM_VRAM_PL_FLAG_SYSTEM);
  197. /*
  198. * A failing ttm_bo_init will call ttm_buffer_object_destroy
  199. * to release gbo->bo.base and kfree gbo.
  200. */
  201. ret = ttm_bo_init_validate(bdev, &gbo->bo, ttm_bo_type_device,
  202. &gbo->placement, pg_align, false, NULL, NULL,
  203. ttm_buffer_object_destroy);
  204. if (ret)
  205. return ERR_PTR(ret);
  206. return gbo;
  207. }
  208. EXPORT_SYMBOL(drm_gem_vram_create);
  209. /**
  210. * drm_gem_vram_put() - Releases a reference to a VRAM-backed GEM object
  211. * @gbo: the GEM VRAM object
  212. *
  213. * See ttm_bo_put() for more information.
  214. */
  215. void drm_gem_vram_put(struct drm_gem_vram_object *gbo)
  216. {
  217. ttm_bo_put(&gbo->bo);
  218. }
  219. EXPORT_SYMBOL(drm_gem_vram_put);
  220. static u64 drm_gem_vram_pg_offset(struct drm_gem_vram_object *gbo)
  221. {
  222. /* Keep TTM behavior for now, remove when drivers are audited */
  223. if (WARN_ON_ONCE(!gbo->bo.resource ||
  224. gbo->bo.resource->mem_type == TTM_PL_SYSTEM))
  225. return 0;
  226. return gbo->bo.resource->start;
  227. }
  228. /**
  229. * drm_gem_vram_offset() - Returns a GEM VRAM object's offset in video memory
  230. * @gbo: the GEM VRAM object
  231. *
  232. * This function returns the buffer object's offset in the device's video
  233. * memory. The buffer object has to be pinned to %TTM_PL_VRAM.
  234. *
  235. * Returns:
  236. * The buffer object's offset in video memory on success, or
  237. * a negative errno code otherwise.
  238. */
  239. s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo)
  240. {
  241. if (WARN_ON_ONCE(!gbo->bo.pin_count))
  242. return (s64)-ENODEV;
  243. return drm_gem_vram_pg_offset(gbo) << PAGE_SHIFT;
  244. }
  245. EXPORT_SYMBOL(drm_gem_vram_offset);
  246. static int drm_gem_vram_pin_locked(struct drm_gem_vram_object *gbo,
  247. unsigned long pl_flag)
  248. {
  249. struct ttm_operation_ctx ctx = { false, false };
  250. int ret;
  251. dma_resv_assert_held(gbo->bo.base.resv);
  252. if (gbo->bo.pin_count)
  253. goto out;
  254. if (pl_flag)
  255. drm_gem_vram_placement(gbo, pl_flag);
  256. ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
  257. if (ret < 0)
  258. return ret;
  259. out:
  260. ttm_bo_pin(&gbo->bo);
  261. return 0;
  262. }
  263. /**
  264. * drm_gem_vram_pin() - Pins a GEM VRAM object in a region.
  265. * @gbo: the GEM VRAM object
  266. * @pl_flag: a bitmask of possible memory regions
  267. *
  268. * Pinning a buffer object ensures that it is not evicted from
  269. * a memory region. A pinned buffer object has to be unpinned before
  270. * it can be pinned to another region. If the pl_flag argument is 0,
  271. * the buffer is pinned at its current location (video RAM or system
  272. * memory).
  273. *
  274. * Small buffer objects, such as cursor images, can lead to memory
  275. * fragmentation if they are pinned in the middle of video RAM. This
  276. * is especially a problem on devices with only a small amount of
  277. * video RAM. Fragmentation can prevent the primary framebuffer from
  278. * fitting in, even though there's enough memory overall. The modifier
  279. * DRM_GEM_VRAM_PL_FLAG_TOPDOWN marks the buffer object to be pinned
  280. * at the high end of the memory region to avoid fragmentation.
  281. *
  282. * Returns:
  283. * 0 on success, or
  284. * a negative error code otherwise.
  285. */
  286. int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag)
  287. {
  288. int ret;
  289. ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
  290. if (ret)
  291. return ret;
  292. ret = drm_gem_vram_pin_locked(gbo, pl_flag);
  293. ttm_bo_unreserve(&gbo->bo);
  294. return ret;
  295. }
  296. EXPORT_SYMBOL(drm_gem_vram_pin);
  297. static void drm_gem_vram_unpin_locked(struct drm_gem_vram_object *gbo)
  298. {
  299. dma_resv_assert_held(gbo->bo.base.resv);
  300. ttm_bo_unpin(&gbo->bo);
  301. }
  302. /**
  303. * drm_gem_vram_unpin() - Unpins a GEM VRAM object
  304. * @gbo: the GEM VRAM object
  305. *
  306. * Returns:
  307. * 0 on success, or
  308. * a negative error code otherwise.
  309. */
  310. int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
  311. {
  312. int ret;
  313. ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
  314. if (ret)
  315. return ret;
  316. drm_gem_vram_unpin_locked(gbo);
  317. ttm_bo_unreserve(&gbo->bo);
  318. return 0;
  319. }
  320. EXPORT_SYMBOL(drm_gem_vram_unpin);
  321. /**
  322. * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
  323. * space
  324. * @gbo: The GEM VRAM object to map
  325. * @map: Returns the kernel virtual address of the VRAM GEM object's backing
  326. * store.
  327. *
  328. * The vmap function pins a GEM VRAM object to its current location, either
  329. * system or video memory, and maps its buffer into kernel address space.
  330. * As pinned object cannot be relocated, you should avoid pinning objects
  331. * permanently. Call drm_gem_vram_vunmap() with the returned address to
  332. * unmap and unpin the GEM VRAM object.
  333. *
  334. * Returns:
  335. * 0 on success, or a negative error code otherwise.
  336. */
  337. int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct iosys_map *map)
  338. {
  339. int ret;
  340. dma_resv_assert_held(gbo->bo.base.resv);
  341. if (gbo->vmap_use_count > 0)
  342. goto out;
  343. /*
  344. * VRAM helpers unmap the BO only on demand. So the previous
  345. * page mapping might still be around. Only vmap if the there's
  346. * no mapping present.
  347. */
  348. if (iosys_map_is_null(&gbo->map)) {
  349. ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
  350. if (ret)
  351. return ret;
  352. }
  353. out:
  354. ++gbo->vmap_use_count;
  355. *map = gbo->map;
  356. return 0;
  357. }
  358. EXPORT_SYMBOL(drm_gem_vram_vmap);
  359. /**
  360. * drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
  361. * @gbo: The GEM VRAM object to unmap
  362. * @map: Kernel virtual address where the VRAM GEM object was mapped
  363. *
  364. * A call to drm_gem_vram_vunmap() unmaps and unpins a GEM VRAM buffer. See
  365. * the documentation for drm_gem_vram_vmap() for more information.
  366. */
  367. void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo,
  368. struct iosys_map *map)
  369. {
  370. struct drm_device *dev = gbo->bo.base.dev;
  371. dma_resv_assert_held(gbo->bo.base.resv);
  372. if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count))
  373. return;
  374. if (drm_WARN_ON_ONCE(dev, !iosys_map_is_equal(&gbo->map, map)))
  375. return; /* BUG: map not mapped from this BO */
  376. if (--gbo->vmap_use_count > 0)
  377. return;
  378. /*
  379. * Permanently mapping and unmapping buffers adds overhead from
  380. * updating the page tables and creates debugging output. Therefore,
  381. * we delay the actual unmap operation until the BO gets evicted
  382. * from memory. See drm_gem_vram_bo_driver_move_notify().
  383. */
  384. }
  385. EXPORT_SYMBOL(drm_gem_vram_vunmap);
  386. /**
  387. * drm_gem_vram_fill_create_dumb() - Helper for implementing
  388. * &struct drm_driver.dumb_create
  389. *
  390. * @file: the DRM file
  391. * @dev: the DRM device
  392. * @pg_align: the buffer's alignment in multiples of the page size
  393. * @pitch_align: the scanline's alignment in powers of 2
  394. * @args: the arguments as provided to
  395. * &struct drm_driver.dumb_create
  396. *
  397. * This helper function fills &struct drm_mode_create_dumb, which is used
  398. * by &struct drm_driver.dumb_create. Implementations of this interface
  399. * should forwards their arguments to this helper, plus the driver-specific
  400. * parameters.
  401. *
  402. * Returns:
  403. * 0 on success, or
  404. * a negative error code otherwise.
  405. */
  406. int drm_gem_vram_fill_create_dumb(struct drm_file *file,
  407. struct drm_device *dev,
  408. unsigned long pg_align,
  409. unsigned long pitch_align,
  410. struct drm_mode_create_dumb *args)
  411. {
  412. size_t pitch, size;
  413. struct drm_gem_vram_object *gbo;
  414. int ret;
  415. u32 handle;
  416. pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
  417. if (pitch_align) {
  418. if (WARN_ON_ONCE(!is_power_of_2(pitch_align)))
  419. return -EINVAL;
  420. pitch = ALIGN(pitch, pitch_align);
  421. }
  422. size = pitch * args->height;
  423. size = roundup(size, PAGE_SIZE);
  424. if (!size)
  425. return -EINVAL;
  426. gbo = drm_gem_vram_create(dev, size, pg_align);
  427. if (IS_ERR(gbo))
  428. return PTR_ERR(gbo);
  429. ret = drm_gem_handle_create(file, &gbo->bo.base, &handle);
  430. if (ret)
  431. goto err_drm_gem_object_put;
  432. drm_gem_object_put(&gbo->bo.base);
  433. args->pitch = pitch;
  434. args->size = size;
  435. args->handle = handle;
  436. return 0;
  437. err_drm_gem_object_put:
  438. drm_gem_object_put(&gbo->bo.base);
  439. return ret;
  440. }
  441. EXPORT_SYMBOL(drm_gem_vram_fill_create_dumb);
  442. /*
  443. * Helpers for struct ttm_device_funcs
  444. */
  445. static bool drm_is_gem_vram(struct ttm_buffer_object *bo)
  446. {
  447. return (bo->destroy == ttm_buffer_object_destroy);
  448. }
  449. static void drm_gem_vram_bo_driver_evict_flags(struct drm_gem_vram_object *gbo,
  450. struct ttm_placement *pl)
  451. {
  452. drm_gem_vram_placement(gbo, DRM_GEM_VRAM_PL_FLAG_SYSTEM);
  453. *pl = gbo->placement;
  454. }
  455. static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo)
  456. {
  457. struct ttm_buffer_object *bo = &gbo->bo;
  458. struct drm_device *dev = bo->base.dev;
  459. if (drm_WARN_ON_ONCE(dev, gbo->vmap_use_count))
  460. return;
  461. ttm_bo_vunmap(bo, &gbo->map);
  462. iosys_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */
  463. }
  464. static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo,
  465. bool evict,
  466. struct ttm_operation_ctx *ctx,
  467. struct ttm_resource *new_mem)
  468. {
  469. drm_gem_vram_bo_driver_move_notify(gbo);
  470. return ttm_bo_move_memcpy(&gbo->bo, ctx, new_mem);
  471. }
  472. /*
  473. * Helpers for struct drm_gem_object_funcs
  474. */
  475. /**
  476. * drm_gem_vram_object_free() - Implements &struct drm_gem_object_funcs.free
  477. * @gem: GEM object. Refers to &struct drm_gem_vram_object.gem
  478. */
  479. static void drm_gem_vram_object_free(struct drm_gem_object *gem)
  480. {
  481. struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
  482. drm_gem_vram_put(gbo);
  483. }
  484. /*
  485. * Helpers for dump buffers
  486. */
  487. /**
  488. * drm_gem_vram_driver_dumb_create() - Implements &struct drm_driver.dumb_create
  489. * @file: the DRM file
  490. * @dev: the DRM device
  491. * @args: the arguments as provided to
  492. * &struct drm_driver.dumb_create
  493. *
  494. * This function requires the driver to use @drm_device.vram_mm for its
  495. * instance of VRAM MM.
  496. *
  497. * Returns:
  498. * 0 on success, or
  499. * a negative error code otherwise.
  500. */
  501. int drm_gem_vram_driver_dumb_create(struct drm_file *file,
  502. struct drm_device *dev,
  503. struct drm_mode_create_dumb *args)
  504. {
  505. if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
  506. return -EINVAL;
  507. return drm_gem_vram_fill_create_dumb(file, dev, 0, 0, args);
  508. }
  509. EXPORT_SYMBOL(drm_gem_vram_driver_dumb_create);
  510. /*
  511. * Helpers for struct drm_plane_helper_funcs
  512. */
  513. static void __drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane,
  514. struct drm_plane_state *state,
  515. unsigned int num_planes)
  516. {
  517. struct drm_gem_object *obj;
  518. struct drm_gem_vram_object *gbo;
  519. struct drm_framebuffer *fb = state->fb;
  520. while (num_planes) {
  521. --num_planes;
  522. obj = drm_gem_fb_get_obj(fb, num_planes);
  523. if (!obj)
  524. continue;
  525. gbo = drm_gem_vram_of_gem(obj);
  526. drm_gem_vram_unpin(gbo);
  527. }
  528. }
  529. /**
  530. * drm_gem_vram_plane_helper_prepare_fb() - Implements &struct
  531. * drm_plane_helper_funcs.prepare_fb
  532. * @plane: a DRM plane
  533. * @new_state: the plane's new state
  534. *
  535. * During plane updates, this function sets the plane's fence and
  536. * pins the GEM VRAM objects of the plane's new framebuffer to VRAM.
  537. * Call drm_gem_vram_plane_helper_cleanup_fb() to unpin them.
  538. *
  539. * Returns:
  540. * 0 on success, or
  541. * a negative errno code otherwise.
  542. */
  543. int
  544. drm_gem_vram_plane_helper_prepare_fb(struct drm_plane *plane,
  545. struct drm_plane_state *new_state)
  546. {
  547. struct drm_framebuffer *fb = new_state->fb;
  548. struct drm_gem_vram_object *gbo;
  549. struct drm_gem_object *obj;
  550. unsigned int i;
  551. int ret;
  552. if (!fb)
  553. return 0;
  554. for (i = 0; i < fb->format->num_planes; ++i) {
  555. obj = drm_gem_fb_get_obj(fb, i);
  556. if (!obj) {
  557. ret = -EINVAL;
  558. goto err_drm_gem_vram_unpin;
  559. }
  560. gbo = drm_gem_vram_of_gem(obj);
  561. ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
  562. if (ret)
  563. goto err_drm_gem_vram_unpin;
  564. }
  565. ret = drm_gem_plane_helper_prepare_fb(plane, new_state);
  566. if (ret)
  567. goto err_drm_gem_vram_unpin;
  568. return 0;
  569. err_drm_gem_vram_unpin:
  570. __drm_gem_vram_plane_helper_cleanup_fb(plane, new_state, i);
  571. return ret;
  572. }
  573. EXPORT_SYMBOL(drm_gem_vram_plane_helper_prepare_fb);
  574. /**
  575. * drm_gem_vram_plane_helper_cleanup_fb() - Implements &struct
  576. * drm_plane_helper_funcs.cleanup_fb
  577. * @plane: a DRM plane
  578. * @old_state: the plane's old state
  579. *
  580. * During plane updates, this function unpins the GEM VRAM
  581. * objects of the plane's old framebuffer from VRAM. Complements
  582. * drm_gem_vram_plane_helper_prepare_fb().
  583. */
  584. void
  585. drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane,
  586. struct drm_plane_state *old_state)
  587. {
  588. struct drm_framebuffer *fb = old_state->fb;
  589. if (!fb)
  590. return;
  591. __drm_gem_vram_plane_helper_cleanup_fb(plane, old_state, fb->format->num_planes);
  592. }
  593. EXPORT_SYMBOL(drm_gem_vram_plane_helper_cleanup_fb);
  594. /*
  595. * Helpers for struct drm_simple_display_pipe_funcs
  596. */
  597. /**
  598. * drm_gem_vram_simple_display_pipe_prepare_fb() - Implements &struct
  599. * drm_simple_display_pipe_funcs.prepare_fb
  600. * @pipe: a simple display pipe
  601. * @new_state: the plane's new state
  602. *
  603. * During plane updates, this function pins the GEM VRAM
  604. * objects of the plane's new framebuffer to VRAM. Call
  605. * drm_gem_vram_simple_display_pipe_cleanup_fb() to unpin them.
  606. *
  607. * Returns:
  608. * 0 on success, or
  609. * a negative errno code otherwise.
  610. */
  611. int drm_gem_vram_simple_display_pipe_prepare_fb(
  612. struct drm_simple_display_pipe *pipe,
  613. struct drm_plane_state *new_state)
  614. {
  615. return drm_gem_vram_plane_helper_prepare_fb(&pipe->plane, new_state);
  616. }
  617. EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_prepare_fb);
  618. /**
  619. * drm_gem_vram_simple_display_pipe_cleanup_fb() - Implements &struct
  620. * drm_simple_display_pipe_funcs.cleanup_fb
  621. * @pipe: a simple display pipe
  622. * @old_state: the plane's old state
  623. *
  624. * During plane updates, this function unpins the GEM VRAM
  625. * objects of the plane's old framebuffer from VRAM. Complements
  626. * drm_gem_vram_simple_display_pipe_prepare_fb().
  627. */
  628. void drm_gem_vram_simple_display_pipe_cleanup_fb(
  629. struct drm_simple_display_pipe *pipe,
  630. struct drm_plane_state *old_state)
  631. {
  632. drm_gem_vram_plane_helper_cleanup_fb(&pipe->plane, old_state);
  633. }
  634. EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_cleanup_fb);
  635. /*
  636. * PRIME helpers
  637. */
  638. /**
  639. * drm_gem_vram_object_pin() - Implements &struct drm_gem_object_funcs.pin
  640. * @gem: The GEM object to pin
  641. *
  642. * Returns:
  643. * 0 on success, or
  644. * a negative errno code otherwise.
  645. */
  646. static int drm_gem_vram_object_pin(struct drm_gem_object *gem)
  647. {
  648. struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
  649. /*
  650. * Fbdev console emulation is the use case of these PRIME
  651. * helpers. This may involve updating a hardware buffer from
  652. * a shadow FB. We pin the buffer to it's current location
  653. * (either video RAM or system memory) to prevent it from
  654. * being relocated during the update operation. If you require
  655. * the buffer to be pinned to VRAM, implement a callback that
  656. * sets the flags accordingly.
  657. */
  658. return drm_gem_vram_pin_locked(gbo, 0);
  659. }
  660. /**
  661. * drm_gem_vram_object_unpin() - Implements &struct drm_gem_object_funcs.unpin
  662. * @gem: The GEM object to unpin
  663. */
  664. static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
  665. {
  666. struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
  667. drm_gem_vram_unpin_locked(gbo);
  668. }
  669. /**
  670. * drm_gem_vram_object_vmap() -
  671. * Implements &struct drm_gem_object_funcs.vmap
  672. * @gem: The GEM object to map
  673. * @map: Returns the kernel virtual address of the VRAM GEM object's backing
  674. * store.
  675. *
  676. * Returns:
  677. * 0 on success, or a negative error code otherwise.
  678. */
  679. static int drm_gem_vram_object_vmap(struct drm_gem_object *gem,
  680. struct iosys_map *map)
  681. {
  682. struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
  683. return drm_gem_vram_vmap(gbo, map);
  684. }
  685. /**
  686. * drm_gem_vram_object_vunmap() -
  687. * Implements &struct drm_gem_object_funcs.vunmap
  688. * @gem: The GEM object to unmap
  689. * @map: Kernel virtual address where the VRAM GEM object was mapped
  690. */
  691. static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem,
  692. struct iosys_map *map)
  693. {
  694. struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
  695. drm_gem_vram_vunmap(gbo, map);
  696. }
  697. /*
  698. * GEM object funcs
  699. */
  700. static const struct drm_gem_object_funcs drm_gem_vram_object_funcs = {
  701. .free = drm_gem_vram_object_free,
  702. .pin = drm_gem_vram_object_pin,
  703. .unpin = drm_gem_vram_object_unpin,
  704. .vmap = drm_gem_vram_object_vmap,
  705. .vunmap = drm_gem_vram_object_vunmap,
  706. .mmap = drm_gem_ttm_mmap,
  707. .print_info = drm_gem_ttm_print_info,
  708. };
  709. /*
  710. * VRAM memory manager
  711. */
  712. /*
  713. * TTM TT
  714. */
  715. static void bo_driver_ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *tt)
  716. {
  717. ttm_tt_fini(tt);
  718. kfree(tt);
  719. }
  720. /*
  721. * TTM BO device
  722. */
  723. static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo,
  724. uint32_t page_flags)
  725. {
  726. struct ttm_tt *tt;
  727. int ret;
  728. tt = kzalloc(sizeof(*tt), GFP_KERNEL);
  729. if (!tt)
  730. return NULL;
  731. ret = ttm_tt_init(tt, bo, page_flags, ttm_cached, 0);
  732. if (ret < 0)
  733. goto err_ttm_tt_init;
  734. return tt;
  735. err_ttm_tt_init:
  736. kfree(tt);
  737. return NULL;
  738. }
  739. static void bo_driver_evict_flags(struct ttm_buffer_object *bo,
  740. struct ttm_placement *placement)
  741. {
  742. struct drm_gem_vram_object *gbo;
  743. /* TTM may pass BOs that are not GEM VRAM BOs. */
  744. if (!drm_is_gem_vram(bo))
  745. return;
  746. gbo = drm_gem_vram_of_bo(bo);
  747. drm_gem_vram_bo_driver_evict_flags(gbo, placement);
  748. }
  749. static void bo_driver_delete_mem_notify(struct ttm_buffer_object *bo)
  750. {
  751. struct drm_gem_vram_object *gbo;
  752. /* TTM may pass BOs that are not GEM VRAM BOs. */
  753. if (!drm_is_gem_vram(bo))
  754. return;
  755. gbo = drm_gem_vram_of_bo(bo);
  756. drm_gem_vram_bo_driver_move_notify(gbo);
  757. }
  758. static int bo_driver_move(struct ttm_buffer_object *bo,
  759. bool evict,
  760. struct ttm_operation_ctx *ctx,
  761. struct ttm_resource *new_mem,
  762. struct ttm_place *hop)
  763. {
  764. struct drm_gem_vram_object *gbo;
  765. if (!bo->resource) {
  766. if (new_mem->mem_type != TTM_PL_SYSTEM) {
  767. hop->mem_type = TTM_PL_SYSTEM;
  768. hop->flags = TTM_PL_FLAG_TEMPORARY;
  769. return -EMULTIHOP;
  770. }
  771. ttm_bo_move_null(bo, new_mem);
  772. return 0;
  773. }
  774. gbo = drm_gem_vram_of_bo(bo);
  775. return drm_gem_vram_bo_driver_move(gbo, evict, ctx, new_mem);
  776. }
  777. static int bo_driver_io_mem_reserve(struct ttm_device *bdev,
  778. struct ttm_resource *mem)
  779. {
  780. struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bdev);
  781. switch (mem->mem_type) {
  782. case TTM_PL_SYSTEM: /* nothing to do */
  783. break;
  784. case TTM_PL_VRAM:
  785. mem->bus.offset = (mem->start << PAGE_SHIFT) + vmm->vram_base;
  786. mem->bus.is_iomem = true;
  787. mem->bus.caching = ttm_write_combined;
  788. break;
  789. default:
  790. return -EINVAL;
  791. }
  792. return 0;
  793. }
  794. static struct ttm_device_funcs bo_driver = {
  795. .ttm_tt_create = bo_driver_ttm_tt_create,
  796. .ttm_tt_destroy = bo_driver_ttm_tt_destroy,
  797. .eviction_valuable = ttm_bo_eviction_valuable,
  798. .evict_flags = bo_driver_evict_flags,
  799. .move = bo_driver_move,
  800. .delete_mem_notify = bo_driver_delete_mem_notify,
  801. .io_mem_reserve = bo_driver_io_mem_reserve,
  802. };
  803. /*
  804. * struct drm_vram_mm
  805. */
  806. static int drm_vram_mm_debugfs(struct seq_file *m, void *data)
  807. {
  808. struct drm_debugfs_entry *entry = m->private;
  809. struct drm_vram_mm *vmm = entry->dev->vram_mm;
  810. struct ttm_resource_manager *man = ttm_manager_type(&vmm->bdev, TTM_PL_VRAM);
  811. struct drm_printer p = drm_seq_file_printer(m);
  812. ttm_resource_manager_debug(man, &p);
  813. return 0;
  814. }
  815. static const struct drm_debugfs_info drm_vram_mm_debugfs_list[] = {
  816. { "vram-mm", drm_vram_mm_debugfs, 0, NULL },
  817. };
  818. /**
  819. * drm_vram_mm_debugfs_init() - Register VRAM MM debugfs file.
  820. *
  821. * @minor: drm minor device.
  822. *
  823. */
  824. void drm_vram_mm_debugfs_init(struct drm_minor *minor)
  825. {
  826. drm_debugfs_add_files(minor->dev, drm_vram_mm_debugfs_list,
  827. ARRAY_SIZE(drm_vram_mm_debugfs_list));
  828. }
  829. EXPORT_SYMBOL(drm_vram_mm_debugfs_init);
  830. static int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
  831. uint64_t vram_base, size_t vram_size)
  832. {
  833. int ret;
  834. vmm->vram_base = vram_base;
  835. vmm->vram_size = vram_size;
  836. ret = ttm_device_init(&vmm->bdev, &bo_driver, dev->dev,
  837. dev->anon_inode->i_mapping,
  838. dev->vma_offset_manager,
  839. false, true);
  840. if (ret)
  841. return ret;
  842. ret = ttm_range_man_init(&vmm->bdev, TTM_PL_VRAM,
  843. false, vram_size >> PAGE_SHIFT);
  844. if (ret)
  845. return ret;
  846. return 0;
  847. }
  848. static void drm_vram_mm_cleanup(struct drm_vram_mm *vmm)
  849. {
  850. ttm_range_man_fini(&vmm->bdev, TTM_PL_VRAM);
  851. ttm_device_fini(&vmm->bdev);
  852. }
  853. /*
  854. * Helpers for integration with struct drm_device
  855. */
  856. static struct drm_vram_mm *drm_vram_helper_alloc_mm(struct drm_device *dev, uint64_t vram_base,
  857. size_t vram_size)
  858. {
  859. int ret;
  860. if (WARN_ON(dev->vram_mm))
  861. return dev->vram_mm;
  862. dev->vram_mm = kzalloc(sizeof(*dev->vram_mm), GFP_KERNEL);
  863. if (!dev->vram_mm)
  864. return ERR_PTR(-ENOMEM);
  865. ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size);
  866. if (ret)
  867. goto err_kfree;
  868. return dev->vram_mm;
  869. err_kfree:
  870. kfree(dev->vram_mm);
  871. dev->vram_mm = NULL;
  872. return ERR_PTR(ret);
  873. }
  874. static void drm_vram_helper_release_mm(struct drm_device *dev)
  875. {
  876. if (!dev->vram_mm)
  877. return;
  878. drm_vram_mm_cleanup(dev->vram_mm);
  879. kfree(dev->vram_mm);
  880. dev->vram_mm = NULL;
  881. }
  882. static void drm_vram_mm_release(struct drm_device *dev, void *ptr)
  883. {
  884. drm_vram_helper_release_mm(dev);
  885. }
  886. /**
  887. * drmm_vram_helper_init - Initializes a device's instance of
  888. * &struct drm_vram_mm
  889. * @dev: the DRM device
  890. * @vram_base: the base address of the video memory
  891. * @vram_size: the size of the video memory in bytes
  892. *
  893. * Creates a new instance of &struct drm_vram_mm and stores it in
  894. * struct &drm_device.vram_mm. The instance is auto-managed and cleaned
  895. * up as part of device cleanup. Calling this function multiple times
  896. * will generate an error message.
  897. *
  898. * Returns:
  899. * 0 on success, or a negative errno code otherwise.
  900. */
  901. int drmm_vram_helper_init(struct drm_device *dev, uint64_t vram_base,
  902. size_t vram_size)
  903. {
  904. struct drm_vram_mm *vram_mm;
  905. if (drm_WARN_ON_ONCE(dev, dev->vram_mm))
  906. return 0;
  907. vram_mm = drm_vram_helper_alloc_mm(dev, vram_base, vram_size);
  908. if (IS_ERR(vram_mm))
  909. return PTR_ERR(vram_mm);
  910. return drmm_add_action_or_reset(dev, drm_vram_mm_release, NULL);
  911. }
  912. EXPORT_SYMBOL(drmm_vram_helper_init);
  913. /*
  914. * Mode-config helpers
  915. */
  916. static enum drm_mode_status
  917. drm_vram_helper_mode_valid_internal(struct drm_device *dev,
  918. const struct drm_display_mode *mode,
  919. unsigned long max_bpp)
  920. {
  921. struct drm_vram_mm *vmm = dev->vram_mm;
  922. unsigned long fbsize, fbpages, max_fbpages;
  923. if (WARN_ON(!dev->vram_mm))
  924. return MODE_BAD;
  925. max_fbpages = (vmm->vram_size / 2) >> PAGE_SHIFT;
  926. fbsize = mode->hdisplay * mode->vdisplay * max_bpp;
  927. fbpages = DIV_ROUND_UP(fbsize, PAGE_SIZE);
  928. if (fbpages > max_fbpages)
  929. return MODE_MEM;
  930. return MODE_OK;
  931. }
  932. /**
  933. * drm_vram_helper_mode_valid - Tests if a display mode's
  934. * framebuffer fits into the available video memory.
  935. * @dev: the DRM device
  936. * @mode: the mode to test
  937. *
  938. * This function tests if enough video memory is available for using the
  939. * specified display mode. Atomic modesetting requires importing the
  940. * designated framebuffer into video memory before evicting the active
  941. * one. Hence, any framebuffer may consume at most half of the available
  942. * VRAM. Display modes that require a larger framebuffer can not be used,
  943. * even if the CRTC does support them. Each framebuffer is assumed to
  944. * have 32-bit color depth.
  945. *
  946. * Note:
  947. * The function can only test if the display mode is supported in
  948. * general. If there are too many framebuffers pinned to video memory,
  949. * a display mode may still not be usable in practice. The color depth of
  950. * 32-bit fits all current use case. A more flexible test can be added
  951. * when necessary.
  952. *
  953. * Returns:
  954. * MODE_OK if the display mode is supported, or an error code of type
  955. * enum drm_mode_status otherwise.
  956. */
  957. enum drm_mode_status
  958. drm_vram_helper_mode_valid(struct drm_device *dev,
  959. const struct drm_display_mode *mode)
  960. {
  961. static const unsigned long max_bpp = 4; /* DRM_FORMAT_XRGB8888 */
  962. return drm_vram_helper_mode_valid_internal(dev, mode, max_bpp);
  963. }
  964. EXPORT_SYMBOL(drm_vram_helper_mode_valid);
  965. MODULE_DESCRIPTION("DRM VRAM memory-management helpers");
  966. MODULE_LICENSE("GPL");