/* SPDX-License-Identifier: GPL-2.0 or MIT */12#ifndef _DRM_CLIENT_H_3#define _DRM_CLIENT_H_45#include <linux/iosys-map.h>6#include <linux/lockdep.h>7#include <linux/mutex.h>8#include <linux/types.h>910#include <drm/drm_connector.h>11#include <drm/drm_crtc.h>1213struct drm_client_dev;14struct drm_device;15struct drm_file;16struct drm_framebuffer;17struct drm_gem_object;18struct drm_minor;19struct module;2021/**22* struct drm_client_funcs - DRM client callbacks23*/24struct drm_client_funcs {25/**26* @owner: The module owner27*/28struct module *owner;2930/**31* @free:32*33* Called when the client gets unregistered. Implementations should34* release all client-specific data and free the memory.35*36* This callback is optional.37*/38void (*free)(struct drm_client_dev *client);3940/**41* @unregister:42*43* Called when &drm_device is unregistered. The client should respond by44* releasing its resources using drm_client_release().45*46* This callback is optional.47*/48void (*unregister)(struct drm_client_dev *client);4950/**51* @restore:52*53* Called on drm_lastclose(). The first client instance in the list that54* returns zero gets the privilege to restore and no more clients are55* called. This callback is not called after @unregister has been called.56*57* Note that the core does not guarantee exclusion against concurrent58* drm_open(). Clients need to ensure this themselves, for example by59* using drm_master_internal_acquire() and drm_master_internal_release().60*61* If the caller passes force, the client should ignore any present DRM62* master and restore the display anyway.63*64* This callback is optional.65*/66int (*restore)(struct drm_client_dev *client, bool force);6768/**69* @hotplug:70*71* Called on drm_kms_helper_hotplug_event().72* This callback is not called after @unregister has been called.73*74* This callback is optional.75*/76int (*hotplug)(struct drm_client_dev *client);7778/**79* @suspend:80*81* Called when suspending the device.82*83* This callback is optional.84*/85int (*suspend)(struct drm_client_dev *client);8687/**88* @resume:89*90* Called when resuming the device from suspend.91*92* This callback is optional.93*/94int (*resume)(struct drm_client_dev *client);95};9697/**98* struct drm_client_dev - DRM client instance99*/100struct drm_client_dev {101/**102* @dev: DRM device103*/104struct drm_device *dev;105106/**107* @name: Name of the client.108*/109const char *name;110111/**112* @list:113*114* List of all clients of a DRM device, linked into115* &drm_device.clientlist. Protected by &drm_device.clientlist_mutex.116*/117struct list_head list;118119/**120* @funcs: DRM client functions (optional)121*/122const struct drm_client_funcs *funcs;123124/**125* @file: DRM file126*/127struct drm_file *file;128129/**130* @modeset_mutex: Protects @modesets.131*/132struct mutex modeset_mutex;133134/**135* @modesets: CRTC configurations136*/137struct drm_mode_set *modesets;138139/**140* @suspended:141*142* The client has been suspended.143*/144bool suspended;145146/**147* @hotplug_pending:148*149* A hotplug event has been received while the client was suspended.150* Try again on resume.151*/152bool hotplug_pending;153154/**155* @hotplug_failed:156*157* Set by client hotplug helpers if the hotplugging failed158* before. It is usually not tried again.159*/160bool hotplug_failed;161};162163int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,164const char *name, const struct drm_client_funcs *funcs);165void drm_client_release(struct drm_client_dev *client);166void drm_client_register(struct drm_client_dev *client);167168/**169* struct drm_client_buffer - DRM client buffer170*/171struct drm_client_buffer {172/**173* @client: DRM client174*/175struct drm_client_dev *client;176177/**178* @gem: GEM object backing this buffer179*180* FIXME: The DRM framebuffer holds a reference on its GEM181* buffer objects. Do not use this field in new code and182* update existing users.183*/184struct drm_gem_object *gem;185186/**187* @map: Virtual address for the buffer188*/189struct iosys_map map;190191/**192* @fb: DRM framebuffer193*/194struct drm_framebuffer *fb;195};196197struct drm_client_buffer *198drm_client_buffer_create_dumb(struct drm_client_dev *client, u32 width, u32 height, u32 format);199void drm_client_buffer_delete(struct drm_client_buffer *buffer);200int drm_client_buffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect);201int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer,202struct iosys_map *map_copy);203void drm_client_buffer_vunmap_local(struct drm_client_buffer *buffer);204int drm_client_buffer_vmap(struct drm_client_buffer *buffer,205struct iosys_map *map);206void drm_client_buffer_vunmap(struct drm_client_buffer *buffer);207208int drm_client_modeset_create(struct drm_client_dev *client);209void drm_client_modeset_free(struct drm_client_dev *client);210int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height);211bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation);212int drm_client_modeset_check(struct drm_client_dev *client);213int drm_client_modeset_commit_locked(struct drm_client_dev *client);214int drm_client_modeset_commit(struct drm_client_dev *client);215int drm_client_modeset_dpms(struct drm_client_dev *client, int mode);216int drm_client_modeset_wait_for_vblank(struct drm_client_dev *client, unsigned int crtc_index);217218/**219* drm_client_for_each_modeset() - Iterate over client modesets220* @modeset: &drm_mode_set loop cursor221* @client: DRM client222*/223#define drm_client_for_each_modeset(modeset, client) \224for (({ lockdep_assert_held(&(client)->modeset_mutex); }), \225modeset = (client)->modesets; modeset->crtc; modeset++)226227/**228* drm_client_for_each_connector_iter - connector_list iterator macro229* @connector: &struct drm_connector pointer used as cursor230* @iter: &struct drm_connector_list_iter231*232* This iterates the connectors that are useable for internal clients (excludes233* writeback connectors).234*235* For more info see drm_for_each_connector_iter().236*/237#define drm_client_for_each_connector_iter(connector, iter) \238drm_for_each_connector_iter(connector, iter) \239if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)240241#endif242243244