From patchwork Tue Mar 13 13:31:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Andrushchenko X-Patchwork-Id: 10278799 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 736A06038F for ; Tue, 13 Mar 2018 13:33:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A891290B4 for ; Tue, 13 Mar 2018 13:33:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 388252913C; Tue, 13 Mar 2018 13:33:05 +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=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham 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 93A10291E3 for ; Tue, 13 Mar 2018 13:31:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 225F06E4FA; Tue, 13 Mar 2018 13:31:34 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf0-x243.google.com (mail-lf0-x243.google.com [IPv6:2a00:1450:4010:c07::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9BDBA6E4F0 for ; Tue, 13 Mar 2018 13:31:28 +0000 (UTC) Received: by mail-lf0-x243.google.com with SMTP id q69-v6so28761864lfi.10 for ; Tue, 13 Mar 2018 06:31:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=K7MXjROJf/EvcRuv6s3dpVucV39vyAGrquKeKXy3tyg=; b=bbta3WzrQVl1xT1DbiE4vmRzi3Pc1Bz1rVGxVPzum32DNHVoOkb9mquFTRrs/9oyde Lg6YyXLLXGiLPdebiZtl0LtmfROLNWuabVPF+gwANz8H05fmuXtMO8+uRHQie+XnCr/e BLR88qIBpNRWzVvZAPVLRJEzsO4him2nwTdKM1xpYdkcWmtc0hPHDIOIowsJ5w0LlhFb NpUzKAYUOSnFI6qLTY0GGshJdojwCAcGy6y2lutY7+vomy0nP/kA4f+/jflbFQ1xmjQ7 OV+92h5V8md0+T6r1AfcCrPbX8QmF3CBu4qXbA60IwLaeJxqYPxF/P9/aMea85PV5Oq1 LNDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=K7MXjROJf/EvcRuv6s3dpVucV39vyAGrquKeKXy3tyg=; b=nw12kPS2UDNteGkxNFyhCNLapZuIMjq0PIWFDu4aL5LNMCNs3YhQMxAss0XARSB1wl Oh9wNdEFJJTJ6xgtespnRys0mQsHbzfogQ+tyPvDi5PcPZ12q9XB0shCB+hb3YWrnO6L xnsYxiNZoIugUagRH1MVgDbmtZabKJl7C7qdEI/wUV1hRMiJkqMV3JZwH9W6dTRozmaW eRzae89gqcIjGpavgpbPaWYxfiVPKXWA2g3mdpBApXOlpsL+Sag5oJguOMj3yZlTle62 v91NH2ZZDwniUN7Xi5VZGEs7eQF2hT6YZIE2rdyvPRKMSvuXyqaZwc6WNOopwg94a9vO NZJg== X-Gm-Message-State: AElRT7GxZ8dM4G2cJmengZxEs94eAJILKemtUdIdhGHznawmZwIfjRqX jPBw+sYl6ntVLw7LOl6rSfg= X-Google-Smtp-Source: AG47ELtddBVPkeYzqEZY4F/BKpX1jAqLFEg2edUfljy2loh7rUXUKR7CZiKflJfQ3S4eWRBIRQXL9w== X-Received: by 10.46.82.157 with SMTP id n29mr467202lje.145.1520947886470; Tue, 13 Mar 2018 06:31:26 -0700 (PDT) Received: from a2k-HP-ProDesk-600-G2-SFF.kyiv.epam.com (ll-55.209.223.85.sovam.net.ua. [85.223.209.55]) by smtp.gmail.com with ESMTPSA id l8-v6sm53314lfb.19.2018.03.13.06.31.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 13 Mar 2018 06:31:25 -0700 (PDT) From: Oleksandr Andrushchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, seanpaul@chromium.org, gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com Subject: [PATCH v2 6/8] drm/xen-front: Introduce DRM/KMS virtual display driver Date: Tue, 13 Mar 2018 15:31:05 +0200 Message-Id: <1520947867-32514-7-git-send-email-andr2000@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1520947867-32514-1-git-send-email-andr2000@gmail.com> References: <1520947867-32514-1-git-send-email-andr2000@gmail.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: andr2000@gmail.com, Oleksandr Andrushchenko MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Oleksandr Andrushchenko Implement essential initialization of the display driver: - introduce required data structures - handle DRM/KMS driver registration - register driver on backend connection - remove driver on backend disconnect Implement kernel modesetiing/connector handling using DRM simple KMS helper pipeline: - implement KMS part of the driver with the help of DRM simple pipepline helper which is possible due to the fact that the para-virtualized driver only supports a single (primary) plane: - initialize connectors according to XenStore configuration - handle frame done events from the backend - create and destroy frame buffers and propagate those to the backend - propagate set/reset mode configuration to the backend on display enable/disable callbacks - send page flip request to the backend and implement logic for reporting backend IO errors on prepare fb callback - implement virtual connector handling: - support only pixel formats suitable for single plane modes - make sure the connector is always connected - support a single video mode as per para-virtualized driver configuration Signed-off-by: Oleksandr Andrushchenko --- drivers/gpu/drm/xen/Makefile | 3 + drivers/gpu/drm/xen/xen_drm_front.c | 161 +++++++++++++++- drivers/gpu/drm/xen/xen_drm_front.h | 32 ++++ drivers/gpu/drm/xen/xen_drm_front_conn.c | 119 ++++++++++++ drivers/gpu/drm/xen/xen_drm_front_conn.h | 27 +++ drivers/gpu/drm/xen/xen_drm_front_drv.c | 171 +++++++++++++++++ drivers/gpu/drm/xen/xen_drm_front_drv.h | 65 +++++++ drivers/gpu/drm/xen/xen_drm_front_evtchnl.c | 4 +- drivers/gpu/drm/xen/xen_drm_front_kms.c | 282 ++++++++++++++++++++++++++++ drivers/gpu/drm/xen/xen_drm_front_kms.h | 22 +++ 10 files changed, 883 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/xen/xen_drm_front_conn.c create mode 100644 drivers/gpu/drm/xen/xen_drm_front_conn.h create mode 100644 drivers/gpu/drm/xen/xen_drm_front_drv.c create mode 100644 drivers/gpu/drm/xen/xen_drm_front_drv.h create mode 100644 drivers/gpu/drm/xen/xen_drm_front_kms.c create mode 100644 drivers/gpu/drm/xen/xen_drm_front_kms.h diff --git a/drivers/gpu/drm/xen/Makefile b/drivers/gpu/drm/xen/Makefile index 6c8c751f12ed..a7858693baae 100644 --- a/drivers/gpu/drm/xen/Makefile +++ b/drivers/gpu/drm/xen/Makefile @@ -1,6 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 OR MIT drm_xen_front-objs := xen_drm_front.o \ + xen_drm_front_drv.o \ + xen_drm_front_kms.o \ + xen_drm_front_conn.o \ xen_drm_front_evtchnl.o \ xen_drm_front_shbuf.o \ xen_drm_front_cfg.o diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c index fae631067c31..4e5059a280ba 100644 --- a/drivers/gpu/drm/xen/xen_drm_front.c +++ b/drivers/gpu/drm/xen/xen_drm_front.c @@ -10,6 +10,8 @@ #include +#include + #include #include #include @@ -17,11 +19,149 @@ #include #include "xen_drm_front.h" +#include "xen_drm_front_drv.h" #include "xen_drm_front_evtchnl.h" #include "xen_drm_front_shbuf.h" +int xen_drm_front_mode_set(struct xen_drm_front_drm_pipeline *pipeline, + uint32_t x, uint32_t y, uint32_t width, uint32_t height, + uint32_t bpp, uint64_t fb_cookie) +{ + return 0; +} + +static int be_dbuf_create_int(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie, uint32_t width, uint32_t height, + uint32_t bpp, uint64_t size, struct page **pages, + struct sg_table *sgt) +{ + return 0; +} + +int xen_drm_front_dbuf_create_from_sgt(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie, uint32_t width, uint32_t height, + uint32_t bpp, uint64_t size, struct sg_table *sgt) +{ + return be_dbuf_create_int(front_info, dbuf_cookie, width, height, + bpp, size, NULL, sgt); +} + +int xen_drm_front_dbuf_create_from_pages(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie, uint32_t width, uint32_t height, + uint32_t bpp, uint64_t size, struct page **pages) +{ + return be_dbuf_create_int(front_info, dbuf_cookie, width, height, + bpp, size, pages, NULL); +} + +int xen_drm_front_dbuf_destroy(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie) +{ + return 0; +} + +int xen_drm_front_fb_attach(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie, uint64_t fb_cookie, uint32_t width, + uint32_t height, uint32_t pixel_format) +{ + return 0; +} + +int xen_drm_front_fb_detach(struct xen_drm_front_info *front_info, + uint64_t fb_cookie) +{ + return 0; +} + +int xen_drm_front_page_flip(struct xen_drm_front_info *front_info, + int conn_idx, uint64_t fb_cookie) +{ + return 0; +} + +void xen_drm_front_unload(struct xen_drm_front_info *front_info) +{ + if (front_info->xb_dev->state != XenbusStateReconfiguring) + return; + + DRM_DEBUG("Can try removing driver now\n"); + xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising); +} + +static int xen_drm_drv_probe(struct platform_device *pdev) +{ + /* + * The device is not spawn from a device tree, so arch_setup_dma_ops + * is not called, thus leaving the device with dummy DMA ops. + * This makes the device return error on PRIME buffer import, which + * is not correct: to fix this call of_dma_configure() with a NULL + * node to set default DMA ops. + */ + of_dma_configure(&pdev->dev, NULL); + return xen_drm_front_drv_probe(pdev); +} + +static int xen_drm_drv_remove(struct platform_device *pdev) +{ + return xen_drm_front_drv_remove(pdev); +} + +struct platform_device_info xen_drm_front_platform_info = { + .name = XENDISPL_DRIVER_NAME, + .id = 0, + .num_res = 0, + .dma_mask = DMA_BIT_MASK(32), +}; + +static struct platform_driver xen_drm_front_front_info = { + .probe = xen_drm_drv_probe, + .remove = xen_drm_drv_remove, + .driver = { + .name = XENDISPL_DRIVER_NAME, + }, +}; + +static void xen_drm_drv_deinit(struct xen_drm_front_info *front_info) +{ + if (!front_info->drm_pdrv_registered) + return; + + if (front_info->drm_pdev) + platform_device_unregister(front_info->drm_pdev); + + platform_driver_unregister(&xen_drm_front_front_info); + front_info->drm_pdrv_registered = false; + front_info->drm_pdev = NULL; +} + +static int xen_drm_drv_init(struct xen_drm_front_info *front_info) +{ + int ret; + + ret = platform_driver_register(&xen_drm_front_front_info); + if (ret < 0) + return ret; + + front_info->drm_pdrv_registered = true; + /* pass card configuration via platform data */ + xen_drm_front_platform_info.data = &front_info->cfg; + xen_drm_front_platform_info.size_data = sizeof(front_info->cfg); + + front_info->drm_pdev = platform_device_register_full( + &xen_drm_front_platform_info); + if (IS_ERR_OR_NULL(front_info->drm_pdev)) { + DRM_ERROR("Failed to register " XENDISPL_DRIVER_NAME " PV DRM driver\n"); + front_info->drm_pdev = NULL; + xen_drm_drv_deinit(front_info); + return -ENODEV; + } + + return 0; +} + static void xen_drv_remove_internal(struct xen_drm_front_info *front_info) { + xen_drm_drv_deinit(front_info); xen_drm_front_evtchnl_free_all(front_info); } @@ -47,13 +187,29 @@ static int displback_initwait(struct xen_drm_front_info *front_info) static int displback_connect(struct xen_drm_front_info *front_info) { xen_drm_front_evtchnl_set_state(front_info, EVTCHNL_STATE_CONNECTED); - return 0; + return xen_drm_drv_init(front_info); } static void displback_disconnect(struct xen_drm_front_info *front_info) { + bool removed = true; + + if (front_info->drm_pdev) { + if (xen_drm_front_drv_is_used(front_info->drm_pdev)) { + DRM_WARN("DRM driver still in use, deferring removal\n"); + removed = false; + } else + xen_drv_remove_internal(front_info); + } + xen_drm_front_evtchnl_set_state(front_info, EVTCHNL_STATE_DISCONNECTED); - xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising); + + if (removed) + xenbus_switch_state(front_info->xb_dev, + XenbusStateInitialising); + else + xenbus_switch_state(front_info->xb_dev, + XenbusStateReconfiguring); } static void displback_changed(struct xenbus_device *xb_dev, @@ -136,6 +292,7 @@ static int xen_drv_probe(struct xenbus_device *xb_dev, front_info->xb_dev = xb_dev; spin_lock_init(&front_info->io_lock); + front_info->drm_pdrv_registered = false; dev_set_drvdata(&xb_dev->dev, front_info); return xenbus_switch_state(xb_dev, XenbusStateInitialising); } diff --git a/drivers/gpu/drm/xen/xen_drm_front.h b/drivers/gpu/drm/xen/xen_drm_front.h index 4adb6101c889..d964c4bd4fb6 100644 --- a/drivers/gpu/drm/xen/xen_drm_front.h +++ b/drivers/gpu/drm/xen/xen_drm_front.h @@ -11,6 +11,8 @@ #ifndef __XEN_DRM_FRONT_H_ #define __XEN_DRM_FRONT_H_ +#include + #include "xen_drm_front_cfg.h" #ifndef GRANT_INVALID_REF @@ -22,10 +24,13 @@ #define GRANT_INVALID_REF 0 #endif +struct xen_drm_front_drm_pipeline; + struct xen_drm_front_info { struct xenbus_device *xb_dev; /* to protect data between backend IO code and interrupt handler */ spinlock_t io_lock; + bool drm_pdrv_registered; /* virtual DRM platform device */ struct platform_device *drm_pdev; @@ -34,4 +39,31 @@ struct xen_drm_front_info { struct xen_drm_front_cfg cfg; }; +int xen_drm_front_mode_set(struct xen_drm_front_drm_pipeline *pipeline, + uint32_t x, uint32_t y, uint32_t width, uint32_t height, + uint32_t bpp, uint64_t fb_cookie); + +int xen_drm_front_dbuf_create_from_sgt(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie, uint32_t width, uint32_t height, + uint32_t bpp, uint64_t size, struct sg_table *sgt); + +int xen_drm_front_dbuf_create_from_pages(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie, uint32_t width, uint32_t height, + uint32_t bpp, uint64_t size, struct page **pages); + +int xen_drm_front_dbuf_destroy(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie); + +int xen_drm_front_fb_attach(struct xen_drm_front_info *front_info, + uint64_t dbuf_cookie, uint64_t fb_cookie, uint32_t width, + uint32_t height, uint32_t pixel_format); + +int xen_drm_front_fb_detach(struct xen_drm_front_info *front_info, + uint64_t fb_cookie); + +int xen_drm_front_page_flip(struct xen_drm_front_info *front_info, + int conn_idx, uint64_t fb_cookie); + +void xen_drm_front_unload(struct xen_drm_front_info *front_info); + #endif /* __XEN_DRM_FRONT_H_ */ diff --git a/drivers/gpu/drm/xen/xen_drm_front_conn.c b/drivers/gpu/drm/xen/xen_drm_front_conn.c new file mode 100644 index 000000000000..382c8a9da7e6 --- /dev/null +++ b/drivers/gpu/drm/xen/xen_drm_front_conn.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +/* + * Xen para-virtual DRM device + * + * Copyright (C) 2016-2018 EPAM Systems Inc. + * + * Author: Oleksandr Andrushchenko + */ + +#include +#include + +#include