From nobody Fri Dec 19 12:32:39 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CCE1CA0FE6 for ; Fri, 1 Sep 2023 11:40:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245549AbjIALkY (ORCPT ); Fri, 1 Sep 2023 07:40:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53252 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229818AbjIALkW (ORCPT ); Fri, 1 Sep 2023 07:40:22 -0400 Received: from mail.kapsi.fi (mail.kapsi.fi [IPv6:2001:67c:1be8::25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1435291; Fri, 1 Sep 2023 04:40:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:Message-ID:Date:Subject: Cc:To:From:Sender:Reply-To:Content-Type:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Vaae9RzNE3FL4Gsrihk4ZQIvVZZIGT955vGaddnPSVA=; b=aW+Ice2MA86ZS0kuuTzrVkYBNc EnEJswecLYgVUZ5K4+uqyyG8l3WahofIUPi2pTBMMdxRtFDK9p6HjfjVAMWtGiughQSkJzl6lDbm6 sRt9SJVjQI5dA0WCV/IpmehfFl1IMKidYdfvlDtGn3SK9u8M66x7rB0fXTG3KTttU+qWwfCQ2v4v8 nezWr4+lI0/9IWSxsXkI8axKJzM17RJnloZHufvWYTJt9CbtRZKZOBuDMvl70om147QP5XvQhKt21 q/Oq02b9SSxL+dqiRFDNYfhalphJSj9tIfo3JnYqGqm5xToV1DiubnUzl/k1oSJVuJP5ylHeuopIY vAOLN/Zg==; Received: from 91-158-25-70.elisa-laajakaista.fi ([91.158.25.70] helo=toshino.localdomain) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1qc2Va-008s8J-0M; Fri, 01 Sep 2023 14:40:14 +0300 From: Mikko Perttunen To: Thierry Reding Cc: Mikko Perttunen , dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] gpu: host1x: Syncpoint interrupt sharding Date: Fri, 1 Sep 2023 14:40:07 +0300 Message-ID: <20230901114008.672433-1-cyndis@kapsi.fi> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 91.158.25.70 X-SA-Exim-Mail-From: cyndis@kapsi.fi X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Mikko Perttunen Support sharded syncpoint interrupts on Tegra234+. This feature allows specifying one of eight interrupt lines for each syncpoint to lower processing latency of syncpoint threshold interrupts. Signed-off-by: Mikko Perttunen --- drivers/gpu/host1x/dev.c | 28 +++++++++++++++++--- drivers/gpu/host1x/dev.h | 3 ++- drivers/gpu/host1x/hw/intr_hw.c | 46 ++++++++++++++++++++++++--------- 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 7c6699aed7d2..b22821c81394 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -488,7 +488,7 @@ static int host1x_get_resets(struct host1x *host) static int host1x_probe(struct platform_device *pdev) { struct host1x *host; - int err; + int err, i; =20 host =3D devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); if (!host) @@ -516,9 +516,29 @@ static int host1x_probe(struct platform_device *pdev) return PTR_ERR(host->regs); } =20 - host->syncpt_irq =3D platform_get_irq(pdev, 0); - if (host->syncpt_irq < 0) - return host->syncpt_irq; + for (i =3D 0; i < ARRAY_SIZE(host->syncpt_irqs); i++) { + char irq_name[] =3D "syncptX"; + sprintf(irq_name, "syncpt%d", i); + + err =3D platform_get_irq_byname_optional(pdev, irq_name); + if (err =3D=3D -ENXIO) + break; + if (err < 0) + return err; + + host->syncpt_irqs[i] =3D err; + } + + host->num_syncpt_irqs =3D i; + + /* Device tree without irq names */ + if (i =3D=3D 0) { + host->syncpt_irqs[0] =3D platform_get_irq(pdev, 0); + if (host->syncpt_irqs[0] < 0) + return host->syncpt_irqs[0]; + + host->num_syncpt_irqs =3D 1; + } =20 mutex_init(&host->devices_lock); INIT_LIST_HEAD(&host->devices); diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h index 75de50fe03d0..c8e302de7625 100644 --- a/drivers/gpu/host1x/dev.h +++ b/drivers/gpu/host1x/dev.h @@ -124,7 +124,8 @@ struct host1x { void __iomem *regs; void __iomem *hv_regs; /* hypervisor region */ void __iomem *common_regs; - int syncpt_irq; + int syncpt_irqs[8]; + int num_syncpt_irqs; struct host1x_syncpt *syncpt; struct host1x_syncpt_base *bases; struct device *dev; diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_h= w.c index b915ef7d0348..9880e0c47235 100644 --- a/drivers/gpu/host1x/hw/intr_hw.c +++ b/drivers/gpu/host1x/hw/intr_hw.c @@ -13,13 +13,20 @@ #include "../intr.h" #include "../dev.h" =20 +struct host1x_intr_irq_data { + struct host1x *host; + u32 offset; +}; + static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id) { - struct host1x *host =3D dev_id; + struct host1x_intr_irq_data *irq_data =3D dev_id; + struct host1x *host =3D irq_data->host; unsigned long reg; unsigned int i, id; =20 - for (i =3D 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) { + for (i =3D irq_data->offset; i < DIV_ROUND_UP(host->info->nb_pts, 32); + i +=3D host->num_syncpt_irqs) { reg =3D host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i)); =20 @@ -67,26 +74,41 @@ static void intr_hw_init(struct host1x *host, u32 cpm) =20 /* * Program threshold interrupt destination among 8 lines per VM, - * per syncpoint. For now, just direct all to the first interrupt - * line. + * per syncpoint. For each group of 32 syncpoints (corresponding to one + * interrupt status register), direct to one interrupt line, going + * around in a round robin fashion. */ - for (id =3D 0; id < host->info->nb_pts; id++) - host1x_sync_writel(host, 0, HOST1X_SYNC_SYNCPT_INTR_DEST(id)); + for (id =3D 0; id < host->info->nb_pts; id++) { + u32 reg_offset =3D id / 32; + u32 irq_index =3D reg_offset % host->num_syncpt_irqs; + + host1x_sync_writel(host, irq_index, HOST1X_SYNC_SYNCPT_INTR_DEST(id)); + } #endif } =20 static int host1x_intr_init_host_sync(struct host1x *host, u32 cpm) { - int err; + int err, i; + struct host1x_intr_irq_data *irq_data; + + irq_data =3D devm_kcalloc(host->dev, host->num_syncpt_irqs, sizeof(irq_da= ta[0]), GFP_KERNEL); + if (!irq_data) + return -ENOMEM; =20 host1x_hw_intr_disable_all_syncpt_intrs(host); =20 - err =3D devm_request_irq(host->dev, host->syncpt_irq, - syncpt_thresh_isr, IRQF_SHARED, - "host1x_syncpt", host); - if (err < 0) - return err; + for (i =3D 0; i < host->num_syncpt_irqs; i++) { + irq_data[i].host =3D host; + irq_data[i].offset =3D i; + + err =3D devm_request_irq(host->dev, host->syncpt_irqs[i], + syncpt_thresh_isr, IRQF_SHARED, + "host1x_syncpt", &irq_data[i]); + if (err < 0) + return err; + } =20 intr_hw_init(host, cpm); =20 --=20 2.41.0