From patchwork Thu Apr 12 13:17:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10338529 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1486C603B5 for ; Thu, 12 Apr 2018 13:18:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 03ACD23B23 for ; Thu, 12 Apr 2018 13:18:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ECB62288BA; Thu, 12 Apr 2018 13:18:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1CCB623B23 for ; Thu, 12 Apr 2018 13:18:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CF3B96E838; Thu, 12 Apr 2018 13:17:59 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 58C2D6E813; Thu, 12 Apr 2018 13:17:50 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:48164 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1f6c6m-0002l8-32; Thu, 12 Apr 2018 15:17:48 +0200 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Date: Thu, 12 Apr 2018 15:17:09 +0200 Message-Id: <20180412131727.8914-8-noralf@tronnes.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180412131727.8914-1-noralf@tronnes.org> References: <20180412131727.8914-1-noralf@tronnes.org> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC v4 07/25] drm: Begin an API for in-kernel clients X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org, =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , laurent.pinchart@ideasonboard.com, mstaudt@suse.de, dh.herrmann@gmail.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 + */ + +#include + +#include +#include +#include +#include +#include + +/** + * 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