From patchwork Wed Oct 25 10:39:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Zhao X-Patchwork-Id: 13435989 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7D151C25B6E for ; Wed, 25 Oct 2023 10:40:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=tYW0K0W4n/DOpdyMzwcfMfv3RQ2ScGt8M+gartnr0mA=; b=dUYOztQZ9qF0Tp iZWs8DbsywEnr36YLuJJrVeBhRt2i5+t6CR1rTQEouAg74zQKiAd8+RX9FeShFR3IPv1gxzDi5966 y3qXRb7pnjjKhh3LHmDWToWn+COsiwkr2A71RecREK/c3/vkAbtdfMTwa1ZSYVkrMOb6i1RvILDRm QzoZnQQ3z2VJTilwkZ+5pX/MSeZWckgSR5EeQpU0reRk+hAs8UEbfDK7IjPW8gMhaD1kDU7sMrN6H sGxItLG2WeWtRkYFG19eLgKqlQlrSod5yAs426UGuHDEm3/PWo6xBC2PK/y35IVsdP9D3gWgr/YQ0 FQx6fNkvlfi5s0cRyNBg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qvbJk-00C5Wr-1b; Wed, 25 Oct 2023 10:40:52 +0000 Received: from ex01.ufhost.com ([61.152.239.75]) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qvbJc-00C5Pr-0N for linux-riscv@lists.infradead.org; Wed, 25 Oct 2023 10:40:46 +0000 Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id E30AA24E28F; Wed, 25 Oct 2023 18:39:59 +0800 (CST) Received: from EXMBX061.cuchost.com (172.16.6.61) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Wed, 25 Oct 2023 18:39:59 +0800 Received: from xiaofei.localdomain (180.164.60.184) by EXMBX061.cuchost.com (172.16.6.61) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Wed, 25 Oct 2023 18:39:59 +0800 From: Keith Zhao To: , , , , , CC: David Airlie , Daniel Vetter , "Rob Herring" , Krzysztof Kozlowski , Conor Dooley , "Emil Renner Berthing" , Paul Walmsley , Palmer Dabbelt , Albert Ou , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Philipp Zabel , Sumit Semwal , , Bjorn Andersson , "Heiko Stuebner" , Shawn Guo , Jagan Teki , Chris Morgan , Keith Zhao , Jack Zhu , Shengyang Chen , Changhuang Liang Subject: [PATCH v2 4/6] drm/vs: Register DRM device Date: Wed, 25 Oct 2023 18:39:55 +0800 Message-ID: <20231025103957.3776-5-keith.zhao@starfivetech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231025103957.3776-1-keith.zhao@starfivetech.com> References: <20231025103957.3776-1-keith.zhao@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [180.164.60.184] X-ClientProxiedBy: EXCAS062.cuchost.com (172.16.6.22) To EXMBX061.cuchost.com (172.16.6.61) X-YovoleRuleAgent: yovoleflag X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231025_034044_610219_10A94223 X-CRM114-Status: GOOD ( 25.72 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Implement drm device registration interface Thomas Zimmermann wrote: You are replacing almost all of the GEM DMA object's helper code. Either inherit directly from drm_gem_object drop the dependency entirely, or you could try to fit your code into GEM DMA as well Eventually I found an answer and it was DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE After I adapt this interface, the custom gem logic interfaces can be deleted. It's a big shocking, clap! Signed-off-by: Keith Zhao --- drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/verisilicon/Kconfig | 15 ++ drivers/gpu/drm/verisilicon/Makefile | 7 + drivers/gpu/drm/verisilicon/vs_drv.c | 227 +++++++++++++++++++++++ drivers/gpu/drm/verisilicon/vs_drv.h | 27 +++ drivers/gpu/drm/verisilicon/vs_modeset.c | 36 ++++ drivers/gpu/drm/verisilicon/vs_modeset.h | 10 + include/uapi/drm/vs_drm.h | 50 +++++ 9 files changed, 375 insertions(+) create mode 100644 drivers/gpu/drm/verisilicon/Kconfig create mode 100644 drivers/gpu/drm/verisilicon/Makefile create mode 100644 drivers/gpu/drm/verisilicon/vs_drv.c create mode 100644 drivers/gpu/drm/verisilicon/vs_drv.h create mode 100644 drivers/gpu/drm/verisilicon/vs_modeset.c create mode 100644 drivers/gpu/drm/verisilicon/vs_modeset.h create mode 100644 include/uapi/drm/vs_drm.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index afb3b2f5f..9ede80ef9 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -363,6 +363,8 @@ source "drivers/gpu/drm/solomon/Kconfig" source "drivers/gpu/drm/sprd/Kconfig" +source "drivers/gpu/drm/verisilicon/Kconfig" + config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 7a09a89b4..6db3bc397 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -194,3 +194,4 @@ obj-y += gud/ obj-$(CONFIG_DRM_HYPERV) += hyperv/ obj-y += solomon/ obj-$(CONFIG_DRM_SPRD) += sprd/ +obj-$(CONFIG_DRM_VERISILICON) += verisilicon/ diff --git a/drivers/gpu/drm/verisilicon/Kconfig b/drivers/gpu/drm/verisilicon/Kconfig new file mode 100644 index 000000000..3a361f8c8 --- /dev/null +++ b/drivers/gpu/drm/verisilicon/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 +config DRM_VERISILICON + tristate "DRM Support for VeriSilicon" + depends on DRM + select DRM_KMS_HELPER + select DRM_GEM_DMA_HELPER + select CMA + select DMA_CMA + help + Choose this option if you have a VeriSilicon soc chipset. + This driver provides VeriSilicon kernel mode + setting and buffer management. It does not + provide 2D or 3D acceleration. + + diff --git a/drivers/gpu/drm/verisilicon/Makefile b/drivers/gpu/drm/verisilicon/Makefile new file mode 100644 index 000000000..7d3be305b --- /dev/null +++ b/drivers/gpu/drm/verisilicon/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +vs_drm-objs := vs_drv.o \ + vs_modeset.o + +obj-$(CONFIG_DRM_VERISILICON) += vs_drm.o + diff --git a/drivers/gpu/drm/verisilicon/vs_drv.c b/drivers/gpu/drm/verisilicon/vs_drv.c new file mode 100644 index 000000000..da7698c3d --- /dev/null +++ b/drivers/gpu/drm/verisilicon/vs_drv.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vs_drv.h" +#include "vs_modeset.h" + +#define DRV_NAME "verisilicon" +#define DRV_DESC "Verisilicon DRM driver" +#define DRV_DATE "20230516" +#define DRV_MAJOR 1 +#define DRV_MINOR 0 + +static int vs_gem_dumb_create(struct drm_file *file, struct drm_device *dev, + struct drm_mode_create_dumb *args) +{ + struct vs_drm_device *priv = to_vs_drm_private(dev); + + unsigned int pitch = DIV_ROUND_UP(args->width * args->bpp, 8); + + if (args->bpp % 10) + args->pitch = ALIGN(pitch, priv->pitch_alignment); + else + /* for costum 10bit format with no bit gaps */ + args->pitch = pitch; + + return drm_gem_dma_dumb_create_internal(file, dev, args); +} + +DEFINE_DRM_GEM_FOPS(vs_drm_fops); + +static struct drm_driver vs_drm_driver = { + .driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM, + + DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vs_gem_dumb_create), + + .fops = &vs_drm_fops, + .name = DRV_NAME, + .desc = DRV_DESC, + .date = DRV_DATE, + .major = DRV_MAJOR, + .minor = DRV_MINOR, +}; + +static int vs_drm_bind(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct vs_drm_device *priv; + int ret; + struct drm_device *drm_dev; + + /* Remove existing drivers that may own the framebuffer memory. */ + ret = drm_aperture_remove_framebuffers(&vs_drm_driver); + if (ret) + return ret; + + priv = devm_drm_dev_alloc(dev, &vs_drm_driver, struct vs_drm_device, base); + if (IS_ERR(priv)) + return PTR_ERR(priv); + + priv->pitch_alignment = 64; + + ret = dma_set_coherent_mask(priv->base.dev, DMA_BIT_MASK(40)); + if (ret) + return ret; + + drm_dev = &priv->base; + platform_set_drvdata(pdev, drm_dev); + + vs_mode_config_init(drm_dev); + + /* Now try and bind all our sub-components */ + ret = component_bind_all(dev, drm_dev); + if (ret) + return ret; + + ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc); + if (ret) + return ret; + + drm_mode_config_reset(drm_dev); + + drm_kms_helper_poll_init(drm_dev); + + ret = drm_dev_register(drm_dev, 0); + if (ret) + return ret; + + drm_fbdev_generic_setup(drm_dev, 32); + + return 0; +} + +static void vs_drm_unbind(struct device *dev) +{ + struct drm_device *drm_dev = dev_get_drvdata(dev); + + drm_dev_unregister(drm_dev); + drm_kms_helper_poll_fini(drm_dev); + component_unbind_all(drm_dev->dev, drm_dev); +} + +static const struct component_master_ops vs_drm_ops = { + .bind = vs_drm_bind, + .unbind = vs_drm_unbind, +}; + +static struct platform_driver *drm_sub_drivers[] = { + +}; + +static struct component_match *vs_drm_match_add(struct device *dev) +{ + struct component_match *match = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(drm_sub_drivers); ++i) { + struct platform_driver *drv = drm_sub_drivers[i]; + struct device *p = NULL, *d; + + while ((d = platform_find_device_by_driver(p, &drv->driver))) { + put_device(p); + + component_match_add(dev, &match, component_compare_dev, d); + p = d; + } + put_device(p); + } + + return match ? match : ERR_PTR(-ENODEV); +} + +static int vs_drm_platform_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct component_match *match; + + match = vs_drm_match_add(dev); + if (IS_ERR(match)) + return PTR_ERR(match); + + return component_master_add_with_match(dev, &vs_drm_ops, match); +} + +static int vs_drm_platform_remove(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &vs_drm_ops); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int vs_drm_suspend(struct device *dev) +{ + return drm_mode_config_helper_suspend(dev_get_drvdata(dev)); +} + +static int vs_drm_resume(struct device *dev) +{ + drm_mode_config_helper_resume(dev_get_drvdata(dev)); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(vs_drm_pm_ops, vs_drm_suspend, vs_drm_resume); + +static const struct of_device_id vs_drm_dt_ids[] = { + { .compatible = "starfive,display-subsystem", }, + { }, +}; + +MODULE_DEVICE_TABLE(of, vs_drm_dt_ids); + +static struct platform_driver vs_drm_platform_driver = { + .probe = vs_drm_platform_probe, + .remove = vs_drm_platform_remove, + + .driver = { + .name = DRV_NAME, + .of_match_table = vs_drm_dt_ids, + .pm = &vs_drm_pm_ops, + }, +}; + +static int __init vs_drm_init(void) +{ + int ret; + + ret = platform_register_drivers(drm_sub_drivers, ARRAY_SIZE(drm_sub_drivers)); + if (ret) + return ret; + + ret = drm_platform_driver_register(&vs_drm_platform_driver); + if (ret) + platform_unregister_drivers(drm_sub_drivers, ARRAY_SIZE(drm_sub_drivers)); + + return ret; +} + +static void __exit vs_drm_fini(void) +{ + platform_driver_unregister(&vs_drm_platform_driver); + platform_unregister_drivers(drm_sub_drivers, ARRAY_SIZE(drm_sub_drivers)); +} + +module_init(vs_drm_init); +module_exit(vs_drm_fini); + +MODULE_DESCRIPTION("VeriSilicon DRM Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/verisilicon/vs_drv.h b/drivers/gpu/drm/verisilicon/vs_drv.h new file mode 100644 index 000000000..369ad22d6 --- /dev/null +++ b/drivers/gpu/drm/verisilicon/vs_drv.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. + */ + +#ifndef __VS_DRV_H__ +#define __VS_DRV_H__ + +#include +#include +#include +#include +#include + +/*@pitch_alignment: buffer pitch alignment required by sub-devices.*/ +struct vs_drm_device { + struct drm_device base; + unsigned int pitch_alignment; +}; + +static inline struct vs_drm_device * +to_vs_drm_private(const struct drm_device *dev) +{ + return container_of(dev, struct vs_drm_device, base); +} + +#endif /* __VS_DRV_H__ */ diff --git a/drivers/gpu/drm/verisilicon/vs_modeset.c b/drivers/gpu/drm/verisilicon/vs_modeset.c new file mode 100644 index 000000000..151272067 --- /dev/null +++ b/drivers/gpu/drm/verisilicon/vs_modeset.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. + */ + +#include + +#include +#include +#include + +#include "vs_modeset.h" + +static const struct drm_mode_config_funcs vs_mode_config_funcs = { + .fb_create = drm_gem_fb_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static struct drm_mode_config_helper_funcs vs_mode_config_helpers = { + .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, +}; + +void vs_mode_config_init(struct drm_device *dev) +{ + drm_mode_config_init(dev); + dev->mode_config.fb_modifiers_not_supported = false; + + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + dev->mode_config.max_width = 4096; + dev->mode_config.max_height = 4096; + + dev->mode_config.funcs = &vs_mode_config_funcs; + dev->mode_config.helper_private = &vs_mode_config_helpers; +} diff --git a/drivers/gpu/drm/verisilicon/vs_modeset.h b/drivers/gpu/drm/verisilicon/vs_modeset.h new file mode 100644 index 000000000..ebfe6d612 --- /dev/null +++ b/drivers/gpu/drm/verisilicon/vs_modeset.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 VeriSilicon Holdings Co., Ltd. + */ + +#ifndef __VS_FB_H__ +#define __VS_FB_H__ + +void vs_mode_config_init(struct drm_device *dev); +#endif /* __VS_FB_H__ */ diff --git a/include/uapi/drm/vs_drm.h b/include/uapi/drm/vs_drm.h new file mode 100644 index 000000000..96b7fc95d --- /dev/null +++ b/include/uapi/drm/vs_drm.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (C) 2020 VeriSilicon Holdings Co., Ltd. + */ + +#ifndef __VS_DRM_H__ +#define __VS_DRM_H__ + +#include "drm.h" + +enum drm_vs_degamma_mode { + VS_DEGAMMA_DISABLE = 0, + VS_DEGAMMA_BT709 = 1, + VS_DEGAMMA_BT2020 = 2, +}; + +enum drm_vs_sync_dc_mode { + VS_SINGLE_DC = 0, + VS_MULTI_DC_PRIMARY = 1, + VS_MULTI_DC_SECONDARY = 2, +}; + +enum drm_vs_mmu_prefetch_mode { + VS_MMU_PREFETCH_DISABLE = 0, + VS_MMU_PREFETCH_ENABLE = 1, +}; + +struct drm_vs_watermark { + __u32 watermark; + __u8 qos_low; + __u8 qos_high; +}; + +struct drm_vs_color_mgmt { + __u32 colorkey; + __u32 colorkey_high; + __u32 clear_value; + bool clear_enable; + bool transparency; +}; + +struct drm_vs_roi { + bool enable; + __u16 roi_x; + __u16 roi_y; + __u16 roi_w; + __u16 roi_h; +}; + +#endif /* __VS_DRM_H__ */