From nobody Thu Apr 2 22:59:59 2026 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 E6048C6FA82 for ; Tue, 20 Sep 2022 08:15:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231355AbiITIPN (ORCPT ); Tue, 20 Sep 2022 04:15:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231478AbiITINv (ORCPT ); Tue, 20 Sep 2022 04:13:51 -0400 Received: from mail.kapsi.fi (mail.kapsi.fi [IPv6:2001:67c:1be8::25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 57D59647CC; Tue, 20 Sep 2022 01:12:42 -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:References:In-Reply-To: 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:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=6o06f6lKEImR2OALb/GgSAF0FPbhPTKph1QDZj138Gs=; b=ftDwNfB2q4NJ+7n0ZvUqXGHn+w HySKdIyIn0E+/osPctH6itZ6O7pOrSxLQ73pcvTx95PvcOo3V36iTExyiShTq1PGKRxCUfG0gTIPF Jj/F2F7yotDGWSggfVWKTn4ODkjBm9HQ0SttYbdtARpkujig3wzoe6gpLfcgb2y2meOiLvFiSg63B KGDsF0plKTSwnu9nCeTFXwra09zbumEFZuKS6eVEDBDyG1un7jCYryYgK/ZXM91SjowZB0qgJi9El ZRBItc4PJ4hD84J66L3loVTuQ0aDe+G21HdpL/kIVHOaaDWGnZzvAya19S7b27TOq7sVXyrIp/Wtu AwVgpkXw==; 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.94.2) (envelope-from ) id 1oaYMp-0017q3-Vc; Tue, 20 Sep 2022 11:12:32 +0300 From: Mikko Perttunen To: Thierry Reding , David Airlie , Daniel Vetter , Rob Herring , Krzysztof Kozlowski , Jonathan Hunter Cc: Mikko Perttunen , Ashish Mhetre , Sameer Pujar , dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 8/8] drm/tegra: Add Tegra234 support to NVDEC driver Date: Tue, 20 Sep 2022 11:12:03 +0300 Message-Id: <20220920081203.3237744-9-cyndis@kapsi.fi> X-Mailer: git-send-email 2.37.0 In-Reply-To: <20220920081203.3237744-1-cyndis@kapsi.fi> References: <20220920081203.3237744-1-cyndis@kapsi.fi> 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 Add support for the Tegra234 version of NVDEC to the NVDEC driver. This version sports a RISC-V controller and requires a few additional clocks. After firmware has been loaded, the behavior is, however, backwards compatible. Signed-off-by: Mikko Perttunen --- drivers/gpu/drm/tegra/drm.c | 1 + drivers/gpu/drm/tegra/nvdec.c | 140 ++++++++++++++++++++++++++++++---- 2 files changed, 126 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 6748ec1e0005..a014f11e9edb 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1382,6 +1382,7 @@ static const struct of_device_id host1x_drm_subdevs[]= =3D { { .compatible =3D "nvidia,tegra194-vic", }, { .compatible =3D "nvidia,tegra194-nvdec", }, { .compatible =3D "nvidia,tegra234-vic", }, + { .compatible =3D "nvidia,tegra234-nvdec", }, { /* sentinel */ } }; =20 diff --git a/drivers/gpu/drm/tegra/nvdec.c b/drivers/gpu/drm/tegra/nvdec.c index 05af4d107421..10fd21517281 100644 --- a/drivers/gpu/drm/tegra/nvdec.c +++ b/drivers/gpu/drm/tegra/nvdec.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -16,18 +17,21 @@ #include #include =20 -#include +#include =20 #include "drm.h" #include "falcon.h" +#include "riscv.h" #include "vic.h" =20 +#define NVDEC_FALCON_DEBUGINFO 0x1094 #define NVDEC_TFBIF_TRANSCFG 0x2c44 =20 struct nvdec_config { const char *firmware; unsigned int version; bool supports_sid; + bool has_riscv; bool has_extra_clocks; }; =20 @@ -40,9 +44,14 @@ struct nvdec { struct device *dev; struct clk_bulk_data clks[3]; unsigned int num_clks; + struct reset_control *reset; =20 /* Platform configuration */ const struct nvdec_config *config; + + /* RISC-V specific data */ + struct tegra_drm_riscv riscv; + phys_addr_t carveout_base; }; =20 static inline struct nvdec *to_nvdec(struct tegra_drm_client *client) @@ -56,7 +65,7 @@ static inline void nvdec_writel(struct nvdec *nvdec, u32 = value, writel(value, nvdec->regs + offset); } =20 -static int nvdec_boot(struct nvdec *nvdec) +static int nvdec_boot_falcon(struct nvdec *nvdec) { #ifdef CONFIG_IOMMU_API struct iommu_fwspec *spec =3D dev_iommu_fwspec_get(nvdec->dev); @@ -92,6 +101,64 @@ static int nvdec_boot(struct nvdec *nvdec) return 0; } =20 +static int nvdec_wait_debuginfo(struct nvdec *nvdec, const char *phase) +{ + int err; + u32 val; + + err =3D readl_poll_timeout(nvdec->regs + NVDEC_FALCON_DEBUGINFO, val, val= =3D=3D 0x0, 10, 100000); + if (err) { + dev_err(nvdec->dev, "failed to boot %s, debuginfo=3D0x%x\n", phase, val); + return err; + } + + return 0; +} + +static int nvdec_boot_riscv(struct nvdec *nvdec) +{ + int err; + + err =3D reset_control_acquire(nvdec->reset); + if (err) + return err; + + nvdec_writel(nvdec, 0xabcd1234, NVDEC_FALCON_DEBUGINFO); + + err =3D tegra_drm_riscv_boot_bootrom(&nvdec->riscv, nvdec->carveout_base,= 1, + &nvdec->riscv.bl_desc); + if (err) { + dev_err(nvdec->dev, "failed to execute bootloader\n"); + goto release_reset; + } + + err =3D nvdec_wait_debuginfo(nvdec, "bootloader"); + if (err) + goto release_reset; + + err =3D reset_control_reset(nvdec->reset); + if (err) + goto release_reset; + + nvdec_writel(nvdec, 0xabcd1234, NVDEC_FALCON_DEBUGINFO); + + err =3D tegra_drm_riscv_boot_bootrom(&nvdec->riscv, nvdec->carveout_base,= 1, + &nvdec->riscv.os_desc); + if (err) { + dev_err(nvdec->dev, "failed to execute firmware\n"); + goto release_reset; + } + + err =3D nvdec_wait_debuginfo(nvdec, "firmware"); + if (err) + goto release_reset; + +release_reset: + reset_control_release(nvdec->reset); + + return err; +} + static int nvdec_init(struct host1x_client *client) { struct tegra_drm_client *drm =3D host1x_to_drm_client(client); @@ -191,7 +258,7 @@ static const struct host1x_client_ops nvdec_client_ops = =3D { .exit =3D nvdec_exit, }; =20 -static int nvdec_load_firmware(struct nvdec *nvdec) +static int nvdec_load_falcon_firmware(struct nvdec *nvdec) { struct host1x_client *client =3D &nvdec->client.base; struct tegra_drm *tegra =3D nvdec->client.drm; @@ -254,7 +321,6 @@ static int nvdec_load_firmware(struct nvdec *nvdec) return err; } =20 - static __maybe_unused int nvdec_runtime_resume(struct device *dev) { struct nvdec *nvdec =3D dev_get_drvdata(dev); @@ -266,13 +332,19 @@ static __maybe_unused int nvdec_runtime_resume(struct= device *dev) =20 usleep_range(10, 20); =20 - err =3D nvdec_load_firmware(nvdec); - if (err < 0) - goto disable; + if (nvdec->config->has_riscv) { + err =3D nvdec_boot_riscv(nvdec); + if (err < 0) + goto disable; + } else { + err =3D nvdec_load_falcon_firmware(nvdec); + if (err < 0) + goto disable; =20 - err =3D nvdec_boot(nvdec); - if (err < 0) - goto disable; + err =3D nvdec_boot_falcon(nvdec); + if (err < 0) + goto disable; + } =20 return 0; =20 @@ -348,10 +420,18 @@ static const struct nvdec_config nvdec_t194_config = =3D { .supports_sid =3D true, }; =20 +static const struct nvdec_config nvdec_t234_config =3D { + .version =3D 0x23, + .supports_sid =3D true, + .has_riscv =3D true, + .has_extra_clocks =3D true, +}; + static const struct of_device_id tegra_nvdec_of_match[] =3D { { .compatible =3D "nvidia,tegra210-nvdec", .data =3D &nvdec_t210_config }, { .compatible =3D "nvidia,tegra186-nvdec", .data =3D &nvdec_t186_config }, { .compatible =3D "nvidia,tegra194-nvdec", .data =3D &nvdec_t194_config }, + { .compatible =3D "nvidia,tegra234-nvdec", .data =3D &nvdec_t234_config }, { }, }; MODULE_DEVICE_TABLE(of, tegra_nvdec_of_match); @@ -410,12 +490,42 @@ static int nvdec_probe(struct platform_device *pdev) if (err < 0) host_class =3D HOST1X_CLASS_NVDEC; =20 - nvdec->falcon.dev =3D dev; - nvdec->falcon.regs =3D nvdec->regs; + if (nvdec->config->has_riscv) { + struct tegra_mc *mc; =20 - err =3D falcon_init(&nvdec->falcon); - if (err < 0) - return err; + mc =3D devm_tegra_memory_controller_get(dev); + if (IS_ERR(mc)) { + dev_err_probe(dev, PTR_ERR(mc), + "failed to get memory controller handle\n"); + return PTR_ERR(mc); + } + + err =3D tegra_mc_get_carveout_info(mc, 1, &nvdec->carveout_base, NULL); + if (err) { + dev_err(dev, "failed to get carveout info: %d\n", err); + return err; + } + + nvdec->reset =3D devm_reset_control_get_exclusive_released(dev, "nvdec"); + if (IS_ERR(nvdec->reset)) { + dev_err_probe(dev, PTR_ERR(nvdec->reset), "failed to get reset\n"); + return PTR_ERR(nvdec->reset); + } + + nvdec->riscv.dev =3D dev; + nvdec->riscv.regs =3D nvdec->regs; + + err =3D tegra_drm_riscv_read_descriptors(&nvdec->riscv); + if (err < 0) + return err; + } else { + nvdec->falcon.dev =3D dev; + nvdec->falcon.regs =3D nvdec->regs; + + err =3D falcon_init(&nvdec->falcon); + if (err < 0) + return err; + } =20 platform_set_drvdata(pdev, nvdec); =20 --=20 2.37.0