From patchwork Mon Dec 3 21:18:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Marek X-Patchwork-Id: 10711313 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6751715A6 for ; Tue, 4 Dec 2018 08:32:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C5282A50D for ; Tue, 4 Dec 2018 08:32:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 506132A513; Tue, 4 Dec 2018 08:32:47 +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=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 F3AA42A50D for ; Tue, 4 Dec 2018 08:32:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 325EE6E21A; Tue, 4 Dec 2018 08:32:18 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qt1-x841.google.com (mail-qt1-x841.google.com [IPv6:2607:f8b0:4864:20::841]) by gabe.freedesktop.org (Postfix) with ESMTPS id AAE1289C07 for ; Mon, 3 Dec 2018 21:21:09 +0000 (UTC) Received: by mail-qt1-x841.google.com with SMTP id i7so15584080qtj.10 for ; Mon, 03 Dec 2018 13:21:09 -0800 (PST) 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; bh=bxnZOVi3Uenah6dbS+lwc/jQi8hk5u9BafXjIbd1zAc=; b=agjx2oQamIyFB+lYfJ4r5KqE7PqDjg/VTvy/D9pK+DeRFtNURRAsPKSlO2VolxRpkk RkuxoWt8WbABOWNVRBvoiLodm8UqLASe1D59TbqSj5XQlbyZzjwyAJGoPPk4jPPC+ODp M4EK7aI8zQeZjLEMYNCn1rxLs1QpgznCQYe0K5P/N9d2RvoJ2AJCBX4X5ca17mFMZ8Fs g0pslWFyFYa1dLbvGVLE+qwbFOjBp5uiM4zyIFP1PKmgclHg/bx/NSHOEV6Z+obruclp azne10ibtMuPgSoukFlnS4tspUlcJX9R4Oap6K2AbAz4/nD6HEFV+nazDXYSX2wiSBUA khBw== X-Gm-Message-State: AA+aEWblZGRkAss+UMMx87yXwQv+TNJsUB04/MZkYktvMdx0OYshorZd 6zaUbg0OrQ9Q+3LDM8tpch/d5w== X-Google-Smtp-Source: AFSGD/VbKX+bEZbWwsnYJwwEHgDqVe5acSmApsDB5eSgp8RD/w9AzfDwj2Y4Gfz0FzfZdKtIOzz5UQ== X-Received: by 2002:a0c:9531:: with SMTP id l46mr17045875qvl.175.1543872068753; Mon, 03 Dec 2018 13:21:08 -0800 (PST) Received: from localhost.localdomain (modemcable014.247-57-74.mc.videotron.ca. [74.57.247.14]) by smtp.gmail.com with ESMTPSA id l33sm10567353qta.57.2018.12.03.13.21.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 13:21:07 -0800 (PST) From: Jonathan Marek To: freedreno@lists.freedesktop.org Subject: [PATCH v3 1/4] drm/msm/mdp4: add lcdc-align-lsb flag to control lane alignment Date: Mon, 3 Dec 2018 16:18:13 -0500 Message-Id: <20181203211816.5129-1-jonathan@marek.ca> X-Mailer: git-send-email 2.17.1 X-Mailman-Approved-At: Tue, 04 Dec 2018 08:32:02 +0000 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: Mark Rutland , "open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" , David Airlie , "open list:DRM DRIVER FOR MSM ADRENO GPU" , open list , "open list:DRM DRIVER FOR MSM ADRENO GPU" , Rob Herring , Sean Paul , Chris.Healy@zii.aero MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This allows controlling which of the 8 lanes are used for 6 bit color. Signed-off-by: Jonathan Marek --- v3: removed empty line and added documentation .../devicetree/bindings/display/msm/mdp4.txt | 2 ++ .../gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/mdp4.txt b/Documentation/devicetree/bindings/display/msm/mdp4.txt index 3c341a15c..b07eeb38f 100644 --- a/Documentation/devicetree/bindings/display/msm/mdp4.txt +++ b/Documentation/devicetree/bindings/display/msm/mdp4.txt @@ -38,6 +38,8 @@ Required properties: Optional properties: - clock-names: the following clocks are optional: * "lut_clk" +- qcom,lcdc-align-lsb: Boolean value indicating that LSB alignment should be + used for LCDC. This is only valid for 18bpp panels. Example: diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c index 9e08c2efa..c9e34501a 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c @@ -377,20 +377,25 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) unsigned long pc = mdp4_lcdc_encoder->pixclock; struct mdp4_kms *mdp4_kms = get_kms(encoder); struct drm_panel *panel; + uint32_t config; int i, ret; if (WARN_ON(mdp4_lcdc_encoder->enabled)) return; /* TODO: hard-coded for 18bpp: */ - mdp4_crtc_set_config(encoder->crtc, - MDP4_DMA_CONFIG_R_BPC(BPC6) | - MDP4_DMA_CONFIG_G_BPC(BPC6) | - MDP4_DMA_CONFIG_B_BPC(BPC6) | - MDP4_DMA_CONFIG_PACK_ALIGN_MSB | - MDP4_DMA_CONFIG_PACK(0x21) | - MDP4_DMA_CONFIG_DEFLKR_EN | - MDP4_DMA_CONFIG_DITHER_EN); + config = + MDP4_DMA_CONFIG_R_BPC(BPC6) | + MDP4_DMA_CONFIG_G_BPC(BPC6) | + MDP4_DMA_CONFIG_B_BPC(BPC6) | + MDP4_DMA_CONFIG_PACK(0x21) | + MDP4_DMA_CONFIG_DEFLKR_EN | + MDP4_DMA_CONFIG_DITHER_EN; + + if (!of_property_read_bool(dev->dev->of_node, "qcom,lcdc-align-lsb")) + config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB; + + mdp4_crtc_set_config(encoder->crtc, config); mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); bs_set(mdp4_lcdc_encoder, 1); From patchwork Mon Dec 3 21:18:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Marek X-Patchwork-Id: 10711303 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BF09C15A6 for ; Tue, 4 Dec 2018 08:32:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B341C2A50D for ; Tue, 4 Dec 2018 08:32:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A78D72A516; Tue, 4 Dec 2018 08:32:23 +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=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 261812A50D for ; Tue, 4 Dec 2018 08:32:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2748D6E19C; Tue, 4 Dec 2018 08:32:04 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qt1-x843.google.com (mail-qt1-x843.google.com [IPv6:2607:f8b0:4864:20::843]) by gabe.freedesktop.org (Postfix) with ESMTPS id 40E0E89C0D for ; Mon, 3 Dec 2018 21:21:11 +0000 (UTC) Received: by mail-qt1-x843.google.com with SMTP id y20so15578368qtm.13 for ; Mon, 03 Dec 2018 13:21:11 -0800 (PST) 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=Ko4Y7Uyh13FJDGl/9r6xGDDp7+352wGvWojGv/9q9YQ=; b=fBDVK8QGlYr2iCNqvX5r6H9YdTbgmtR5s4NPgccyLN8y9gVB7PKKf374I2XtFPnFyt Gnl2rmiK9xeuOezW7VGHNj7CalZ1kFFOO++AEVkhytPs4uO4sCojOe6Rz4sqkH51LVjU CioCBNhJUsMrkrMcwI1isUtqtjmMiY+wbm2H8+j7U5AprgIA2j2U7HItguoogpWZgJO0 bKkfyN65o9hVFLnqetmiUZ3BnStNVtJEge6u7GXIAXS38FxeXCDHNSFNeeW7rPa9vB4g Qp/d0nJi/bllNlbPbkuAAqLhLzswh5THGT+VydlLzD/zvwbQlG8vBzT7j+yhsxLwj4WX y/0Q== X-Gm-Message-State: AA+aEWar2FQH8rc6RtE7U0OCjhigjqWpv3kOixYeoxZjXuUGHSbjmCXR ABlIg7FezzYqS+SlOUU8M+vdyg== X-Google-Smtp-Source: AFSGD/ULaPIfuO54XOKaSk4ZI2sC2bVpOb25YKfONIqrrPFlk5Ow6ZNcdetFX0NLnOzOhkaVCHDUXA== X-Received: by 2002:ac8:4901:: with SMTP id e1mr16673596qtq.244.1543872070396; Mon, 03 Dec 2018 13:21:10 -0800 (PST) Received: from localhost.localdomain (modemcable014.247-57-74.mc.videotron.ca. [74.57.247.14]) by smtp.gmail.com with ESMTPSA id l33sm10567353qta.57.2018.12.03.13.21.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 13:21:09 -0800 (PST) From: Jonathan Marek To: freedreno@lists.freedesktop.org Subject: [PATCH v3 2/4] drm/msm: add headless gpu device for imx5 Date: Mon, 3 Dec 2018 16:18:14 -0500 Message-Id: <20181203211816.5129-2-jonathan@marek.ca> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181203211816.5129-1-jonathan@marek.ca> References: <20181203211816.5129-1-jonathan@marek.ca> X-Mailman-Approved-At: Tue, 04 Dec 2018 08:32:02 +0000 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: David Airlie , "open list:DRM DRIVER FOR MSM ADRENO GPU" , open list , "open list:DRM DRIVER FOR MSM ADRENO GPU" , Sean Paul , Chris.Healy@zii.aero MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch allows using drm/msm without qcom display hardware. It adds a amd,imageon compatible, which is used instead of qcom,adreno, but does not require a top level msm node. Signed-off-by: Jonathan Marek --- v3: reworked to work with only a amd,imageon node drivers/gpu/drm/msm/Kconfig | 4 +-- drivers/gpu/drm/msm/adreno/adreno_device.c | 35 ++++++++++++++++++++-- drivers/gpu/drm/msm/msm_debugfs.c | 2 +- drivers/gpu/drm/msm/msm_drv.c | 21 +++++++------ 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 843a9d40c..cf549f1ed 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -2,7 +2,7 @@ config DRM_MSM tristate "MSM DRM" depends on DRM - depends on ARCH_QCOM || (ARM && COMPILE_TEST) + depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST) depends on OF && COMMON_CLK depends on MMU select QCOM_MDT_LOADER if ARCH_QCOM @@ -11,7 +11,7 @@ config DRM_MSM select DRM_PANEL select SHMEM select TMPFS - select QCOM_SCM + select QCOM_SCM if ARCH_QCOM select WANT_DEV_COREDUMP select SND_SOC_HDMI_CODEC if SND_SOC select SYNC_FILE diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index adc442f73..99e363c3d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -271,7 +271,8 @@ static int find_chipid(struct device *dev, struct adreno_rev *rev) if (ret == 0) { unsigned int r, patch; - if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2) { + if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2 || + sscanf(compat, "amd,imageon-%u.%u", &r, &patch) == 2) { rev->core = r / 100; r %= 100; rev->major = r / 10; @@ -356,9 +357,37 @@ static const struct component_ops a3xx_ops = { .unbind = adreno_unbind, }; +static void adreno_device_register_headless(void) +{ + /* on imx5, we don't have a top-level mdp/dpu node + * this creates a dummy node for the driver for that case + */ + struct platform_device_info dummy_info = { + .parent = NULL, + .name = "msm", + .id = -1, + .res = NULL, + .num_res = 0, + .data = NULL, + .size_data = 0, + .dma_mask = ~0, + }; + platform_device_register_full(&dummy_info); +} + static int adreno_probe(struct platform_device *pdev) { - return component_add(&pdev->dev, &a3xx_ops); + + int ret; + + ret = component_add(&pdev->dev, &a3xx_ops); + if (ret) + return ret; + + if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon")) + adreno_device_register_headless(); + + return 0; } static int adreno_remove(struct platform_device *pdev) @@ -370,6 +399,8 @@ static int adreno_remove(struct platform_device *pdev) static const struct of_device_id dt_match[] = { { .compatible = "qcom,adreno" }, { .compatible = "qcom,adreno-3xx" }, + /* for compatibility with imx5 gpu: */ + { .compatible = "amd,imageon" }, /* for backwards compat w/ downstream kgsl DT files: */ { .compatible = "qcom,kgsl-3d0" }, {} diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 9a7cf9fe2..fb423d309 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -242,7 +242,7 @@ int msm_debugfs_init(struct drm_minor *minor) debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root, dev, &msm_gpu_fops); - if (priv->kms->funcs->debugfs_init) { + if (priv->kms && priv->kms->funcs->debugfs_init) { ret = priv->kms->funcs->debugfs_init(priv->kms, minor); if (ret) return ret; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 81bfac744..7842518a9 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -510,17 +510,13 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) priv->kms = kms; break; default: - kms = ERR_PTR(-ENODEV); + /* valid only for the dummy headless case, where of_node=NULL */ + WARN_ON(dev->of_node); + kms = NULL; break; } if (IS_ERR(kms)) { - /* - * NOTE: once we have GPU support, having no kms should not - * be considered fatal.. ideally we would still support gpu - * and (for example) use dmabuf/prime to share buffers with - * imx drm driver on iMX5 - */ DRM_DEV_ERROR(dev, "failed to load kms\n"); ret = PTR_ERR(kms); priv->kms = NULL; @@ -620,7 +616,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) drm_mode_config_reset(ddev); #ifdef CONFIG_DRM_FBDEV_EMULATION - if (fbdev) + if (kms && fbdev) priv->fbdev = msm_fbdev_init(ddev); #endif @@ -1302,6 +1298,7 @@ static int add_display_components(struct device *dev, static const struct of_device_id msm_gpu_match[] = { { .compatible = "qcom,adreno" }, { .compatible = "qcom,adreno-3xx" }, + { .compatible = "amd,imageon" }, { .compatible = "qcom,kgsl-3d0" }, { }, }; @@ -1346,9 +1343,11 @@ static int msm_pdev_probe(struct platform_device *pdev) struct component_match *match = NULL; int ret; - ret = add_display_components(&pdev->dev, &match); - if (ret) - return ret; + if (get_mdp_ver(pdev)) { + ret = add_display_components(&pdev->dev, &match); + if (ret) + return ret; + } ret = add_gpu_components(&pdev->dev, &match); if (ret) From patchwork Mon Dec 3 21:18:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Marek X-Patchwork-Id: 10711311 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DCDF215A6 for ; Tue, 4 Dec 2018 08:32:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CF8B32A50D for ; Tue, 4 Dec 2018 08:32:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3CA82A513; Tue, 4 Dec 2018 08:32:43 +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=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 D4DB52A50D for ; Tue, 4 Dec 2018 08:32:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1D2696E1E2; Tue, 4 Dec 2018 08:32:16 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qt1-x844.google.com (mail-qt1-x844.google.com [IPv6:2607:f8b0:4864:20::844]) by gabe.freedesktop.org (Postfix) with ESMTPS id B20DB89F6B for ; Mon, 3 Dec 2018 21:21:13 +0000 (UTC) Received: by mail-qt1-x844.google.com with SMTP id n21so15594635qtl.6 for ; Mon, 03 Dec 2018 13:21:13 -0800 (PST) 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=nMp+bo1u4Ju+AOZGqXFZCxG0+uZcT9bJyW5D89nvzhA=; b=V4svXblEQ/sTCPPVRqzt1w0Qrzbt/DHs3m9r2PuLWgewXp1CqilzYmf8c22zmpXAtK mmQrWHjDn+LLuP/3WhCvjmGn0KA5l+47d8K2kRMNcNs0V963B9dp2yYLdZ6WvkAKIZO0 UewB9qes6zUSkYiYaI6iGfVy0JYE+rY2h0hlFeJ7itgNoZNs6tdoq/3vzCv9Up9WqzZT 3MsjBPZJDLTM+2mLTNYotq4S+ifWe/O11FexQxjPUaTNRqW37f2wSm3jI0qVqNWzJSWe WD/VnJHETT55ySV/pdaJno2FLktZE5xtUFcIvFVYyxap58+L50svoIjjD2aQHv6eQEby n45w== X-Gm-Message-State: AA+aEWabuzDhtZBl069smj1Q0mjkkaH8zBS/11JDWlnpiCkaH9Ba4G1T JlKincv5Jre5Rk3zx+ef96P1yQ== X-Google-Smtp-Source: AFSGD/UudsWnt/DoYEW2/Yf6qcZEh9EktY3t5v/ilTja8ihdWbyqKWjjAh7WJ1Z+u9o4FQEdRO42ww== X-Received: by 2002:aed:2b64:: with SMTP id p91mr15819613qtd.94.1543872072631; Mon, 03 Dec 2018 13:21:12 -0800 (PST) Received: from localhost.localdomain (modemcable014.247-57-74.mc.videotron.ca. [74.57.247.14]) by smtp.gmail.com with ESMTPSA id l33sm10567353qta.57.2018.12.03.13.21.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 13:21:12 -0800 (PST) From: Jonathan Marek To: freedreno@lists.freedesktop.org Subject: [PATCH v3 3/4] drm/msm: implement a2xx mmu Date: Mon, 3 Dec 2018 16:18:15 -0500 Message-Id: <20181203211816.5129-3-jonathan@marek.ca> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181203211816.5129-1-jonathan@marek.ca> References: <20181203211816.5129-1-jonathan@marek.ca> X-Mailman-Approved-At: Tue, 04 Dec 2018 08:32:02 +0000 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: David Airlie , "open list:DRM DRIVER FOR MSM ADRENO GPU" , open list , "open list:DRM DRIVER FOR MSM ADRENO GPU" , Sean Paul , Chris.Healy@zii.aero MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP A2XX has its own very simple MMU. Added a msm_use_mmu() function because we can't rely on iommu_present to decide to use MMU or not. Signed-off-by: Jonathan Marek --- v3: rebased on msm-next-staging and moved is_a2xx initialization earlier drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 50 ++++++++- drivers/gpu/drm/msm/adreno/adreno_device.c | 3 + drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 + drivers/gpu/drm/msm/msm_drv.c | 11 +- drivers/gpu/drm/msm/msm_drv.h | 8 ++ drivers/gpu/drm/msm/msm_gem.c | 4 +- drivers/gpu/drm/msm/msm_gem_vma.c | 23 ++++ drivers/gpu/drm/msm/msm_gpu.c | 31 ++++-- drivers/gpu/drm/msm/msm_gpummu.c | 122 +++++++++++++++++++++ drivers/gpu/drm/msm/msm_mmu.h | 3 + 11 files changed, 241 insertions(+), 20 deletions(-) create mode 100644 drivers/gpu/drm/msm/msm_gpummu.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 61e76f87a..1b26c4105 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -93,7 +93,8 @@ msm-y := \ msm_rd.o \ msm_ringbuffer.o \ msm_submitqueue.o \ - msm_gpu_tracepoints.o + msm_gpu_tracepoints.o \ + msm_gpummu.o msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \ disp/dpu1/dpu_dbg.o diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index 5eddcf14e..1f83bc18d 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -2,6 +2,8 @@ /* Copyright (c) 2018 The Linux Foundation. All rights reserved. */ #include "a2xx_gpu.h" +#include "msm_gem.h" +#include "msm_mmu.h" extern bool hang_debug; @@ -58,9 +60,12 @@ static bool a2xx_me_init(struct msm_gpu *gpu) static int a2xx_hw_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + dma_addr_t pt_base, tran_error; uint32_t *ptr, len; int i, ret; + msm_gpummu_params(gpu->aspace->mmu, &pt_base, &tran_error); + DBG("%s", gpu->name); /* halt ME to avoid ucode upload issues on a20x */ @@ -80,9 +85,34 @@ static int a2xx_hw_init(struct msm_gpu *gpu) /* note: kgsl uses 0x0000ffff for a20x */ gpu_write(gpu, REG_A2XX_RBBM_CNTL, 0x00004442); - gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, 0); - gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0); + /* MPU: physical range */ + gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0x00000000); gpu_write(gpu, REG_A2XX_MH_MMU_MPU_END, 0xfffff000); + + gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, A2XX_MH_MMU_CONFIG_MMU_ENABLE | + A2XX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(BEH_TRAN_RNG)); + + /* same as parameters in adreno_gpu */ + gpu_write(gpu, REG_A2XX_MH_MMU_VA_RANGE, SZ_16M | + A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS(0xfff)); + + gpu_write(gpu, REG_A2XX_MH_MMU_PT_BASE, pt_base); + gpu_write(gpu, REG_A2XX_MH_MMU_TRAN_ERROR, tran_error); + + gpu_write(gpu, REG_A2XX_MH_MMU_INVALIDATE, + A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL | + A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC); + gpu_write(gpu, REG_A2XX_MH_ARBITER_CONFIG, A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT(16) | A2XX_MH_ARBITER_CONFIG_L1_ARB_ENABLE | @@ -109,9 +139,21 @@ static int a2xx_hw_init(struct msm_gpu *gpu) /* note: gsl doesn't set this */ gpu_write(gpu, REG_A2XX_RBBM_DEBUG, 0x00080000); - gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL, 0); - gpu_write(gpu, REG_AXXX_CP_INT_CNTL, 0x80000000); /* RB INT */ + gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL, + A2XX_RBBM_INT_CNTL_RDERR_INT_MASK); + gpu_write(gpu, REG_AXXX_CP_INT_CNTL, + AXXX_CP_INT_CNTL_T0_PACKET_IN_IB_MASK | + AXXX_CP_INT_CNTL_OPCODE_ERROR_MASK | + AXXX_CP_INT_CNTL_PROTECTED_MODE_ERROR_MASK | + AXXX_CP_INT_CNTL_RESERVED_BIT_ERROR_MASK | + AXXX_CP_INT_CNTL_IB_ERROR_MASK | + AXXX_CP_INT_CNTL_IB1_INT_MASK | + AXXX_CP_INT_CNTL_RB_INT_MASK); gpu_write(gpu, REG_A2XX_SQ_INT_CNTL, 0); + gpu_write(gpu, REG_A2XX_MH_INTERRUPT_MASK, + A2XX_MH_INTERRUPT_MASK_AXI_READ_ERROR | + A2XX_MH_INTERRUPT_MASK_AXI_WRITE_ERROR | + A2XX_MH_INTERRUPT_MASK_MMU_PAGE_FAULT); for (i = 3; i <= 5; i++) if ((SZ_16K << i) == adreno_gpu->gmem) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 99e363c3d..714ed6505 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -308,6 +308,7 @@ static int adreno_bind(struct device *dev, struct device *master, void *data) static struct adreno_platform_config config = {}; const struct adreno_info *info; struct drm_device *drm = dev_get_drvdata(master); + struct msm_drm_private *priv = drm->dev_private; struct msm_gpu *gpu; int ret; @@ -330,6 +331,8 @@ static int adreno_bind(struct device *dev, struct device *master, void *data) DBG("Found GPU: %u.%u.%u.%u", config.rev.core, config.rev.major, config.rev.minor, config.rev.patchid); + priv->is_a2xx = config.rev.core == 2; + gpu = info->init(drm); if (IS_ERR(gpu)) { dev_warn(drm->dev, "failed to load adreno gpu\n"); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 9ab67dd1b..2e4372ef1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -769,6 +769,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, adreno_gpu_config.va_start = SZ_16M; adreno_gpu_config.va_end = 0xffffffff; + /* maximum range of a2xx mmu */ + if (adreno_is_a2xx(adreno_gpu)) + adreno_gpu_config.va_end = SZ_16M + 0xfff * SZ_64K; adreno_gpu_config.nr_rings = nr_rings; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 7842518a9..271f1df61 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -26,6 +26,7 @@ #include "msm_gem.h" #include "msm_gpu.h" #include "msm_kms.h" +#include "adreno/adreno_gpu.h" /* @@ -360,6 +361,14 @@ static int get_mdp_ver(struct platform_device *pdev) #include +bool msm_use_mmu(struct drm_device *dev) +{ + struct msm_drm_private *priv = dev->dev_private; + + /* a2xx comes with its own MMU */ + return priv->is_a2xx || iommu_present(&platform_bus_type); +} + static int msm_init_vram(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -398,7 +407,7 @@ static int msm_init_vram(struct drm_device *dev) * Grab the entire CMA chunk carved out in early startup in * mach-msm: */ - } else if (!iommu_present(&platform_bus_type)) { + } else if (!msm_use_mmu(dev)) { DRM_INFO("using %s VRAM carveout\n", vram); size = memparse(vram, NULL); } diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 71a03ce21..9cd6a96c6 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -179,6 +179,8 @@ struct msm_drm_private { /* when we have more than one 'msm_gpu' these need to be an array: */ struct msm_gpu *gpu; struct msm_file_private *lastctx; + /* gpu is only set on open(), but we need this info earlier */ + bool is_a2xx; struct drm_fb_helper *fbdev; @@ -258,9 +260,15 @@ struct msm_gem_address_space * msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, const char *name); +struct msm_gem_address_space * +msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu, + const char *name, uint64_t va_start, uint64_t va_end); + int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu); +bool msm_use_mmu(struct drm_device *dev); + void msm_gem_submit_free(struct msm_gem_submit *submit); int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 38b7f4e9e..51a95da69 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -975,7 +975,7 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, size = PAGE_ALIGN(size); - if (!iommu_present(&platform_bus_type)) + if (!msm_use_mmu(dev)) use_vram = true; else if ((flags & (MSM_BO_STOLEN | MSM_BO_SCANOUT)) && priv->vram.size) use_vram = true; @@ -1052,7 +1052,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, int ret, npages; /* if we don't have IOMMU, don't bother pretending we can import: */ - if (!iommu_present(&platform_bus_type)) { + if (!msm_use_mmu(dev)) { DRM_DEV_ERROR(dev->dev, "cannot import without IOMMU\n"); return ERR_PTR(-EINVAL); } diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index ee46d8321..557360788 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -159,3 +159,26 @@ msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, return aspace; } + +struct msm_gem_address_space * +msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu, + const char *name, uint64_t va_start, uint64_t va_end) +{ + struct msm_gem_address_space *aspace; + u64 size = va_end - va_start; + + aspace = kzalloc(sizeof(*aspace), GFP_KERNEL); + if (!aspace) + return ERR_PTR(-ENOMEM); + + spin_lock_init(&aspace->lock); + aspace->name = name; + aspace->mmu = msm_gpummu_new(dev, gpu); + + drm_mm_init(&aspace->mm, (va_start >> PAGE_SHIFT), + size >> PAGE_SHIFT); + + kref_init(&aspace->kref); + + return aspace; +} diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index c1968d63b..5f3eff304 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -20,6 +20,7 @@ #include "msm_mmu.h" #include "msm_fence.h" #include "msm_gpu_trace.h" +#include "adreno/adreno_gpu.h" #include #include @@ -825,7 +826,6 @@ static struct msm_gem_address_space * msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev, uint64_t va_start, uint64_t va_end) { - struct iommu_domain *iommu; struct msm_gem_address_space *aspace; int ret; @@ -834,20 +834,27 @@ msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev, * and have separate page tables per context. For now, to keep things * simple and to get something working, just use a single address space: */ - iommu = iommu_domain_alloc(&platform_bus_type); - if (!iommu) - return NULL; - - iommu->geometry.aperture_start = va_start; - iommu->geometry.aperture_end = va_end; - - DRM_DEV_INFO(gpu->dev->dev, "%s: using IOMMU\n", gpu->name); + if (!adreno_is_a2xx(to_adreno_gpu(gpu))) { + struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type); + if (!iommu) + return NULL; + + iommu->geometry.aperture_start = va_start; + iommu->geometry.aperture_end = va_end; + + DRM_DEV_INFO(gpu->dev->dev, "%s: using IOMMU\n", gpu->name); + + aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu"); + if (IS_ERR(aspace)) + iommu_domain_free(iommu); + } else { + aspace = msm_gem_address_space_create_a2xx(&pdev->dev, gpu, "gpu", + va_start, va_end); + } - aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu"); if (IS_ERR(aspace)) { - DRM_DEV_ERROR(gpu->dev->dev, "failed to init iommu: %ld\n", + DRM_DEV_ERROR(gpu->dev->dev, "failed to init mmu: %ld\n", PTR_ERR(aspace)); - iommu_domain_free(iommu); return ERR_CAST(aspace); } diff --git a/drivers/gpu/drm/msm/msm_gpummu.c b/drivers/gpu/drm/msm/msm_gpummu.c new file mode 100644 index 000000000..a04a64faa --- /dev/null +++ b/drivers/gpu/drm/msm/msm_gpummu.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */ + +#include "msm_drv.h" +#include "msm_mmu.h" +#include "adreno/adreno_gpu.h" +#include "adreno/a2xx.xml.h" + +struct msm_gpummu { + struct msm_mmu base; + struct msm_gpu *gpu; + dma_addr_t pt_base; + uint32_t *table; +}; +#define to_msm_gpummu(x) container_of(x, struct msm_gpummu, base) + +#define VA_START SZ_16M +#define VA_RANGE (0xfff * SZ_64K) +#define MMU_PAGE_SIZE SZ_4K +#define TABLE_SIZE (sizeof(uint32_t) * VA_RANGE / MMU_PAGE_SIZE) + +static int msm_gpummu_attach(struct msm_mmu *mmu, const char * const *names, + int cnt) +{ + return 0; +} + +static void msm_gpummu_detach(struct msm_mmu *mmu, const char * const *names, + int cnt) +{ +} + +static void update_pt(struct msm_mmu *mmu, uint64_t iova, + struct sg_table *sgt, unsigned len, unsigned prot) +{ + struct msm_gpummu *gpummu = to_msm_gpummu(mmu); + unsigned idx = (iova - VA_START) / MMU_PAGE_SIZE; + struct scatterlist *sg; + unsigned i, j; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + dma_addr_t addr = sg->dma_address; + for (j = 0; j < sg->length / MMU_PAGE_SIZE; j++, idx++) { + gpummu->table[idx] = prot ? addr | prot : 0; + addr += MMU_PAGE_SIZE; + } + } + + /* flush the tlb everytime the page table is updated + * we can probably do something smarter + */ + gpu_write(gpummu->gpu, REG_A2XX_MH_MMU_INVALIDATE, + A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL | + A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC); +} + +static int msm_gpummu_map(struct msm_mmu *mmu, uint64_t iova, + struct sg_table *sgt, unsigned len, int prot) +{ + unsigned prot_bits = 0; + if (prot & IOMMU_WRITE) + prot_bits |= 1; + if (prot & IOMMU_READ) + prot_bits |= 2; + update_pt(mmu, iova, sgt, len, prot_bits); + return 0; +} + +static int msm_gpummu_unmap(struct msm_mmu *mmu, uint64_t iova, + struct sg_table *sgt, unsigned len) +{ + update_pt(mmu, iova, sgt, len, 0); + return 0; +} + +static void msm_gpummu_destroy(struct msm_mmu *mmu) +{ + struct msm_gpummu *gpummu = to_msm_gpummu(mmu); + + dma_free_attrs(mmu->dev, TABLE_SIZE, gpummu->table, gpummu->pt_base, + DMA_ATTR_FORCE_CONTIGUOUS); + + kfree(gpummu); +} + +static const struct msm_mmu_funcs funcs = { + .attach = msm_gpummu_attach, + .detach = msm_gpummu_detach, + .map = msm_gpummu_map, + .unmap = msm_gpummu_unmap, + .destroy = msm_gpummu_destroy, +}; + +struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu) +{ + struct msm_gpummu *gpummu; + + gpummu = kzalloc(sizeof(*gpummu), GFP_KERNEL); + if (!gpummu) + return ERR_PTR(-ENOMEM); + + gpummu->table = dma_alloc_attrs(dev, TABLE_SIZE + 32, &gpummu->pt_base, + GFP_KERNEL | __GFP_ZERO, DMA_ATTR_FORCE_CONTIGUOUS); + if (!gpummu->table) { + kfree(gpummu); + return ERR_PTR(-ENOMEM); + } + + gpummu->gpu = gpu; + msm_mmu_init(&gpummu->base, dev, &funcs); + + return &gpummu->base; +} + +void msm_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base, + dma_addr_t *tran_error) +{ + dma_addr_t base = to_msm_gpummu(mmu)->pt_base; + + *pt_base = base; + *tran_error = base + TABLE_SIZE; /* 32-byte aligned */ +} diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index 94c0b83d8..d21b26604 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h @@ -53,4 +53,7 @@ static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg, mmu->handler = handler; } +void msm_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base, + dma_addr_t *tran_error); + #endif /* __MSM_MMU_H__ */