From patchwork Fri May 4 13:37:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 10380467 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 2FF386038F for ; Fri, 4 May 2018 13:37:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1CD0227D0C for ; Fri, 4 May 2018 13:37:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1B0D029429; Fri, 4 May 2018 13:37:21 +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.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, MAILING_LIST_MULTI, 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 7B87229468 for ; Fri, 4 May 2018 13:37:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C7A716E8A0; Fri, 4 May 2018 13:37:17 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wr0-x244.google.com (mail-wr0-x244.google.com [IPv6:2a00:1450:400c:c0c::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 421476E898 for ; Fri, 4 May 2018 13:37:16 +0000 (UTC) Received: by mail-wr0-x244.google.com with SMTP id p5-v6so21105382wre.12 for ; Fri, 04 May 2018 06:37:16 -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=p5el8ahHK7y9e6lwQeE8WOZf1nPxnV+qQUf/RmEv/bQ=; b=n01FlU0+c8qtXAji5b/CcxrH9x35lB6Yrdx5RXTXpCy8+Za/W7KSMxKSfpzawVBn/z eluorRcTm+VY8jYyRoPcC7IT6lMjpO16Nd0qUndsTnUbVkRkkSnvjvL8vqZqbnZRNjay 3aDun3/PMlo7div7R9GE5xgiUawkA59LAGbfzh3tucFdkJTOHOilvzNDppu/jEVwjvcK KNH7+08QHpM1cZkJlYcch93gofw/3HLkJam6DMAB4jaq/4b2uzRIYOm1Qb1hNtHKJE4z 08KxkRO6vbRqJQTNAe4n0Tq1aX57w8xKgokpn9hGmNXOnYQ8Ec2kovZQejjMb210yhY1 9kJw== 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=p5el8ahHK7y9e6lwQeE8WOZf1nPxnV+qQUf/RmEv/bQ=; b=rHW46hhcFvE0BoFpfYuFjcA5av60rS2XP/MjZ6EvRDyGRS/UBM5Twjl7bsa4EiW+pt ipMcxTQPQCwPRhL2YxBLZR13rvOQmQb0hRzURhLuWyKH1frhn2iQokjQd8xSjUKAhhg8 Qxh9qDgPh+NMzXzH0YGayEvCzADJgSsxItNcp6mKjrtgN+8ZYYKZrQ4cUunCJfXvgN16 Sm+9Okkqj8A8FX9XuDW7SC0SehXlSLd4kRyzbLJqXyRXQM4M5pENc+QM+aDcVamsPFEE IysVt4wTBnTl0uG5xsL/ukzZctohKtF53sij3Z2e7UB4nmuNLJwALs2XTtVFcEPadZSD NAiQ== X-Gm-Message-State: ALQs6tD2NFl0xIr6R+v/gQoaa08vBsM3dgGDXg2IB5Ni9BDOxGeBXwVD uVFjJwe8PaJ/9R0i2ijSwGg03Q== X-Google-Smtp-Source: AB8JxZo8SSvJGoBrODJgmRpm/9Yy588rtUKRHHXt4oQwXs2E0YzHqpuMFlmEmD/OKp0ej3DkAT6G0g== X-Received: by 2002:adf:86b2:: with SMTP id 47-v6mr21588102wrx.256.1525441034777; Fri, 04 May 2018 06:37:14 -0700 (PDT) Received: from localhost (p200300E41F041C0032947E635CB49D15.dip0.t-ipconnect.de. [2003:e4:1f04:1c00:3294:7e63:5cb4:9d15]) by smtp.gmail.com with ESMTPSA id 12-v6sm2790053wmn.27.2018.05.04.06.37.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 04 May 2018 06:37:14 -0700 (PDT) From: Thierry Reding To: Thierry Reding Subject: [PATCH 4/4] drm/tegra: Refactor IOMMU attach/detach Date: Fri, 4 May 2018 15:37:07 +0200 Message-Id: <20180504133707.22451-4-thierry.reding@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180504133707.22451-1-thierry.reding@gmail.com> References: <20180504133707.22451-1-thierry.reding@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: linux-tegra@vger.kernel.org, Dmitry Osipenko , dri-devel@lists.freedesktop.org MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Thierry Reding Attaching to and detaching from an IOMMU uses the same code sequence in every driver, so factor it out into separate helpers. Signed-off-by: Thierry Reding Reviewed-by: Dmitry Osipenko --- drivers/gpu/drm/tegra/dc.c | 42 ++++++------------------------------ drivers/gpu/drm/tegra/drm.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 4 ++++ drivers/gpu/drm/tegra/gr2d.c | 32 +++++++-------------------- drivers/gpu/drm/tegra/gr3d.c | 31 ++++++-------------------- 5 files changed, 68 insertions(+), 83 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index c843f11043db..3e7ec3937346 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1837,21 +1837,11 @@ static int tegra_dc_init(struct host1x_client *client) if (!dc->syncpt) dev_warn(dc->dev, "failed to allocate syncpoint\n"); - if (tegra->domain) { - dc->group = iommu_group_get(client->dev); - - if (dc->group && dc->group != tegra->group) { - err = iommu_attach_group(tegra->domain, dc->group); - if (err < 0) { - dev_err(dc->dev, - "failed to attach to domain: %d\n", - err); - iommu_group_put(dc->group); - return err; - } - - tegra->group = dc->group; - } + dc->group = host1x_client_iommu_attach(client, true); + if (IS_ERR(dc->group)) { + err = PTR_ERR(dc->group); + dev_err(client->dev, "failed to attach to domain: %d\n", err); + return err; } if (dc->soc->wgrps) @@ -1916,15 +1906,7 @@ static int tegra_dc_init(struct host1x_client *client) if (!IS_ERR(primary)) drm_plane_cleanup(primary); - if (dc->group) { - if (dc->group == tegra->group) { - iommu_detach_group(tegra->domain, dc->group); - tegra->group = NULL; - } - - iommu_group_put(dc->group); - } - + host1x_client_iommu_detach(client, dc->group); host1x_syncpt_free(dc->syncpt); return err; @@ -1932,9 +1914,7 @@ static int tegra_dc_init(struct host1x_client *client) static int tegra_dc_exit(struct host1x_client *client) { - struct drm_device *drm = dev_get_drvdata(client->parent); struct tegra_dc *dc = host1x_client_to_dc(client); - struct tegra_drm *tegra = drm->dev_private; int err; devm_free_irq(dc->dev, dc->irq, dc); @@ -1945,15 +1925,7 @@ static int tegra_dc_exit(struct host1x_client *client) return err; } - if (dc->group) { - if (dc->group == tegra->group) { - iommu_detach_group(tegra->domain, dc->group); - tegra->group = NULL; - } - - iommu_group_put(dc->group); - } - + host1x_client_iommu_detach(client, dc->group); host1x_syncpt_free(dc->syncpt); return 0; diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 7afe2f635f74..bc1008305e1e 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1114,6 +1114,48 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra, return 0; } +struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client, + bool shared) +{ + struct drm_device *drm = dev_get_drvdata(client->parent); + struct tegra_drm *tegra = drm->dev_private; + struct iommu_group *group = NULL; + int err; + + if (tegra->domain) { + group = iommu_group_get(client->dev); + + if (group && (!shared || (shared && (group != tegra->group)))) { + err = iommu_attach_group(tegra->domain, group); + if (err < 0) { + iommu_group_put(group); + return ERR_PTR(err); + } + + if (shared && !tegra->group) + tegra->group = group; + } + } + + return group; +} + +void host1x_client_iommu_detach(struct host1x_client *client, + struct iommu_group *group) +{ + struct drm_device *drm = dev_get_drvdata(client->parent); + struct tegra_drm *tegra = drm->dev_private; + + if (group) { + if (group == tegra->group) { + iommu_detach_group(tegra->domain, group); + tegra->group = NULL; + } + + iommu_group_put(group); + } +} + void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size, dma_addr_t *dma) { struct iova *alloc; diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 4f41aaec8530..fe263cf58f34 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -110,6 +110,10 @@ int tegra_drm_register_client(struct tegra_drm *tegra, struct tegra_drm_client *client); int tegra_drm_unregister_client(struct tegra_drm *tegra, struct tegra_drm_client *client); +struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client, + bool shared); +void host1x_client_iommu_detach(struct host1x_client *client, + struct iommu_group *group); int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm); int tegra_drm_exit(struct tegra_drm *tegra); diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c index 0b42e99da8ad..2cd0f66c8aa9 100644 --- a/drivers/gpu/drm/tegra/gr2d.c +++ b/drivers/gpu/drm/tegra/gr2d.c @@ -32,7 +32,6 @@ static int gr2d_init(struct host1x_client *client) struct tegra_drm_client *drm = host1x_to_drm_client(client); struct drm_device *dev = dev_get_drvdata(client->parent); unsigned long flags = HOST1X_SYNCPT_HAS_BASE; - struct tegra_drm *tegra = dev->dev_private; struct gr2d *gr2d = to_gr2d(drm); int err; @@ -47,22 +46,14 @@ static int gr2d_init(struct host1x_client *client) goto put; } - if (tegra->domain) { - gr2d->group = iommu_group_get(client->dev); - - if (gr2d->group) { - err = iommu_attach_group(tegra->domain, gr2d->group); - if (err < 0) { - dev_err(client->dev, - "failed to attach to domain: %d\n", - err); - iommu_group_put(gr2d->group); - goto free; - } - } + gr2d->group = host1x_client_iommu_attach(client, false); + if (IS_ERR(gr2d->group)) { + err = PTR_ERR(gr2d->group); + dev_err(client->dev, "failed to attach to domain: %d\n", err); + goto free; } - err = tegra_drm_register_client(tegra, drm); + err = tegra_drm_register_client(dev->dev_private, drm); if (err < 0) { dev_err(client->dev, "failed to register client: %d\n", err); goto detach; @@ -71,10 +62,7 @@ static int gr2d_init(struct host1x_client *client) return 0; detach: - if (gr2d->group) { - iommu_detach_group(tegra->domain, gr2d->group); - iommu_group_put(gr2d->group); - } + host1x_client_iommu_detach(client, gr2d->group); free: host1x_syncpt_free(client->syncpts[0]); put: @@ -94,14 +82,10 @@ static int gr2d_exit(struct host1x_client *client) if (err < 0) return err; + host1x_client_iommu_detach(client, gr2d->group); host1x_syncpt_free(client->syncpts[0]); host1x_channel_put(gr2d->channel); - if (gr2d->group) { - iommu_detach_group(tegra->domain, gr2d->group); - iommu_group_put(gr2d->group); - } - return 0; } diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index e129f1afff33..98e3c67d0fb5 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -42,7 +42,6 @@ static int gr3d_init(struct host1x_client *client) struct tegra_drm_client *drm = host1x_to_drm_client(client); struct drm_device *dev = dev_get_drvdata(client->parent); unsigned long flags = HOST1X_SYNCPT_HAS_BASE; - struct tegra_drm *tegra = dev->dev_private; struct gr3d *gr3d = to_gr3d(drm); int err; @@ -56,19 +55,11 @@ static int gr3d_init(struct host1x_client *client) goto put; } - if (tegra->domain) { - gr3d->group = iommu_group_get(client->dev); - - if (gr3d->group) { - err = iommu_attach_group(tegra->domain, gr3d->group); - if (err < 0) { - dev_err(client->dev, - "failed to attach to domain: %d\n", - err); - iommu_group_put(gr3d->group); - goto free; - } - } + gr3d->group = host1x_client_iommu_attach(client, false); + if (IS_ERR(gr3d->group)) { + err = PTR_ERR(gr3d->group); + dev_err(client->dev, "failed to attach to domain: %d\n", err); + goto free; } err = tegra_drm_register_client(dev->dev_private, drm); @@ -80,10 +71,7 @@ static int gr3d_init(struct host1x_client *client) return 0; detach: - if (gr3d->group) { - iommu_detach_group(tegra->domain, gr3d->group); - iommu_group_put(gr3d->group); - } + host1x_client_iommu_detach(client, gr3d->group); free: host1x_syncpt_free(client->syncpts[0]); put: @@ -95,7 +83,6 @@ static int gr3d_exit(struct host1x_client *client) { struct tegra_drm_client *drm = host1x_to_drm_client(client); struct drm_device *dev = dev_get_drvdata(client->parent); - struct tegra_drm *tegra = dev->dev_private; struct gr3d *gr3d = to_gr3d(drm); int err; @@ -103,14 +90,10 @@ static int gr3d_exit(struct host1x_client *client) if (err < 0) return err; + host1x_client_iommu_detach(client, gr3d->group); host1x_syncpt_free(client->syncpts[0]); host1x_channel_put(gr3d->channel); - if (gr3d->group) { - iommu_detach_group(tegra->domain, gr3d->group); - iommu_group_put(gr3d->group); - } - return 0; }