18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 or MIT */
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#ifndef _DRM_CLIENT_H_
48c2ecf20Sopenharmony_ci#define _DRM_CLIENT_H_
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/lockdep.h>
78c2ecf20Sopenharmony_ci#include <linux/mutex.h>
88c2ecf20Sopenharmony_ci#include <linux/types.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <drm/drm_connector.h>
118c2ecf20Sopenharmony_ci#include <drm/drm_crtc.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cistruct drm_client_dev;
148c2ecf20Sopenharmony_cistruct drm_device;
158c2ecf20Sopenharmony_cistruct drm_file;
168c2ecf20Sopenharmony_cistruct drm_framebuffer;
178c2ecf20Sopenharmony_cistruct drm_gem_object;
188c2ecf20Sopenharmony_cistruct drm_minor;
198c2ecf20Sopenharmony_cistruct module;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/**
228c2ecf20Sopenharmony_ci * struct drm_client_funcs - DRM client callbacks
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_cistruct drm_client_funcs {
258c2ecf20Sopenharmony_ci	/**
268c2ecf20Sopenharmony_ci	 * @owner: The module owner
278c2ecf20Sopenharmony_ci	 */
288c2ecf20Sopenharmony_ci	struct module *owner;
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	/**
318c2ecf20Sopenharmony_ci	 * @unregister:
328c2ecf20Sopenharmony_ci	 *
338c2ecf20Sopenharmony_ci	 * Called when &drm_device is unregistered. The client should respond by
348c2ecf20Sopenharmony_ci	 * releasing its resources using drm_client_release().
358c2ecf20Sopenharmony_ci	 *
368c2ecf20Sopenharmony_ci	 * This callback is optional.
378c2ecf20Sopenharmony_ci	 */
388c2ecf20Sopenharmony_ci	void (*unregister)(struct drm_client_dev *client);
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	/**
418c2ecf20Sopenharmony_ci	 * @restore:
428c2ecf20Sopenharmony_ci	 *
438c2ecf20Sopenharmony_ci	 * Called on drm_lastclose(). The first client instance in the list that
448c2ecf20Sopenharmony_ci	 * returns zero gets the privilege to restore and no more clients are
458c2ecf20Sopenharmony_ci	 * called. This callback is not called after @unregister has been called.
468c2ecf20Sopenharmony_ci	 *
478c2ecf20Sopenharmony_ci	 * Note that the core does not guarantee exclusion against concurrent
488c2ecf20Sopenharmony_ci	 * drm_open(). Clients need to ensure this themselves, for example by
498c2ecf20Sopenharmony_ci	 * using drm_master_internal_acquire() and
508c2ecf20Sopenharmony_ci	 * drm_master_internal_release().
518c2ecf20Sopenharmony_ci	 *
528c2ecf20Sopenharmony_ci	 * This callback is optional.
538c2ecf20Sopenharmony_ci	 */
548c2ecf20Sopenharmony_ci	int (*restore)(struct drm_client_dev *client);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	/**
578c2ecf20Sopenharmony_ci	 * @hotplug:
588c2ecf20Sopenharmony_ci	 *
598c2ecf20Sopenharmony_ci	 * Called on drm_kms_helper_hotplug_event().
608c2ecf20Sopenharmony_ci	 * This callback is not called after @unregister has been called.
618c2ecf20Sopenharmony_ci	 *
628c2ecf20Sopenharmony_ci	 * This callback is optional.
638c2ecf20Sopenharmony_ci	 */
648c2ecf20Sopenharmony_ci	int (*hotplug)(struct drm_client_dev *client);
658c2ecf20Sopenharmony_ci};
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci/**
688c2ecf20Sopenharmony_ci * struct drm_client_dev - DRM client instance
698c2ecf20Sopenharmony_ci */
708c2ecf20Sopenharmony_cistruct drm_client_dev {
718c2ecf20Sopenharmony_ci	/**
728c2ecf20Sopenharmony_ci	 * @dev: DRM device
738c2ecf20Sopenharmony_ci	 */
748c2ecf20Sopenharmony_ci	struct drm_device *dev;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	/**
778c2ecf20Sopenharmony_ci	 * @name: Name of the client.
788c2ecf20Sopenharmony_ci	 */
798c2ecf20Sopenharmony_ci	const char *name;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	/**
828c2ecf20Sopenharmony_ci	 * @list:
838c2ecf20Sopenharmony_ci	 *
848c2ecf20Sopenharmony_ci	 * List of all clients of a DRM device, linked into
858c2ecf20Sopenharmony_ci	 * &drm_device.clientlist. Protected by &drm_device.clientlist_mutex.
868c2ecf20Sopenharmony_ci	 */
878c2ecf20Sopenharmony_ci	struct list_head list;
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	/**
908c2ecf20Sopenharmony_ci	 * @funcs: DRM client functions (optional)
918c2ecf20Sopenharmony_ci	 */
928c2ecf20Sopenharmony_ci	const struct drm_client_funcs *funcs;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/**
958c2ecf20Sopenharmony_ci	 * @file: DRM file
968c2ecf20Sopenharmony_ci	 */
978c2ecf20Sopenharmony_ci	struct drm_file *file;
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	/**
1008c2ecf20Sopenharmony_ci	 * @modeset_mutex: Protects @modesets.
1018c2ecf20Sopenharmony_ci	 */
1028c2ecf20Sopenharmony_ci	struct mutex modeset_mutex;
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	/**
1058c2ecf20Sopenharmony_ci	 * @modesets: CRTC configurations
1068c2ecf20Sopenharmony_ci	 */
1078c2ecf20Sopenharmony_ci	struct drm_mode_set *modesets;
1088c2ecf20Sopenharmony_ci};
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ciint drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
1118c2ecf20Sopenharmony_ci		    const char *name, const struct drm_client_funcs *funcs);
1128c2ecf20Sopenharmony_civoid drm_client_release(struct drm_client_dev *client);
1138c2ecf20Sopenharmony_civoid drm_client_register(struct drm_client_dev *client);
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_civoid drm_client_dev_unregister(struct drm_device *dev);
1168c2ecf20Sopenharmony_civoid drm_client_dev_hotplug(struct drm_device *dev);
1178c2ecf20Sopenharmony_civoid drm_client_dev_restore(struct drm_device *dev);
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci/**
1208c2ecf20Sopenharmony_ci * struct drm_client_buffer - DRM client buffer
1218c2ecf20Sopenharmony_ci */
1228c2ecf20Sopenharmony_cistruct drm_client_buffer {
1238c2ecf20Sopenharmony_ci	/**
1248c2ecf20Sopenharmony_ci	 * @client: DRM client
1258c2ecf20Sopenharmony_ci	 */
1268c2ecf20Sopenharmony_ci	struct drm_client_dev *client;
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	/**
1298c2ecf20Sopenharmony_ci	 * @handle: Buffer handle
1308c2ecf20Sopenharmony_ci	 */
1318c2ecf20Sopenharmony_ci	u32 handle;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	/**
1348c2ecf20Sopenharmony_ci	 * @pitch: Buffer pitch
1358c2ecf20Sopenharmony_ci	 */
1368c2ecf20Sopenharmony_ci	u32 pitch;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	/**
1398c2ecf20Sopenharmony_ci	 * @gem: GEM object backing this buffer
1408c2ecf20Sopenharmony_ci	 */
1418c2ecf20Sopenharmony_ci	struct drm_gem_object *gem;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	/**
1448c2ecf20Sopenharmony_ci	 * @vaddr: Virtual address for the buffer
1458c2ecf20Sopenharmony_ci	 */
1468c2ecf20Sopenharmony_ci	void *vaddr;
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	/**
1498c2ecf20Sopenharmony_ci	 * @fb: DRM framebuffer
1508c2ecf20Sopenharmony_ci	 */
1518c2ecf20Sopenharmony_ci	struct drm_framebuffer *fb;
1528c2ecf20Sopenharmony_ci};
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistruct drm_client_buffer *
1558c2ecf20Sopenharmony_cidrm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format);
1568c2ecf20Sopenharmony_civoid drm_client_framebuffer_delete(struct drm_client_buffer *buffer);
1578c2ecf20Sopenharmony_ciint drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect);
1588c2ecf20Sopenharmony_civoid *drm_client_buffer_vmap(struct drm_client_buffer *buffer);
1598c2ecf20Sopenharmony_civoid drm_client_buffer_vunmap(struct drm_client_buffer *buffer);
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ciint drm_client_modeset_create(struct drm_client_dev *client);
1628c2ecf20Sopenharmony_civoid drm_client_modeset_free(struct drm_client_dev *client);
1638c2ecf20Sopenharmony_ciint drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height);
1648c2ecf20Sopenharmony_cibool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation);
1658c2ecf20Sopenharmony_ciint drm_client_modeset_check(struct drm_client_dev *client);
1668c2ecf20Sopenharmony_ciint drm_client_modeset_commit_locked(struct drm_client_dev *client);
1678c2ecf20Sopenharmony_ciint drm_client_modeset_commit(struct drm_client_dev *client);
1688c2ecf20Sopenharmony_ciint drm_client_modeset_dpms(struct drm_client_dev *client, int mode);
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci/**
1718c2ecf20Sopenharmony_ci * drm_client_for_each_modeset() - Iterate over client modesets
1728c2ecf20Sopenharmony_ci * @modeset: &drm_mode_set loop cursor
1738c2ecf20Sopenharmony_ci * @client: DRM client
1748c2ecf20Sopenharmony_ci */
1758c2ecf20Sopenharmony_ci#define drm_client_for_each_modeset(modeset, client) \
1768c2ecf20Sopenharmony_ci	for (({ lockdep_assert_held(&(client)->modeset_mutex); }), \
1778c2ecf20Sopenharmony_ci	     modeset = (client)->modesets; modeset->crtc; modeset++)
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci/**
1808c2ecf20Sopenharmony_ci * drm_client_for_each_connector_iter - connector_list iterator macro
1818c2ecf20Sopenharmony_ci * @connector: &struct drm_connector pointer used as cursor
1828c2ecf20Sopenharmony_ci * @iter: &struct drm_connector_list_iter
1838c2ecf20Sopenharmony_ci *
1848c2ecf20Sopenharmony_ci * This iterates the connectors that are useable for internal clients (excludes
1858c2ecf20Sopenharmony_ci * writeback connectors).
1868c2ecf20Sopenharmony_ci *
1878c2ecf20Sopenharmony_ci * For more info see drm_for_each_connector_iter().
1888c2ecf20Sopenharmony_ci */
1898c2ecf20Sopenharmony_ci#define drm_client_for_each_connector_iter(connector, iter) \
1908c2ecf20Sopenharmony_ci	drm_for_each_connector_iter(connector, iter) \
1918c2ecf20Sopenharmony_ci		if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_civoid drm_client_debugfs_init(struct drm_minor *minor);
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci#endif
196