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: 908725 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="n01FlU0+"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40ctNY29nfz9s3Z for ; Fri, 4 May 2018 23:37:17 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751277AbeEDNhQ (ORCPT ); Fri, 4 May 2018 09:37:16 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:34641 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751114AbeEDNhQ (ORCPT ); Fri, 4 May 2018 09:37:16 -0400 Received: by mail-wr0-f196.google.com with SMTP id p18-v6so21159845wrm.1 for ; Fri, 04 May 2018 06:37:15 -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=HpeA1P5+XGh3rwOSW2KjKm1DZNR5Qtiikp3rdBgnZ87efEWwlf2G6DhcxWZFSZ9LSl iP9iePr7XlACsHihckm2JmwA9+vP4McPCw+sMYSGBboy8XwS21P9YGrm45deo7w1sUhF yzTUpRkCl4h0qqJ05wovTFkKV4inUMvA4r0e4p79zz4tq+N0+IX0entZXRuRgBoga/Q3 wHIvkj9LhBLHX5rjhc+QPfVo/cI8jL8sdXThy8SNuH6Hc2iHfEROSPnB0Ay9wiORXHs3 w/Xo0sZklvvtyts2y3j/1CxDEdQg0JkuM1qvIbAQat00Yq+r7wu+cwLNA222X5bh2WyL 7uAg== X-Gm-Message-State: ALQs6tCxgen1ziK68oiEoozc3Y+jpwq2PKzhfldvT/otLGaAKc9RgZZ2 oWHh8b8W9HwEYeXaskARYBU= 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 Cc: Dmitry Osipenko , linux-tegra@vger.kernel.org, dri-devel@lists.freedesktop.org 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> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org 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; }