This the beginning of an API for in-kernel clients. First out is a display representation that will be used by drm_fb_helper in order to move out its mode setting code. Signed-off-by: Noralf Trønnes <noralf@xxxxxxxxxxx> --- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_client.c | 119 +++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_client.h | 44 ++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/drm_client.c create mode 100644 include/drm/drm_client.h diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 9d66657ea117..d25afa136d8f 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -18,7 +18,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_encoder.o drm_mode_object.o drm_property.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ - drm_syncobj.o drm_lease.o + drm_syncobj.o drm_lease.o drm_client.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_DRM_VM) += drm_vm.o diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c new file mode 100644 index 000000000000..7c31a6efb2f4 --- /dev/null +++ b/drivers/gpu/drm/drm_client.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2018 Noralf Trønnes + * + * For parts copied from drm_fb_helper: + * Copyright (c) 2006-2009 Red Hat Inc. + * Copyright (c) 2006-2008 Intel Corporation + * Copyright (c) 2007 Dave Airlie <airlied@xxxxxxxx> + */ + +#include <linux/slab.h> + +#include <drm/drm_client.h> +#include <drm/drm_connector.h> +#include <drm/drm_crtc.h> +#include <drm/drm_device.h> +#include <drm/drm_modes.h> + +/** + * drm_client_display_create() - Create display structure + * @dev: DRM device + * + * This function creates a display structure for clients backed by an array of + * &drm_mode_set, one per CRTC. + * + * Returns: + * A &drm_client_display or an error pointer on allocation failure. + */ +struct drm_client_display *drm_client_display_create(struct drm_device *dev) +{ + unsigned int num_crtc = dev->mode_config.num_crtc; + struct drm_client_display *display; + struct drm_mode_set *modeset; + struct drm_crtc *crtc; + unsigned int i = 0; + + display = kzalloc(sizeof(*display), GFP_KERNEL); + if (!display) + return ERR_PTR(-ENOMEM); + + /* Add NULL terminating entry to enable index less iteration */ + display->modesets = kcalloc(num_crtc + 1, sizeof(*display->modesets), GFP_KERNEL); + if (!display->modesets) { + kfree(display); + return ERR_PTR(-ENOMEM); + } + + display->dev = dev; + display->modeset_count = num_crtc; + + drm_for_each_crtc(crtc, dev) + display->modesets[i++].crtc = crtc; + + drm_client_display_for_each_modeset(modeset, display) { + /* One connector per crtc except for the cloned case */ + modeset->connectors = kcalloc(2, sizeof(*modeset->connectors), GFP_KERNEL); + if (!modeset->connectors) + goto err_free; + } + + return display; + +err_free: + drm_client_display_free(display); + + return ERR_PTR(-ENOMEM); +} +EXPORT_SYMBOL(drm_client_display_create); + +/** + * drm_client_display_free() - Free display structure + * @display: Client display + * + * This function frees the structure allocated by drm_client_display_create(). + * It also destroys display modes and puts connectors. + */ +void drm_client_display_free(struct drm_client_display *display) +{ + struct drm_mode_set *modeset; + unsigned int i; + + if (!display) + return; + + drm_client_display_for_each_modeset(modeset, display) { + if (modeset->mode) + drm_mode_destroy(display->dev, modeset->mode); + + for (i = 0; i < modeset->num_connectors; i++) + drm_connector_put(modeset->connectors[i]); + kfree(modeset->connectors); + } + kfree(display->modesets); + kfree(display); +} +EXPORT_SYMBOL(drm_client_display_free); + +/** + * drm_client_display_find_modeset() - Find modeset matching a CRTC + * @display: Client display + * @crtc: CRTC + * + * This function looks up the @display modeset connected to @crtc. + * + * Returns: + * A &drm_mode_set or NULL. + */ +struct drm_mode_set * +drm_client_display_find_modeset(struct drm_client_display *display, struct drm_crtc *crtc) +{ + struct drm_mode_set *modeset; + + drm_client_display_for_each_modeset(modeset, display) + if (modeset->crtc == crtc) + return modeset; + + return NULL; +} +EXPORT_SYMBOL(drm_client_display_find_modeset); diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h new file mode 100644 index 000000000000..b6a057802769 --- /dev/null +++ b/include/drm/drm_client.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _DRM_CLIENT_H_ +#define _DRM_CLIENT_H_ + +struct drm_crtc; +struct drm_device; +struct drm_mode_set; + +/** + * struct drm_client_display - DRM client display + */ +struct drm_client_display { + /** + * @dev: + * + * DRM device. + */ + struct drm_device *dev; + + /** + * @modesets: + * + * Per CRTC array of modeset configurations. + */ + struct drm_mode_set *modesets; + + /** + * @modeset_count: + * + * Number of modesets + */ + unsigned int modeset_count; +}; + +struct drm_client_display *drm_client_display_create(struct drm_device *dev); +void drm_client_display_free(struct drm_client_display *display); +struct drm_mode_set * +drm_client_display_find_modeset(struct drm_client_display *display, struct drm_crtc *crtc); + +#define drm_client_display_for_each_modeset(modeset, display) \ + for (modeset = display->modesets; modeset->crtc; modeset++) + +#endif -- 2.15.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx