18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#ifndef DRM_GEM_VRAM_HELPER_H
48c2ecf20Sopenharmony_ci#define DRM_GEM_VRAM_HELPER_H
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <drm/drm_file.h>
78c2ecf20Sopenharmony_ci#include <drm/drm_gem.h>
88c2ecf20Sopenharmony_ci#include <drm/drm_ioctl.h>
98c2ecf20Sopenharmony_ci#include <drm/drm_modes.h>
108c2ecf20Sopenharmony_ci#include <drm/ttm/ttm_bo_api.h>
118c2ecf20Sopenharmony_ci#include <drm/ttm/ttm_bo_driver.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/kernel.h> /* for container_of() */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistruct drm_mode_create_dumb;
168c2ecf20Sopenharmony_cistruct drm_plane;
178c2ecf20Sopenharmony_cistruct drm_plane_state;
188c2ecf20Sopenharmony_cistruct drm_simple_display_pipe;
198c2ecf20Sopenharmony_cistruct filp;
208c2ecf20Sopenharmony_cistruct vm_area_struct;
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#define DRM_GEM_VRAM_PL_FLAG_SYSTEM	(1 << 0)
238c2ecf20Sopenharmony_ci#define DRM_GEM_VRAM_PL_FLAG_VRAM	(1 << 1)
248c2ecf20Sopenharmony_ci#define DRM_GEM_VRAM_PL_FLAG_TOPDOWN	(1 << 2)
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/*
278c2ecf20Sopenharmony_ci * Buffer-object helpers
288c2ecf20Sopenharmony_ci */
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/**
318c2ecf20Sopenharmony_ci * struct drm_gem_vram_object - GEM object backed by VRAM
328c2ecf20Sopenharmony_ci * @gem:	GEM object
338c2ecf20Sopenharmony_ci * @bo:		TTM buffer object
348c2ecf20Sopenharmony_ci * @kmap:	Mapping information for @bo
358c2ecf20Sopenharmony_ci * @placement:	TTM placement information. Supported placements are \
368c2ecf20Sopenharmony_ci	%TTM_PL_VRAM and %TTM_PL_SYSTEM
378c2ecf20Sopenharmony_ci * @placements:	TTM placement information.
388c2ecf20Sopenharmony_ci * @pin_count:	Pin counter
398c2ecf20Sopenharmony_ci *
408c2ecf20Sopenharmony_ci * The type struct drm_gem_vram_object represents a GEM object that is
418c2ecf20Sopenharmony_ci * backed by VRAM. It can be used for simple framebuffer devices with
428c2ecf20Sopenharmony_ci * dedicated memory. The buffer object can be evicted to system memory if
438c2ecf20Sopenharmony_ci * video memory becomes scarce.
448c2ecf20Sopenharmony_ci *
458c2ecf20Sopenharmony_ci * GEM VRAM objects perform reference counting for pin and mapping
468c2ecf20Sopenharmony_ci * operations. So a buffer object that has been pinned N times with
478c2ecf20Sopenharmony_ci * drm_gem_vram_pin() must be unpinned N times with
488c2ecf20Sopenharmony_ci * drm_gem_vram_unpin(). The same applies to pairs of
498c2ecf20Sopenharmony_ci * drm_gem_vram_kmap() and drm_gem_vram_kunmap(), as well as pairs of
508c2ecf20Sopenharmony_ci * drm_gem_vram_vmap() and drm_gem_vram_vunmap().
518c2ecf20Sopenharmony_ci */
528c2ecf20Sopenharmony_cistruct drm_gem_vram_object {
538c2ecf20Sopenharmony_ci	struct ttm_buffer_object bo;
548c2ecf20Sopenharmony_ci	struct ttm_bo_kmap_obj kmap;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	/**
578c2ecf20Sopenharmony_ci	 * @kmap_use_count:
588c2ecf20Sopenharmony_ci	 *
598c2ecf20Sopenharmony_ci	 * Reference count on the virtual address.
608c2ecf20Sopenharmony_ci	 * The address are un-mapped when the count reaches zero.
618c2ecf20Sopenharmony_ci	 */
628c2ecf20Sopenharmony_ci	unsigned int kmap_use_count;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	/* Supported placements are %TTM_PL_VRAM and %TTM_PL_SYSTEM */
658c2ecf20Sopenharmony_ci	struct ttm_placement placement;
668c2ecf20Sopenharmony_ci	struct ttm_place placements[2];
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	int pin_count;
698c2ecf20Sopenharmony_ci};
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci/**
728c2ecf20Sopenharmony_ci * Returns the container of type &struct drm_gem_vram_object
738c2ecf20Sopenharmony_ci * for field bo.
748c2ecf20Sopenharmony_ci * @bo:		the VRAM buffer object
758c2ecf20Sopenharmony_ci * Returns:	The containing GEM VRAM object
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_cistatic inline struct drm_gem_vram_object *drm_gem_vram_of_bo(
788c2ecf20Sopenharmony_ci	struct ttm_buffer_object *bo)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	return container_of(bo, struct drm_gem_vram_object, bo);
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci/**
848c2ecf20Sopenharmony_ci * Returns the container of type &struct drm_gem_vram_object
858c2ecf20Sopenharmony_ci * for field gem.
868c2ecf20Sopenharmony_ci * @gem:	the GEM object
878c2ecf20Sopenharmony_ci * Returns:	The containing GEM VRAM object
888c2ecf20Sopenharmony_ci */
898c2ecf20Sopenharmony_cistatic inline struct drm_gem_vram_object *drm_gem_vram_of_gem(
908c2ecf20Sopenharmony_ci	struct drm_gem_object *gem)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	return container_of(gem, struct drm_gem_vram_object, bo.base);
938c2ecf20Sopenharmony_ci}
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_cistruct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
968c2ecf20Sopenharmony_ci						size_t size,
978c2ecf20Sopenharmony_ci						unsigned long pg_align);
988c2ecf20Sopenharmony_civoid drm_gem_vram_put(struct drm_gem_vram_object *gbo);
998c2ecf20Sopenharmony_ciu64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo);
1008c2ecf20Sopenharmony_cis64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo);
1018c2ecf20Sopenharmony_ciint drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag);
1028c2ecf20Sopenharmony_ciint drm_gem_vram_unpin(struct drm_gem_vram_object *gbo);
1038c2ecf20Sopenharmony_civoid *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo);
1048c2ecf20Sopenharmony_civoid drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, void *vaddr);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ciint drm_gem_vram_fill_create_dumb(struct drm_file *file,
1078c2ecf20Sopenharmony_ci				  struct drm_device *dev,
1088c2ecf20Sopenharmony_ci				  unsigned long pg_align,
1098c2ecf20Sopenharmony_ci				  unsigned long pitch_align,
1108c2ecf20Sopenharmony_ci				  struct drm_mode_create_dumb *args);
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci/*
1138c2ecf20Sopenharmony_ci * Helpers for struct drm_driver
1148c2ecf20Sopenharmony_ci */
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ciint drm_gem_vram_driver_dumb_create(struct drm_file *file,
1178c2ecf20Sopenharmony_ci				    struct drm_device *dev,
1188c2ecf20Sopenharmony_ci				    struct drm_mode_create_dumb *args);
1198c2ecf20Sopenharmony_ciint drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
1208c2ecf20Sopenharmony_ci					 struct drm_device *dev,
1218c2ecf20Sopenharmony_ci					 uint32_t handle, uint64_t *offset);
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/*
1248c2ecf20Sopenharmony_ci * Helpers for struct drm_plane_helper_funcs
1258c2ecf20Sopenharmony_ci */
1268c2ecf20Sopenharmony_ciint
1278c2ecf20Sopenharmony_cidrm_gem_vram_plane_helper_prepare_fb(struct drm_plane *plane,
1288c2ecf20Sopenharmony_ci				     struct drm_plane_state *new_state);
1298c2ecf20Sopenharmony_civoid
1308c2ecf20Sopenharmony_cidrm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane,
1318c2ecf20Sopenharmony_ci				     struct drm_plane_state *old_state);
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci/*
1348c2ecf20Sopenharmony_ci * Helpers for struct drm_simple_display_pipe_funcs
1358c2ecf20Sopenharmony_ci */
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciint drm_gem_vram_simple_display_pipe_prepare_fb(
1388c2ecf20Sopenharmony_ci	struct drm_simple_display_pipe *pipe,
1398c2ecf20Sopenharmony_ci	struct drm_plane_state *new_state);
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_civoid drm_gem_vram_simple_display_pipe_cleanup_fb(
1428c2ecf20Sopenharmony_ci	struct drm_simple_display_pipe *pipe,
1438c2ecf20Sopenharmony_ci	struct drm_plane_state *old_state);
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci/**
1468c2ecf20Sopenharmony_ci * define DRM_GEM_VRAM_DRIVER - default callback functions for \
1478c2ecf20Sopenharmony_ci	&struct drm_driver
1488c2ecf20Sopenharmony_ci *
1498c2ecf20Sopenharmony_ci * Drivers that use VRAM MM and GEM VRAM can use this macro to initialize
1508c2ecf20Sopenharmony_ci * &struct drm_driver with default functions.
1518c2ecf20Sopenharmony_ci */
1528c2ecf20Sopenharmony_ci#define DRM_GEM_VRAM_DRIVER \
1538c2ecf20Sopenharmony_ci	.debugfs_init             = drm_vram_mm_debugfs_init, \
1548c2ecf20Sopenharmony_ci	.dumb_create		  = drm_gem_vram_driver_dumb_create, \
1558c2ecf20Sopenharmony_ci	.dumb_map_offset	  = drm_gem_vram_driver_dumb_mmap_offset, \
1568c2ecf20Sopenharmony_ci	.gem_prime_mmap		  = drm_gem_prime_mmap
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci/*
1598c2ecf20Sopenharmony_ci *  VRAM memory manager
1608c2ecf20Sopenharmony_ci */
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci/**
1638c2ecf20Sopenharmony_ci * struct drm_vram_mm - An instance of VRAM MM
1648c2ecf20Sopenharmony_ci * @vram_base:	Base address of the managed video memory
1658c2ecf20Sopenharmony_ci * @vram_size:	Size of the managed video memory in bytes
1668c2ecf20Sopenharmony_ci * @bdev:	The TTM BO device.
1678c2ecf20Sopenharmony_ci * @funcs:	TTM BO functions
1688c2ecf20Sopenharmony_ci *
1698c2ecf20Sopenharmony_ci * The fields &struct drm_vram_mm.vram_base and
1708c2ecf20Sopenharmony_ci * &struct drm_vram_mm.vrm_size are managed by VRAM MM, but are
1718c2ecf20Sopenharmony_ci * available for public read access. Use the field
1728c2ecf20Sopenharmony_ci * &struct drm_vram_mm.bdev to access the TTM BO device.
1738c2ecf20Sopenharmony_ci */
1748c2ecf20Sopenharmony_cistruct drm_vram_mm {
1758c2ecf20Sopenharmony_ci	uint64_t vram_base;
1768c2ecf20Sopenharmony_ci	size_t vram_size;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	struct ttm_bo_device bdev;
1798c2ecf20Sopenharmony_ci};
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci/**
1828c2ecf20Sopenharmony_ci * drm_vram_mm_of_bdev() - \
1838c2ecf20Sopenharmony_ci	Returns the container of type &struct ttm_bo_device for field bdev.
1848c2ecf20Sopenharmony_ci * @bdev:	the TTM BO device
1858c2ecf20Sopenharmony_ci *
1868c2ecf20Sopenharmony_ci * Returns:
1878c2ecf20Sopenharmony_ci * The containing instance of &struct drm_vram_mm
1888c2ecf20Sopenharmony_ci */
1898c2ecf20Sopenharmony_cistatic inline struct drm_vram_mm *drm_vram_mm_of_bdev(
1908c2ecf20Sopenharmony_ci	struct ttm_bo_device *bdev)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	return container_of(bdev, struct drm_vram_mm, bdev);
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_civoid drm_vram_mm_debugfs_init(struct drm_minor *minor);
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci/*
1988c2ecf20Sopenharmony_ci * Helpers for integration with struct drm_device
1998c2ecf20Sopenharmony_ci */
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_cistruct drm_vram_mm *drm_vram_helper_alloc_mm(
2028c2ecf20Sopenharmony_ci	struct drm_device *dev, uint64_t vram_base, size_t vram_size);
2038c2ecf20Sopenharmony_civoid drm_vram_helper_release_mm(struct drm_device *dev);
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ciint drmm_vram_helper_init(struct drm_device *dev, uint64_t vram_base,
2068c2ecf20Sopenharmony_ci			  size_t vram_size);
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci/*
2098c2ecf20Sopenharmony_ci * Mode-config helpers
2108c2ecf20Sopenharmony_ci */
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_cienum drm_mode_status
2138c2ecf20Sopenharmony_cidrm_vram_helper_mode_valid(struct drm_device *dev,
2148c2ecf20Sopenharmony_ci			   const struct drm_display_mode *mode);
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci#endif
217