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 <nor...@tronnes.org>
---
 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 <airl...@linux.ie>
+ */
+
+#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@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to