Devicetree
 help / color / mirror / Atom feed
* [PATCH 0/7] Host1x/VIC support on Tegra264
@ 2026-06-12  6:32 Mikko Perttunen
  2026-06-12  6:32 ` [PATCH 1/7] dt-bindings: display: tegra: Changes to support Tegra264 Mikko Perttunen
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Mikko Perttunen @ 2026-06-12  6:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen,
	Santosh BS

Hello everyone,

this series adds support for Host1x and VIC on Tegra264 SoCs.
The Host1x side is not very interesting, just adding the usual register
definitions and other information. One thing of note is that multimedia
engines apart from VIC have moved away from Host1x on this generation.

On the VIC side, there is a bit more of a change, as the VIC Falcon is
now RISC-V based. Unlike NVDEC, VIC is still "externally booted", so
the boot sequence is very similar to before.

host1x uapi-test[1] has been updated for Tegra264. Necessary headers for 
constructing VIC jobs have been added to open-gpu-doc[2].

Patches 1 and 2 add new compatible strings to Host1x and VIC device tree
bindings.

Patch 3 fixes the context device device tree parsing code to handle
iommu-map entries with length more than 1.

Patch 4 adds Tegra264 support to the Host1x driver.

Patches 5 and 6 add Tegra264 support to the VIC driver.

Patch 7 adds Host1x and VIC nodes to the Tegra264 device tree.

Thank you,
Mikko

[1] https://github.com/cyndis/uapi-test
[2] https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/video/clceb6.h
    https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/video/vic_ceb6_types.h

---
Mikko Perttunen (6):
      dt-bindings: display: tegra: Changes to support Tegra264
      dt-bindings: display: tegra: Add Tegra264 compatible for VIC
      gpu: host1x: Correctly parse linear ranges of context devices
      drm/tegra: falcon: Add support for RISC-V external boot
      drm/tegra: vic: Add Tegra264 support
      arm64: tegra: Add Host1x and VIC on Tegra264

Santosh BS (1):
      gpu: host1x: Add Tegra264 support

 .../display/tegra/nvidia,tegra124-vic.yaml         |   1 +
 .../display/tegra/nvidia,tegra20-host1x.yaml       |   5 +-
 arch/arm64/boot/dts/nvidia/tegra264.dtsi           |  63 +++++++
 drivers/gpu/drm/tegra/drm.c                        |   1 +
 drivers/gpu/drm/tegra/falcon.c                     |  66 ++++++--
 drivers/gpu/drm/tegra/falcon.h                     |  23 +++
 drivers/gpu/drm/tegra/vic.c                        |  95 ++++++++---
 drivers/gpu/drm/tegra/vic.h                        |   9 +-
 drivers/gpu/host1x/Makefile                        |   3 +-
 drivers/gpu/host1x/context.c                       |  13 +-
 drivers/gpu/host1x/dev.c                           |  41 +++++
 drivers/gpu/host1x/hw/cdma_hw.c                    |  12 +-
 drivers/gpu/host1x/hw/host1x10.c                   |  33 ++++
 drivers/gpu/host1x/hw/host1x10.h                   |  15 ++
 drivers/gpu/host1x/hw/host1x10_hardware.h          |  21 +++
 drivers/gpu/host1x/hw/hw_host1x10_common.h         |   6 +
 drivers/gpu/host1x/hw/hw_host1x10_hypervisor.h     |  10 ++
 drivers/gpu/host1x/hw/hw_host1x10_uclass.h         | 181 +++++++++++++++++++++
 drivers/gpu/host1x/hw/hw_host1x10_vm.h             |  36 ++++
 19 files changed, 586 insertions(+), 48 deletions(-)
---
base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
change-id: 20260313-t264-host1x-c97171fdde77


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/7] dt-bindings: display: tegra: Changes to support Tegra264
  2026-06-12  6:32 [PATCH 0/7] Host1x/VIC support on Tegra264 Mikko Perttunen
@ 2026-06-12  6:32 ` Mikko Perttunen
  2026-06-12  6:40   ` sashiko-bot
  2026-06-12  6:32 ` [PATCH 2/7] dt-bindings: display: tegra: Add Tegra264 compatible for VIC Mikko Perttunen
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Mikko Perttunen @ 2026-06-12  6:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

Add nvidia,tegra264-host1x compatible string. The Tegra264 host1x is
similar to Tegra234, but with a different set of engines and layout.

The engine register range is no longer continuous, so two range entries
are also needed.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 .../devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml     | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
index 3563378a01af..5b0e3158aa5b 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
@@ -25,6 +25,7 @@ properties:
           - nvidia,tegra186-host1x
           - nvidia,tegra194-host1x
           - nvidia,tegra234-host1x
+          - nvidia,tegra264-host1x
 
       - items:
           - const: nvidia,tegra132-host1x
@@ -57,7 +58,8 @@ properties:
     enum: [1, 2]
 
   ranges:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   clocks:
     description: Must contain one entry, for the module clock. See
@@ -192,6 +194,7 @@ allOf:
           contains:
             enum:
               - nvidia,tegra234-host1x
+              - nvidia,tegra264-host1x
     then:
       properties:
         reg-names:

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/7] dt-bindings: display: tegra: Add Tegra264 compatible for VIC
  2026-06-12  6:32 [PATCH 0/7] Host1x/VIC support on Tegra264 Mikko Perttunen
  2026-06-12  6:32 ` [PATCH 1/7] dt-bindings: display: tegra: Changes to support Tegra264 Mikko Perttunen
@ 2026-06-12  6:32 ` Mikko Perttunen
  2026-06-12  6:32 ` [PATCH 3/7] gpu: host1x: Correctly parse linear ranges of context devices Mikko Perttunen
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Mikko Perttunen @ 2026-06-12  6:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

Add nvidia,tegra264-vic compatible string for the VIC on Tegra264. VIC
on Tegra264 has a new RISC-V based microcontroller and improved image
processing capabilities.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml
index 7200095ef19e..bdf981781bd5 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml
@@ -22,6 +22,7 @@ properties:
           - nvidia,tegra186-vic
           - nvidia,tegra194-vic
           - nvidia,tegra234-vic
+          - nvidia,tegra264-vic
 
       - items:
           - const: nvidia,tegra132-vic

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/7] gpu: host1x: Correctly parse linear ranges of context devices
  2026-06-12  6:32 [PATCH 0/7] Host1x/VIC support on Tegra264 Mikko Perttunen
  2026-06-12  6:32 ` [PATCH 1/7] dt-bindings: display: tegra: Changes to support Tegra264 Mikko Perttunen
  2026-06-12  6:32 ` [PATCH 2/7] dt-bindings: display: tegra: Add Tegra264 compatible for VIC Mikko Perttunen
@ 2026-06-12  6:32 ` Mikko Perttunen
  2026-06-12  6:45   ` sashiko-bot
  2026-06-12  6:32 ` [PATCH 4/7] gpu: host1x: Add Tegra264 support Mikko Perttunen
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Mikko Perttunen @ 2026-06-12  6:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

The previous parsing of the iommu-map property assumed each context
device has its own one-length entry in the device tree. This has worked
fine so far, but on Tegra264 larger numbers of context devices are
usable, so it's better to support linear ranges as well.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 drivers/gpu/host1x/context.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c
index d50d41c20561..52ca663902ad 100644
--- a/drivers/gpu/host1x/context.c
+++ b/drivers/gpu/host1x/context.c
@@ -23,7 +23,7 @@ int host1x_memory_context_list_init(struct host1x *host1x)
 	struct host1x_memory_context_list *cdl = &host1x->context_list;
 	struct device_node *node = host1x->dev->of_node;
 	struct host1x_memory_context *ctx;
-	unsigned int i;
+	unsigned int devs, i;
 	int err;
 
 	cdl->devs = NULL;
@@ -34,7 +34,16 @@ int host1x_memory_context_list_init(struct host1x *host1x)
 	if (err < 0)
 		return 0;
 
-	cdl->len = err / 4;
+	devs = 0;
+
+	for (i = 0; i < err / 4; i++) {
+		u32 length;
+
+		of_property_read_u32_index(node, "iommu-map", i * 4 + 3, &length);
+		devs += length;
+	}
+
+	cdl->len = devs;
 	cdl->devs = kzalloc_objs(*cdl->devs, cdl->len);
 	if (!cdl->devs)
 		return -ENOMEM;

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/7] gpu: host1x: Add Tegra264 support
  2026-06-12  6:32 [PATCH 0/7] Host1x/VIC support on Tegra264 Mikko Perttunen
                   ` (2 preceding siblings ...)
  2026-06-12  6:32 ` [PATCH 3/7] gpu: host1x: Correctly parse linear ranges of context devices Mikko Perttunen
@ 2026-06-12  6:32 ` Mikko Perttunen
  2026-06-12  6:43   ` sashiko-bot
  2026-06-12  6:32 ` [PATCH 5/7] drm/tegra: falcon: Add support for RISC-V external boot Mikko Perttunen
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Mikko Perttunen @ 2026-06-12  6:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Santosh BS,
	Mikko Perttunen

From: Santosh BS <santoshb@nvidia.com>

Add device data and chip headers for Tegra264.

Signed-off-by: Santosh BS <santoshb@nvidia.com>
Co-developed-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 drivers/gpu/host1x/Makefile                    |   3 +-
 drivers/gpu/host1x/dev.c                       |  41 ++++++
 drivers/gpu/host1x/hw/cdma_hw.c                |  12 +-
 drivers/gpu/host1x/hw/host1x10.c               |  33 +++++
 drivers/gpu/host1x/hw/host1x10.h               |  15 ++
 drivers/gpu/host1x/hw/host1x10_hardware.h      |  21 +++
 drivers/gpu/host1x/hw/hw_host1x10_common.h     |   6 +
 drivers/gpu/host1x/hw/hw_host1x10_hypervisor.h |  10 ++
 drivers/gpu/host1x/hw/hw_host1x10_uclass.h     | 181 +++++++++++++++++++++++++
 drivers/gpu/host1x/hw/hw_host1x10_vm.h         |  36 +++++
 10 files changed, 352 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index fead483af0b4..b684fbf73841 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -17,7 +17,8 @@ host1x-y = \
 	hw/host1x05.o \
 	hw/host1x06.o \
 	hw/host1x07.o \
-	hw/host1x08.o
+	hw/host1x08.o \
+	hw/host1x10.o
 
 host1x-$(CONFIG_IOMMU_API) += \
 	context.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 3f475f0e6545..d2c64728f804 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -41,6 +41,7 @@
 #include "hw/host1x06.h"
 #include "hw/host1x07.h"
 #include "hw/host1x08.h"
+#include "hw/host1x10.h"
 
 void host1x_common_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -287,7 +288,47 @@ static const struct host1x_info host1x08_info = {
 	.reserve_vblank_syncpts = false,
 };
 
+static const struct host1x_sid_entry tegra264_sid_table[] = {
+	{ /* SE1 MMIO     */  .base = 0x1650, .offset = 0x90,  .limit = 0x90  },
+	{ /* SE2 MMIO     */  .base = 0x1658, .offset = 0x90,  .limit = 0x90  },
+	{ /* SE4 MMIO     */  .base = 0x1660, .offset = 0x90,  .limit = 0x90  },
+	{ /* SE1 ch       */  .base = 0x1738, .offset = 0x90,  .limit = 0x90  },
+	{ /* SE2 ch       */  .base = 0x1740, .offset = 0x90,  .limit = 0x90  },
+	{ /* SE4 ch       */  .base = 0x1748, .offset = 0x90,  .limit = 0x90  },
+	{ /* VIC ch       */  .base = 0x1790, .offset = 0x30,  .limit = 0x30  },
+	{ /* VIC MMIO     */  .base = 0x1688, .offset = 0x34,  .limit = 0x34  },
+	{ /* TSEC MMIO    */  .base = 0x1690, .offset = 0x30,  .limit = 0x34  },
+	{ /* VI MMIO      */  .base = 0x1698, .offset = 0x800, .limit = 0x800 },
+	{ /* VI_THI MMIO  */  .base = 0x16a0, .offset = 0x30,  .limit = 0x34  },
+	{ /* ISP MMIO     */  .base = 0x1680, .offset = 0x800, .limit = 0x800 },
+	{ /* ISP_THI MMIO */  .base = 0x16a8, .offset = 0x30,  .limit = 0x34  },
+	{ /* VI2 MMIO     */  .base = 0x16b8, .offset = 0x800, .limit = 0x800 },
+	{ /* VI2_THI MMIO */  .base = 0x16c0, .offset = 0x30,  .limit = 0x34  },
+	{ /* ISP1 MMIO    */  .base = 0x16c8, .offset = 0x800, .limit = 0x800 },
+	{ /* ISP1_THI MMIO */ .base = 0x16d0, .offset = 0x30,  .limit = 0x34  },
+};
+
+static const struct host1x_info host1x10_info = {
+	.nb_channels = 63,
+	.nb_pts = 1024,
+	.nb_mlocks = 24,
+	.nb_bases = 0,
+	.init = host1x10_init,
+	.sync_offset = 0x0,
+	.dma_mask = DMA_BIT_MASK(40),
+	.has_wide_gather = true,
+	.has_hypervisor = true,
+	.has_common = true,
+	.num_sid_entries = ARRAY_SIZE(tegra264_sid_table),
+	.sid_table = tegra264_sid_table,
+	.streamid_vm_table = { 0x1004, 128 },
+	.classid_vm_table = { 0x1404, 25 },
+	.mmio_vm_table = { 0x1504, 25 },
+	.reserve_vblank_syncpts = false,
+};
+
 static const struct of_device_id host1x_of_match[] = {
+	{ .compatible = "nvidia,tegra264-host1x", .data = &host1x10_info, },
 	{ .compatible = "nvidia,tegra234-host1x", .data = &host1x08_info, },
 	{ .compatible = "nvidia,tegra194-host1x", .data = &host1x07_info, },
 	{ .compatible = "nvidia,tegra186-host1x", .data = &host1x06_info, },
diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c
index 3f3f0018eee0..e43a9cf20c27 100644
--- a/drivers/gpu/host1x/hw/cdma_hw.c
+++ b/drivers/gpu/host1x/hw/cdma_hw.c
@@ -246,23 +246,24 @@ static void timeout_release_mlock(struct host1x_cdma *cdma)
 	 * so it turns out that if we don't /actually/ need MLOCKs, we can just
 	 * ignore them.
 	 *
-	 * As such, for now just implement this on Tegra234 where things are
-	 * stricter but also easy to implement.
+	 * As such, for now just implement this on Tegra234 and above where things
+	 * are stricter but also easy to implement.
 	 */
 	struct host1x_channel *ch = cdma_to_channel(cdma);
 	struct host1x *host1x = cdma_to_host1x(cdma);
 	u32 offset;
 
 	switch (ch->client->class) {
+	case HOST1X_CLASS_VIC:
+		offset = HOST1X_COMMON_VIC_MLOCK;
+		break;
+#if HOST1X_HW == 8
 	case HOST1X_CLASS_NVJPG1:
 		offset = HOST1X_COMMON_NVJPG1_MLOCK;
 		break;
 	case HOST1X_CLASS_NVENC:
 		offset = HOST1X_COMMON_NVENC_MLOCK;
 		break;
-	case HOST1X_CLASS_VIC:
-		offset = HOST1X_COMMON_VIC_MLOCK;
-		break;
 	case HOST1X_CLASS_NVJPG:
 		offset = HOST1X_COMMON_NVJPG_MLOCK;
 		break;
@@ -272,6 +273,7 @@ static void timeout_release_mlock(struct host1x_cdma *cdma)
 	case HOST1X_CLASS_OFA:
 		offset = HOST1X_COMMON_OFA_MLOCK;
 		break;
+#endif
 	default:
 		WARN(1, "%s was not updated for class %u", __func__, ch->client->class);
 		return;
diff --git a/drivers/gpu/host1x/hw/host1x10.c b/drivers/gpu/host1x/hw/host1x10.c
new file mode 100644
index 000000000000..2800f309bf6f
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x10.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Host1x init for Tegra264 SoCs
+ *
+ * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ */
+
+/* include hw specification */
+#include "host1x10.h"
+#include "host1x10_hardware.h"
+
+/* include code */
+#define HOST1X_HW 10
+
+#include "cdma_hw.c"
+#include "channel_hw.c"
+#include "debug_hw.c"
+#include "intr_hw.c"
+#include "syncpt_hw.c"
+
+#include "../dev.h"
+
+int host1x10_init(struct host1x *host)
+{
+	host->channel_op = &host1x_channel_ops;
+	host->cdma_op = &host1x_cdma_ops;
+	host->cdma_pb_op = &host1x_pushbuffer_ops;
+	host->syncpt_op = &host1x_syncpt_ops;
+	host->intr_op = &host1x_intr_ops;
+	host->debug_op = &host1x_debug_ops;
+
+	return 0;
+}
diff --git a/drivers/gpu/host1x/hw/host1x10.h b/drivers/gpu/host1x/hw/host1x10.h
new file mode 100644
index 000000000000..577f6ff3dff5
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x10.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Host1x init for Tegra264 SoCs
+ *
+ * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ */
+
+#ifndef HOST1X_HOST1X10_H
+#define HOST1X_HOST1X10_H
+
+struct host1x;
+
+int host1x10_init(struct host1x *host);
+
+#endif
diff --git a/drivers/gpu/host1x/hw/host1x10_hardware.h b/drivers/gpu/host1x/hw/host1x10_hardware.h
new file mode 100644
index 000000000000..abbead8190b1
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x10_hardware.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Tegra host1x Register Offsets for Tegra264
+ *
+ * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ */
+
+#ifndef __HOST1X_HOST1X10_HARDWARE_H
+#define __HOST1X_HOST1X10_HARDWARE_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+#include "hw_host1x10_uclass.h"
+#include "hw_host1x10_vm.h"
+#include "hw_host1x10_hypervisor.h"
+#include "hw_host1x10_common.h"
+
+#include "opcodes.h"
+
+#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x10_common.h b/drivers/gpu/host1x/hw/hw_host1x10_common.h
new file mode 100644
index 000000000000..48a632672a47
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x10_common.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ */
+
+#define HOST1X_COMMON_VIC_MLOCK			0x4060
diff --git a/drivers/gpu/host1x/hw/hw_host1x10_hypervisor.h b/drivers/gpu/host1x/hw/hw_host1x10_hypervisor.h
new file mode 100644
index 000000000000..8c9069caffa8
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x10_hypervisor.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ */
+
+#define HOST1X_HV_SYNCPT_PROT_EN			0x172c
+#define HOST1X_HV_SYNCPT_PROT_EN_CH_EN			BIT(1)
+#define HOST1X_HV_CH_MLOCK_EN(x)			(0x1708 + (x * 4))
+#define HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(x)		(0x1718 + (x * 4))
+#define HOST1X_HV_SYNCPT_VM(x)				(0x0 + 4 * (x))
diff --git a/drivers/gpu/host1x/hw/hw_host1x10_uclass.h b/drivers/gpu/host1x/hw/hw_host1x10_uclass.h
new file mode 100644
index 000000000000..abe83e67fa83
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x10_uclass.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ */
+
+ /*
+  * Function naming determines intended use:
+  *
+  *     <x>_r(void) : Returns the offset for register <x>.
+  *
+  *     <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
+  *
+  *     <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
+  *
+  *     <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
+  *         and masked to place it at field <y> of register <x>.  This value
+  *         can be |'d with others to produce a full register value for
+  *         register <x>.
+  *
+  *     <x>_<y>_m(void) : Returns a mask for field <y> of register <x>.  This
+  *         value can be ~'d and then &'d to clear the value of field <y> for
+  *         register <x>.
+  *
+  *     <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
+  *         to place it at field <y> of register <x>.  This value can be |'d
+  *         with others to produce a full register value for <x>.
+  *
+  *     <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
+  *         <x> value 'r' after being shifted to place its LSB at bit 0.
+  *         This value is suitable for direct comparison with other unshifted
+  *         values appropriate for use in field <y> of register <x>.
+  *
+  *     <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
+  *         field <y> of register <x>.  This value is suitable for direct
+  *         comparison with unshifted values appropriate for use in field <y>
+  *         of register <x>.
+  */
+
+#ifndef HOST1X_HW_HOST1X10_UCLASS_H
+#define HOST1X_HW_HOST1X10_UCLASS_H
+
+static inline u32 host1x_uclass_incr_syncpt_r(void)
+{
+	return 0x0;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT \
+	host1x_uclass_incr_syncpt_r()
+static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
+{
+	return (v & 0xff) << 10;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT_COND_F(v) \
+	host1x_uclass_incr_syncpt_cond_f(v)
+static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
+{
+	return (v & 0x3ff) << 0;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT_INDX_F(v) \
+	host1x_uclass_incr_syncpt_indx_f(v)
+static inline u32 host1x_uclass_wait_syncpt_r(void)
+{
+	return 0x8;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT \
+	host1x_uclass_wait_syncpt_r()
+static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
+{
+	return (v & 0xff) << 24;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_INDX_F(v) \
+	host1x_uclass_wait_syncpt_indx_f(v)
+static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
+{
+	return (v & 0xffffff) << 0;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_THRESH_F(v) \
+	host1x_uclass_wait_syncpt_thresh_f(v)
+static inline u32 host1x_uclass_wait_syncpt_base_r(void)
+{
+	return 0x9;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_BASE \
+	host1x_uclass_wait_syncpt_base_r()
+static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
+{
+	return (v & 0xff) << 24;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_INDX_F(v) \
+	host1x_uclass_wait_syncpt_base_indx_f(v)
+static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
+{
+	return (v & 0xff) << 16;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_BASE_INDX_F(v) \
+	host1x_uclass_wait_syncpt_base_base_indx_f(v)
+static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
+{
+	return (v & 0xffff) << 0;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_OFFSET_F(v) \
+	host1x_uclass_wait_syncpt_base_offset_f(v)
+static inline u32 host1x_uclass_load_syncpt_base_r(void)
+{
+	return 0xb;
+}
+#define HOST1X_UCLASS_LOAD_SYNCPT_BASE \
+	host1x_uclass_load_syncpt_base_r()
+static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
+{
+	return (v & 0xff) << 24;
+}
+#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(v) \
+	host1x_uclass_load_syncpt_base_base_indx_f(v)
+static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
+{
+	return (v & 0xffffff) << 0;
+}
+#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(v) \
+	host1x_uclass_load_syncpt_base_value_f(v)
+static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
+{
+	return (v & 0xff) << 24;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT_BASE_BASE_INDX_F(v) \
+	host1x_uclass_incr_syncpt_base_base_indx_f(v)
+static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
+{
+	return (v & 0xffffff) << 0;
+}
+#define HOST1X_UCLASS_INCR_SYNCPT_BASE_OFFSET_F(v) \
+	host1x_uclass_incr_syncpt_base_offset_f(v)
+static inline u32 host1x_uclass_indoff_r(void)
+{
+	return 0x2d;
+}
+#define HOST1X_UCLASS_INDOFF \
+	host1x_uclass_indoff_r()
+static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
+{
+	return (v & 0xf) << 28;
+}
+#define HOST1X_UCLASS_INDOFF_INDBE_F(v) \
+	host1x_uclass_indoff_indbe_f(v)
+static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
+{
+	return (v & 0x1) << 27;
+}
+#define HOST1X_UCLASS_INDOFF_AUTOINC_F(v) \
+	host1x_uclass_indoff_autoinc_f(v)
+static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
+{
+	return (v & 0xff) << 18;
+}
+#define HOST1X_UCLASS_INDOFF_INDMODID_F(v) \
+	host1x_uclass_indoff_indmodid_f(v)
+static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
+{
+	return (v & 0xffff) << 2;
+}
+#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
+	host1x_uclass_indoff_indroffset_f(v)
+static inline u32 host1x_uclass_indoff_rwn_read_v(void)
+{
+	return 1;
+}
+#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
+	host1x_uclass_indoff_indroffset_f(v)
+static inline u32 host1x_uclass_load_syncpt_payload_32_r(void)
+{
+	return 0x4e;
+}
+#define HOST1X_UCLASS_LOAD_SYNCPT_PAYLOAD_32 \
+	host1x_uclass_load_syncpt_payload_32_r()
+static inline u32 host1x_uclass_wait_syncpt_32_r(void)
+{
+	return 0x50;
+}
+#define HOST1X_UCLASS_WAIT_SYNCPT_32 \
+	host1x_uclass_wait_syncpt_32_r()
+
+#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x10_vm.h b/drivers/gpu/host1x/hw/hw_host1x10_vm.h
new file mode 100644
index 000000000000..75f5b881c561
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x10_vm.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ */
+
+#define HOST1X_CHANNEL_DMASTART				0x0000
+#define HOST1X_CHANNEL_DMASTART_HI			0x0004
+#define HOST1X_CHANNEL_DMAPUT				0x0008
+#define HOST1X_CHANNEL_DMAPUT_HI			0x000c
+#define HOST1X_CHANNEL_DMAGET				0x0010
+#define HOST1X_CHANNEL_DMAGET_HI			0x0014
+#define HOST1X_CHANNEL_DMAEND				0x0018
+#define HOST1X_CHANNEL_DMAEND_HI			0x001c
+#define HOST1X_CHANNEL_DMACTRL				0x0020
+#define HOST1X_CHANNEL_DMACTRL_DMASTOP			BIT(0)
+#define HOST1X_CHANNEL_DMACTRL_DMAGETRST		BIT(1)
+#define HOST1X_CHANNEL_DMACTRL_DMAINITGET		BIT(2)
+#define HOST1X_CHANNEL_CMDFIFO_STAT			0x0024
+#define HOST1X_CHANNEL_CMDFIFO_STAT_EMPTY		BIT(13)
+#define HOST1X_CHANNEL_CMDFIFO_RDATA			0x0028
+#define HOST1X_CHANNEL_CMDP_OFFSET			0x0030
+#define HOST1X_CHANNEL_CMDP_CLASS			0x0034
+#define HOST1X_CHANNEL_CHANNELSTAT			0x0038
+#define HOST1X_CHANNEL_CMDPROC_STOP			0x0048
+#define HOST1X_CHANNEL_TEARDOWN				0x004c
+#define HOST1X_CHANNEL_SMMU_STREAMID			0x0084
+
+#define HOST1X_SYNC_SYNCPT_CPU_INCR(x)			(0x6400 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(x)	(0x6600 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_INTR_DEST(x)			(0x6684 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(x)	(0x770c + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(x)	(0x7790 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT(x)				(0x8080 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_INT_THRESH(x)		(0xa088 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_CH_APP(x)			(0xb090 + 4 * (x))
+#define HOST1X_SYNC_SYNCPT_CH_APP_CH(v)			(((v) & 0x3f) << 8)

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/7] drm/tegra: falcon: Add support for RISC-V external boot
  2026-06-12  6:32 [PATCH 0/7] Host1x/VIC support on Tegra264 Mikko Perttunen
                   ` (3 preceding siblings ...)
  2026-06-12  6:32 ` [PATCH 4/7] gpu: host1x: Add Tegra264 support Mikko Perttunen
@ 2026-06-12  6:32 ` Mikko Perttunen
  2026-06-12  6:44   ` sashiko-bot
  2026-06-12  6:32 ` [PATCH 6/7] drm/tegra: vic: Add Tegra264 support Mikko Perttunen
  2026-06-12  6:32 ` [PATCH 7/7] arm64: tegra: Add Host1x and VIC on Tegra264 Mikko Perttunen
  6 siblings, 1 reply; 13+ messages in thread
From: Mikko Perttunen @ 2026-06-12  6:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

Add support for loading and booting RISC-V firmwares on Falcons with
RISC-V hardware. The flow is mostly the same as for traditional
Falcons, with a few different registers and different firmware layout.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 drivers/gpu/drm/tegra/falcon.c | 66 +++++++++++++++++++++++++++++++++++-------
 drivers/gpu/drm/tegra/falcon.h | 23 +++++++++++++++
 2 files changed, 79 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/tegra/falcon.c b/drivers/gpu/drm/tegra/falcon.c
index 17f616bbcb45..1172356b6af3 100644
--- a/drivers/gpu/drm/tegra/falcon.c
+++ b/drivers/gpu/drm/tegra/falcon.c
@@ -26,8 +26,12 @@ int falcon_wait_idle(struct falcon *falcon)
 {
 	u32 value;
 
-	return readl_poll_timeout(falcon->regs + FALCON_IDLESTATE, value,
-				  (value == 0), 10, 100000);
+	if (falcon->riscv)
+		return readl_poll_timeout(falcon->regs + RISCV_CPUCTL, value,
+					  (value & RISCV_CPUCTL_ACTIVE_STAT_ACTIVE), 10, 100000);
+	else
+		return readl_poll_timeout(falcon->regs + FALCON_IDLESTATE, value,
+					  (value == 0), 10, 100000);
 }
 
 static int falcon_dma_wait_not_full(struct falcon *falcon)
@@ -122,6 +126,17 @@ static int falcon_parse_firmware_image(struct falcon *falcon)
 	return 0;
 }
 
+static void falcon_parse_firmware_desc(struct falcon *falcon)
+{
+	struct falcon_fw_riscv_desc *desc =
+		(struct falcon_fw_riscv_desc *)falcon->firmware.desc_firmware->data;
+
+	falcon->firmware.code.offset = desc->code_offset;
+	falcon->firmware.code.size = desc->code_size;
+	falcon->firmware.data.offset = desc->data_offset;
+	falcon->firmware.data.size = desc->data_size;
+}
+
 int falcon_read_firmware(struct falcon *falcon, const char *name)
 {
 	int err;
@@ -133,7 +148,23 @@ int falcon_read_firmware(struct falcon *falcon, const char *name)
 
 	falcon->firmware.size = falcon->firmware.firmware->size;
 
+	if (falcon->riscv) {
+		/* Load separate descriptor */
+		char desc_name[128];
+
+		scnprintf(desc_name, sizeof(desc_name), "%s.desc", name);
+		err = request_firmware(&falcon->firmware.desc_firmware, desc_name, falcon->dev);
+		if (err < 0)
+			goto release_firmware;
+	}
+
 	return 0;
+
+release_firmware:
+	release_firmware(falcon->firmware.firmware);
+	falcon->firmware.firmware = NULL;
+
+	return err;
 }
 
 int falcon_load_firmware(struct falcon *falcon)
@@ -144,16 +175,22 @@ int falcon_load_firmware(struct falcon *falcon)
 	/* copy firmware image into local area. this also ensures endianness */
 	falcon_copy_firmware_image(falcon, firmware);
 
-	/* parse the image data */
-	err = falcon_parse_firmware_image(falcon);
-	if (err < 0) {
-		dev_err(falcon->dev, "failed to parse firmware image\n");
-		return err;
+	if (falcon->riscv) {
+		falcon_parse_firmware_desc(falcon);
+	} else {
+		err = falcon_parse_firmware_image(falcon);
+		if (err < 0) {
+			dev_err(falcon->dev, "failed to parse firmware image\n");
+			return err;
+		}
 	}
 
 	release_firmware(firmware);
 	falcon->firmware.firmware = NULL;
 
+	release_firmware(falcon->firmware.desc_firmware);
+	falcon->firmware.desc_firmware = NULL;
+
 	return 0;
 }
 
@@ -168,6 +205,9 @@ void falcon_exit(struct falcon *falcon)
 {
 	if (falcon->firmware.firmware)
 		release_firmware(falcon->firmware.firmware);
+
+	if (falcon->firmware.desc_firmware)
+		release_firmware(falcon->firmware.desc_firmware);
 }
 
 int falcon_boot(struct falcon *falcon)
@@ -229,9 +269,15 @@ int falcon_boot(struct falcon *falcon)
 			      FALCON_ITFEN_CTXEN,
 		      FALCON_ITFEN);
 
-	/* boot falcon */
-	falcon_writel(falcon, 0x00000000, FALCON_BOOTVEC);
-	falcon_writel(falcon, FALCON_CPUCTL_STARTCPU, FALCON_CPUCTL);
+	if (falcon->riscv) {
+		falcon_writel(falcon, RISCV_BCR_CTRL_CORE_SELECT_RISCV, RISCV_BCR_CTRL);
+		falcon_writel(falcon, 0x0, RISCV_BOOT_VECTOR_HI);
+		falcon_writel(falcon, 0x100000, RISCV_BOOT_VECTOR_LO);
+		falcon_writel(falcon, RISCV_CPUCTL_STARTCPU, RISCV_CPUCTL);
+	} else {
+		falcon_writel(falcon, 0x00000000, FALCON_BOOTVEC);
+		falcon_writel(falcon, FALCON_CPUCTL_STARTCPU, FALCON_CPUCTL);
+	}
 
 	err = falcon_wait_idle(falcon);
 	if (err < 0) {
diff --git a/drivers/gpu/drm/tegra/falcon.h b/drivers/gpu/drm/tegra/falcon.h
index 902bb7e4fd0f..37a17c6136b3 100644
--- a/drivers/gpu/drm/tegra/falcon.h
+++ b/drivers/gpu/drm/tegra/falcon.h
@@ -55,6 +55,16 @@
 
 #define FALCON_DMATRFFBOFFS			0x0000111c
 
+#define RISCV_BOOT_VECTOR_LO			0x00001780
+#define RISCV_BOOT_VECTOR_HI			0x00001784
+
+#define RISCV_CPUCTL				0x00001788
+#define RISCV_CPUCTL_STARTCPU			(1 << 0)
+#define RISCV_CPUCTL_ACTIVE_STAT_ACTIVE		(1 << 7)
+
+#define RISCV_BCR_CTRL				0x00001a68
+#define RISCV_BCR_CTRL_CORE_SELECT_RISCV	(1 << 4)
+
 struct falcon_fw_bin_header_v1 {
 	u32 magic;		/* 0x10de */
 	u32 version;		/* version of bin format (1) */
@@ -76,6 +86,14 @@ struct falcon_fw_os_header_v1 {
 	u32 data_size;
 };
 
+struct falcon_fw_riscv_desc {
+	u32 reserved[74];
+	u32 data_offset;
+	u32 data_size;
+	u32 code_offset;
+	u32 code_size;
+};
+
 struct falcon_firmware_section {
 	unsigned long offset;
 	size_t size;
@@ -84,6 +102,8 @@ struct falcon_firmware_section {
 struct falcon_firmware {
 	/* Firmware after it is read but not loaded */
 	const struct firmware *firmware;
+	/* RISC-V firmware descriptor */
+	const struct firmware *desc_firmware;
 
 	/* Raw firmware data */
 	dma_addr_t iova;
@@ -102,6 +122,9 @@ struct falcon {
 	struct device *dev;
 	void __iomem *regs;
 
+	/* Peregrine falcon, external boot */
+	bool riscv;
+
 	struct falcon_firmware firmware;
 };
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/7] drm/tegra: vic: Add Tegra264 support
  2026-06-12  6:32 [PATCH 0/7] Host1x/VIC support on Tegra264 Mikko Perttunen
                   ` (4 preceding siblings ...)
  2026-06-12  6:32 ` [PATCH 5/7] drm/tegra: falcon: Add support for RISC-V external boot Mikko Perttunen
@ 2026-06-12  6:32 ` Mikko Perttunen
  2026-06-12  6:47   ` sashiko-bot
  2026-06-12  6:32 ` [PATCH 7/7] arm64: tegra: Add Host1x and VIC on Tegra264 Mikko Perttunen
  6 siblings, 1 reply; 13+ messages in thread
From: Mikko Perttunen @ 2026-06-12  6:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

Add support for VIC on Tegra264. The Tegra264 VIC uses a RISC-V based
Falcon microcontroller instead of the traditional Falcon previously,
and has the TRANSCFG register in a different place.

The .version field is set to 0x264 rather than 0x26 to allow
distinguishing between different VIC capabilities between minor version
variations of some chips.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 drivers/gpu/drm/tegra/drm.c |  1 +
 drivers/gpu/drm/tegra/vic.c | 95 +++++++++++++++++++++++++++++++++------------
 drivers/gpu/drm/tegra/vic.h |  9 ++---
 3 files changed, 76 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 1dcef4e7d104..28245bf5ba5f 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1396,6 +1396,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
 	{ .compatible = "nvidia,tegra194-nvdec", },
 	{ .compatible = "nvidia,tegra234-vic", },
 	{ .compatible = "nvidia,tegra234-nvdec", },
+	{ .compatible = "nvidia,tegra264-vic", },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index 332c9b563d3f..46c7e00de347 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -8,6 +8,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/host1x.h>
 #include <linux/iommu.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -20,10 +21,16 @@
 #include "falcon.h"
 #include "vic.h"
 
+#define VIC_FALCON_DEBUGINFO			0x1094
+#define VIC_DEBUGINFO_DUMMY			0xabcd1234
+#define VIC_DEBUGINFO_CLEAR			0x0
+
 struct vic_config {
 	const char *firmware;
 	unsigned int version;
 	bool supports_sid;
+	bool has_riscv;
+	unsigned int transcfg_offset;
 };
 
 struct vic {
@@ -54,8 +61,8 @@ static void vic_writel(struct vic *vic, u32 value, unsigned int offset)
 
 static int vic_boot(struct vic *vic)
 {
-	u32 fce_ucode_size, fce_bin_data_offset, stream_id;
-	void *hdr;
+	u32 stream_id;
+	u32 val;
 	int err = 0;
 
 	if (vic->config->supports_sid && tegra_dev_iommu_get_stream_id(vic->dev, &stream_id)) {
@@ -63,7 +70,7 @@ static int vic_boot(struct vic *vic)
 
 		value = TRANSCFG_ATT(1, TRANSCFG_SID_FALCON) |
 			TRANSCFG_ATT(0, TRANSCFG_SID_HW);
-		vic_writel(vic, value, VIC_TFBIF_TRANSCFG);
+		vic_writel(vic, value, vic->config->transcfg_offset);
 
 		/*
 		 * STREAMID0 is used for input/output buffers. Initialize it to SID_VIC in case
@@ -85,31 +92,50 @@ static int vic_boot(struct vic *vic)
 			CG_WAKEUP_DLY_CNT(4),
 		   NV_PVIC_MISC_PRI_VIC_CG);
 
+	if (vic->config->has_riscv) {
+		/* Write a known pattern into DEBUGINFO register */
+		vic_writel(vic, VIC_DEBUGINFO_DUMMY, VIC_FALCON_DEBUGINFO);
+	}
+
 	err = falcon_boot(&vic->falcon);
 	if (err < 0)
 		return err;
 
-	hdr = vic->falcon.firmware.virt;
-	fce_bin_data_offset = *(u32 *)(hdr + VIC_UCODE_FCE_DATA_OFFSET);
-
-	/* Old VIC firmware needs kernel help with setting up FCE microcode. */
-	if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) {
-		hdr = vic->falcon.firmware.virt +
-			*(u32 *)(hdr + VIC_UCODE_FCE_HEADER_OFFSET);
-		fce_ucode_size = *(u32 *)(hdr + FCE_UCODE_SIZE_OFFSET);
-
-		falcon_execute_method(&vic->falcon, VIC_SET_FCE_UCODE_SIZE,
-				      fce_ucode_size);
-		falcon_execute_method(
-			&vic->falcon, VIC_SET_FCE_UCODE_OFFSET,
-			(vic->falcon.firmware.iova + fce_bin_data_offset) >> 8);
-	}
+	if (vic->config->has_riscv) {
+		/* Check VIC has reached a proper initialized state */
+		err = readl_poll_timeout(vic->regs + VIC_FALCON_DEBUGINFO, val,
+					 val == VIC_DEBUGINFO_CLEAR,
+					 1000, 2000000);
+		if (err) {
+			dev_err(vic->dev, "VIC not initialized, timeout, val=0x%x\n", val);
+			return err;
+		}
+	} else {
+		u32 fce_ucode_size, fce_bin_data_offset;
+		void *hdr;
+
+		hdr = vic->falcon.firmware.virt;
+		fce_bin_data_offset = *(u32 *)(hdr + VIC_UCODE_FCE_DATA_OFFSET);
+
+		/* Old VIC firmware needs kernel help with setting up FCE microcode. */
+		if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) {
+			hdr = vic->falcon.firmware.virt +
+				*(u32 *)(hdr + VIC_UCODE_FCE_HEADER_OFFSET);
+			fce_ucode_size = *(u32 *)(hdr + FCE_UCODE_SIZE_OFFSET);
+
+			falcon_execute_method(&vic->falcon, VIC_SET_FCE_UCODE_SIZE,
+					      fce_ucode_size);
+			falcon_execute_method(
+				&vic->falcon, VIC_SET_FCE_UCODE_OFFSET,
+				(vic->falcon.firmware.iova + fce_bin_data_offset) >> 8);
+		}
 
-	err = falcon_wait_idle(&vic->falcon);
-	if (err < 0) {
-		dev_err(vic->dev,
-			"failed to set application ID and FCE base\n");
-		return err;
+		err = falcon_wait_idle(&vic->falcon);
+		if (err < 0) {
+			dev_err(vic->dev,
+				"failed to set application ID and FCE base\n");
+			return err;
+		}
 	}
 
 	return 0;
@@ -277,6 +303,8 @@ static int vic_load_firmware(struct vic *vic)
 
 	if (!vic->config->supports_sid) {
 		vic->can_use_context = false;
+	} else if (vic->config->has_riscv) {
+		vic->can_use_context = true;
 	} else if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) {
 		/*
 		 * Firmware will access FCE through STREAMID0, so context
@@ -302,7 +330,6 @@ static int vic_load_firmware(struct vic *vic)
 	return err;
 }
 
-
 static int __maybe_unused vic_runtime_resume(struct device *dev)
 {
 	struct vic *vic = dev_get_drvdata(dev);
@@ -417,6 +444,7 @@ static const struct vic_config vic_t186_config = {
 	.firmware = NVIDIA_TEGRA_186_VIC_FIRMWARE,
 	.version = 0x18,
 	.supports_sid = true,
+	.transcfg_offset = 0x2044,
 };
 
 #define NVIDIA_TEGRA_194_VIC_FIRMWARE "nvidia/tegra194/vic.bin"
@@ -425,6 +453,7 @@ static const struct vic_config vic_t194_config = {
 	.firmware = NVIDIA_TEGRA_194_VIC_FIRMWARE,
 	.version = 0x19,
 	.supports_sid = true,
+	.transcfg_offset = 0x2044,
 };
 
 #define NVIDIA_TEGRA_234_VIC_FIRMWARE "nvidia/tegra234/vic.bin"
@@ -433,6 +462,18 @@ static const struct vic_config vic_t234_config = {
 	.firmware = NVIDIA_TEGRA_234_VIC_FIRMWARE,
 	.version = 0x23,
 	.supports_sid = true,
+	.transcfg_offset = 0x2044,
+};
+
+#define NVIDIA_TEGRA_264_VIC_FIRMWARE "nvidia/tegra264/vic.bin"
+#define NVIDIA_TEGRA_264_VIC_DESC "nvidia/tegra264/vic.bin.desc"
+
+static const struct vic_config vic_t264_config = {
+	.firmware = NVIDIA_TEGRA_264_VIC_FIRMWARE,
+	.version = 0x264,
+	.supports_sid = true,
+	.has_riscv = true,
+	.transcfg_offset = 0x2244,
 };
 
 static const struct of_device_id tegra_vic_of_match[] = {
@@ -441,6 +482,7 @@ static const struct of_device_id tegra_vic_of_match[] = {
 	{ .compatible = "nvidia,tegra186-vic", .data = &vic_t186_config },
 	{ .compatible = "nvidia,tegra194-vic", .data = &vic_t194_config },
 	{ .compatible = "nvidia,tegra234-vic", .data = &vic_t234_config },
+	{ .compatible = "nvidia,tegra264-vic", .data = &vic_t264_config },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, tegra_vic_of_match);
@@ -495,6 +537,7 @@ static int vic_probe(struct platform_device *pdev)
 
 	vic->falcon.dev = dev;
 	vic->falcon.regs = vic->regs;
+	vic->falcon.riscv = vic->config->has_riscv;
 
 	err = falcon_init(&vic->falcon);
 	if (err < 0)
@@ -571,3 +614,7 @@ MODULE_FIRMWARE(NVIDIA_TEGRA_194_VIC_FIRMWARE);
 #if IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
 MODULE_FIRMWARE(NVIDIA_TEGRA_234_VIC_FIRMWARE);
 #endif
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_264_SOC)
+MODULE_FIRMWARE(NVIDIA_TEGRA_264_VIC_FIRMWARE);
+MODULE_FIRMWARE(NVIDIA_TEGRA_264_VIC_DESC);
+#endif
diff --git a/drivers/gpu/drm/tegra/vic.h b/drivers/gpu/drm/tegra/vic.h
index acf35aac948b..e525a06daaba 100644
--- a/drivers/gpu/drm/tegra/vic.h
+++ b/drivers/gpu/drm/tegra/vic.h
@@ -21,11 +21,10 @@
 #define CG_IDLE_CG_EN				(1 << 6)
 #define CG_WAKEUP_DLY_CNT(val)			((val & 0xf) << 16)
 
-#define VIC_TFBIF_TRANSCFG	0x00002044
-#define  TRANSCFG_ATT(i, v)	(((v) & 0x3) << (i * 4))
-#define  TRANSCFG_SID_HW	0
-#define  TRANSCFG_SID_PHY	1
-#define  TRANSCFG_SID_FALCON	2
+#define TRANSCFG_ATT(i, v)	(((v) & 0x3) << (i * 4))
+#define TRANSCFG_SID_HW		0
+#define TRANSCFG_SID_PHY	1
+#define TRANSCFG_SID_FALCON	2
 
 /* Firmware offsets */
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/7] arm64: tegra: Add Host1x and VIC on Tegra264
  2026-06-12  6:32 [PATCH 0/7] Host1x/VIC support on Tegra264 Mikko Perttunen
                   ` (5 preceding siblings ...)
  2026-06-12  6:32 ` [PATCH 6/7] drm/tegra: vic: Add Tegra264 support Mikko Perttunen
@ 2026-06-12  6:32 ` Mikko Perttunen
  6 siblings, 0 replies; 13+ messages in thread
From: Mikko Perttunen @ 2026-06-12  6:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

Tegra264 has a host1x instance with a VIC (video image compositor).
Other multimedia engines have moved outside host1x. Stream IDs are
now namespaced by device rather than being defined globally --
however, the only engine we have using context isolation is VIC so
we only define VIC's range of context devices.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra264.dtsi | 63 ++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
index 06d8357bdf52..fc398975a830 100644
--- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
@@ -3807,6 +3807,69 @@ its: msi-controller@40000 {
 		};
 	};
 
+	/* VISION MMIO */
+	bus@8180000000 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x000 0x00000000 0x81 0x80000000 0x00 0x10000000>, /* MMIO (256 MiB) */
+			 <0x100 0x00000000 0x00 0x20000000 0x00 0x40000000>, /* non-prefetchable memory (32-bit) */
+			 <0x200 0x00000000 0xa8 0x80000000 0x57 0x80000000>; /* I/O, ECAM, prefetchable memory (64-bit) */
+
+		host1x@1200000 {
+			compatible = "nvidia,tegra264-host1x";
+			reg = <0x0 0x1200000 0x0 0x10000>,
+			      <0x0 0x1210000 0x0 0x10000>,
+			      <0x0 0x1240000 0x0 0x10000>;
+			reg-names = "common", "hypervisor", "vm";
+			interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "syncpt0", "syncpt1", "syncpt2", "syncpt3", "syncpt4",
+					  "syncpt5", "syncpt6", "syncpt7", "host1x";
+			clocks = <&bpmp TEGRA264_CLK_HOST1X>;
+			clock-names = "host1x";
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+
+			ranges = <0x000 0x00000000 0x00 0x08000000 0x00 0x01000000>,
+				 <0x000 0x02800000 0x00 0x0a800000 0x00 0x00800000>;
+
+			interconnects = <&mc TEGRA264_MEMORY_CLIENT_HOST1XR &emc>;
+			interconnect-names = "dma-mem";
+			iommus = <&smmu1 TEGRA264_SID_HOST1X>;
+			dma-coherent;
+
+			/* Context isolation domains */
+			iommu-map = <0 &smmu1 (TEGRA264_SID_VIC + 1) 16>;
+
+			vic@50000 {
+				compatible = "nvidia,tegra264-vic";
+				reg = <0x0 0x50000 0x0 0x40000>;
+				interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&bpmp TEGRA264_CLK_VIC>;
+				clock-names = "vic";
+				resets = <&bpmp TEGRA264_RESET_VIC>;
+				reset-names = "vic";
+				power-domains = <&bpmp TEGRA264_POWER_DOMAIN_VIC>;
+				interconnects = <&mc TEGRA264_MEMORY_CLIENT_VICR &emc>,
+						<&mc TEGRA264_MEMORY_CLIENT_VICW &emc>;
+				interconnect-names = "dma-mem", "write";
+
+				iommus = <&smmu1 TEGRA264_SID_VIC>;
+				dma-coherent;
+			};
+		};
+	};
+
 	/* DISP_USB MMIO */
 	bus@8800000000 {
 		compatible = "simple-bus";

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/7] dt-bindings: display: tegra: Changes to support Tegra264
  2026-06-12  6:32 ` [PATCH 1/7] dt-bindings: display: tegra: Changes to support Tegra264 Mikko Perttunen
@ 2026-06-12  6:40   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-06-12  6:40 UTC (permalink / raw)
  To: Mikko Perttunen; +Cc: devicetree, robh, dri-devel, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Globally relaxing the `ranges` property weakens validation for all prior generations and fails to enforce the new requirement for Tegra264.
--

commit 318044f1bf4d519c5f4796553c5fa864bbc6d439
Author: Mikko Perttunen <mperttunen@nvidia.com>

dt-bindings: display: tegra: Changes to support Tegra264

This commit adds the nvidia,tegra264-host1x compatible string to the Tegra
host1x bindings. It updates the global ranges property to allow up to two
items, as the Tegra264 engine register range is no longer continuous.

> diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
> index 3563378a01af4..5b0e3158aa5be 100644
> --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
> +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml

[ ... ]

> @@ -57,7 +58,8 @@ properties:
>      enum: [1, 2]
>  
>    ranges:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 2

[Severity: Medium]
Does globally relaxing the ranges constraint weaken validation for all prior
generations? It seems this allows older hardware to incorrectly specify two
ranges and silently pass validation.

[ ... ]

> @@ -192,6 +194,7 @@ allOf:
>            contains:
>              enum:
>                - nvidia,tegra234-host1x
> +              - nvidia,tegra264-host1x
>      then:
>        properties:
>          reg-names:

[Severity: Medium]
Since the commit message notes Tegra264 requires two range entries, should
Tegra264 have a specific conditional block to enforce exactly two ranges
(minItems: 2, maxItems: 2)? Grouping it here without a specific constraints
block might allow a configuration with only one range entry to silently pass
validation despite the hardware requirement.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-t264-host1x-v1-0-8d934987de67@nvidia.com?part=1

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/7] gpu: host1x: Add Tegra264 support
  2026-06-12  6:32 ` [PATCH 4/7] gpu: host1x: Add Tegra264 support Mikko Perttunen
@ 2026-06-12  6:43   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-06-12  6:43 UTC (permalink / raw)
  To: Mikko Perttunen; +Cc: devicetree, robh, conor+dt, dri-devel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The macro `HOST1X_UCLASS_INDOFF_RWN_READ_V` is missing due to a copy-paste error that instead incorrectly duplicates the definition of `HOST1X_UCLASS_INDOFF_INDROFFSET_F(v)`.
--

commit bc3ed2efd3fa7eeadce14ecd91452f9ad7d9471e
Author: Santosh BS <santoshb@nvidia.com>

gpu: host1x: Add Tegra264 support

Add device data and chip headers for Tegra264.

> diff --git a/drivers/gpu/host1x/hw/hw_host1x10_uclass.h b/drivers/gpu/host1x/hw/hw_host1x10_uclass.h
> new file mode 100644
> index 0000000000000..abe83e67fa837
> --- /dev/null
> +++ b/drivers/gpu/host1x/hw/hw_host1x10_uclass.h

[ ... ]

> +static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
> +{
> +	return (v & 0xffff) << 2;
> +}
> +#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
> +	host1x_uclass_indoff_indroffset_f(v)
> +static inline u32 host1x_uclass_indoff_rwn_read_v(void)
> +{
> +	return 1;
> +}
> +#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
> +	host1x_uclass_indoff_indroffset_f(v)

[Severity: Low]
This isn't a bug, but it looks like HOST1X_UCLASS_INDOFF_INDROFFSET_F is
accidentally duplicated here instead of defining the macro wrapper
HOST1X_UCLASS_INDOFF_RWN_READ_V for host1x_uclass_indoff_rwn_read_v.

> +static inline u32 host1x_uclass_load_syncpt_payload_32_r(void)
> +{
> +	return 0x4e;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-t264-host1x-v1-0-8d934987de67@nvidia.com?part=4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 5/7] drm/tegra: falcon: Add support for RISC-V external boot
  2026-06-12  6:32 ` [PATCH 5/7] drm/tegra: falcon: Add support for RISC-V external boot Mikko Perttunen
@ 2026-06-12  6:44   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-06-12  6:44 UTC (permalink / raw)
  To: Mikko Perttunen; +Cc: dri-devel, conor+dt, robh, devicetree

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Missing size validation for the `.desc` firmware file allows an out-of-bounds read of the firmware descriptor buffer.
- [High] Inverted condition in `falcon_wait_idle()` for RISC-V incorrectly waits for the CPU to become active rather than idle, causing premature return.
- [High] Firmware segment offsets and sizes from the `.desc` file are not validated against the main firmware buffer size, leading to out-of-bounds DMA reads.
- [Medium] Missing endianness conversion when reading `u32` fields from the `.desc` firmware descriptor breaks on big-endian architectures.
--

commit 9b921eae84dc7cacf7c324bd76e166d6a5d942be
Author: Mikko Perttunen <mperttunen@nvidia.com>

drm/tegra: falcon: Add support for RISC-V external boot

This commit adds support for loading and booting RISC-V firmwares on Falcons
with RISC-V hardware. It introduces a new firmware layout and uses different
registers for the boot flow compared to traditional Falcons.

> diff --git a/drivers/gpu/drm/tegra/falcon.c b/drivers/gpu/drm/tegra/falcon.c
> index 17f616bbcb45b..1172356b6af3b 100644
> --- a/drivers/gpu/drm/tegra/falcon.c
> +++ b/drivers/gpu/drm/tegra/falcon.c
> @@ -26,8 +26,12 @@ int falcon_wait_idle(struct falcon *falcon)
>  {
>  	u32 value;
>  
> -	return readl_poll_timeout(falcon->regs + FALCON_IDLESTATE, value,
> -				  (value == 0), 10, 100000);
> +	if (falcon->riscv)
> +		return readl_poll_timeout(falcon->regs + RISCV_CPUCTL, value,
> +					  (value & RISCV_CPUCTL_ACTIVE_STAT_ACTIVE), 10, 100000);

[Severity: High]
Does this condition successfully terminate when the CPU is active rather than
idle?

If falcon_boot() calls this immediately after issuing the STARTCPU command,
the processor will instantly become active, and the wait will return
immediately instead of waiting for the processor to go idle. Would negating
the condition to !(value & RISCV_CPUCTL_ACTIVE_STAT_ACTIVE) correctly wait
for the firmware boot sequence to finish?

> +	else
> +		return readl_poll_timeout(falcon->regs + FALCON_IDLESTATE, value,
> +					  (value == 0), 10, 100000);
>  }

[ ... ]

> @@ -122,6 +126,17 @@ static int falcon_parse_firmware_image(struct falcon *falcon)
>  	return 0;
>  }
>  
> +static void falcon_parse_firmware_desc(struct falcon *falcon)
> +{
> +	struct falcon_fw_riscv_desc *desc =
> +		(struct falcon_fw_riscv_desc *)falcon->firmware.desc_firmware->data;

[Severity: High]
Is it possible for the loaded firmware file to be smaller than
sizeof(struct falcon_fw_riscv_desc)?

If a truncated or malformed .desc file is loaded from userspace, could
casting and reading desc_firmware->data here result in an out-of-bounds
memory read of the allocated buffer?

> +
> +	falcon->firmware.code.offset = desc->code_offset;
> +	falcon->firmware.code.size = desc->code_size;
> +	falcon->firmware.data.offset = desc->data_offset;
> +	falcon->firmware.data.size = desc->data_size;

[Severity: Medium]
Do these assignments need endianness conversion, such as le32_to_cpu()?

The older .bin parsing path safely copies and byte-swaps the firmware via
falcon_copy_firmware_image(). Since this RISC-V path appears to perform
no conversions, could reading these fields directly from the raw byte
array produce incorrect, byte-swapped values on big-endian architectures?

[Severity: High]
Are these offsets and sizes validated against the main firmware buffer size?

In falcon_boot(), these sizes are used to calculate bounds and program
the Falcon hardware DMA engine via falcon_copy_chunk():

falcon_boot() {
    ...
    for (offset = 0; offset < falcon->firmware.data.size; offset += 256)
        falcon_copy_chunk(falcon,
                          falcon->firmware.data.offset + offset,
                          offset, FALCON_MEMORY_DATA);
    ...
}

If the values are not checked to ensure
offset + size <= falcon->firmware.size, could a maliciously crafted .desc
file instruct the DMA controller to read out-of-bounds physical memory?

> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-t264-host1x-v1-0-8d934987de67@nvidia.com?part=5

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/7] gpu: host1x: Correctly parse linear ranges of context devices
  2026-06-12  6:32 ` [PATCH 3/7] gpu: host1x: Correctly parse linear ranges of context devices Mikko Perttunen
@ 2026-06-12  6:45   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-06-12  6:45 UTC (permalink / raw)
  To: Mikko Perttunen; +Cc: robh, dri-devel, devicetree, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] The driver synchronously frees the dynamically allocated `cdl->devs` array immediately after calling `device_unregister()`, while using an empty `.release()` callback. This violates the Linux device model and leads to a Use-After-Free.
--

commit 46b291569da04e8306d82ff644615dfc60ee956f
Author: Mikko Perttunen <mperttunen@nvidia.com>

gpu: host1x: Correctly parse linear ranges of context devices

The commit updates the parsing of the iommu-map property to support
linear ranges of context devices instead of assuming each device has
a one-length entry.

> diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c
> --- a/drivers/gpu/host1x/context.c
> +++ b/drivers/gpu/host1x/context.c
[ ... ]
> @@ -34,7 +34,16 @@ int host1x_memory_context_list_init(struct host1x *host1x)
>  	if (err < 0)
>  		return 0;
>  
> -	cdl->len = err / 4;
> +	devs = 0;
> +
> +	for (i = 0; i < err / 4; i++) {
> +		u32 length;
> +
> +		of_property_read_u32_index(node, "iommu-map", i * 4 + 3, &length);
> +		devs += length;
> +	}
> +
> +	cdl->len = devs;
>  	cdl->devs = kzalloc_objs(*cdl->devs, cdl->len);

[Severity: High]
This isn't a bug introduced by this patch, but there is a pre-existing
issue with how the cdl->devs array is managed during cleanup.

In host1x_memory_context_list_init(), if an error occurs later in the
initialization, the unreg_devices error path unregisters the devices and
immediately frees the array:

host1x_memory_context_list_init() {
    ...
unreg_devices:
    while (i--)
        device_unregister(&cdl->devs[i].dev);
        
    kfree(cdl->devs);
    ...
}

The same pattern appears in host1x_memory_context_list_free() during
normal teardown.

The driver also provides a dummy release callback:

static void host1x_memory_context_release(struct device *dev)
{
    /* context device is freed in host1x_memory_context_list_free() */
}

Could this lead to a use-after-free? When device_unregister() is called,
it drops the initial device reference, but sysfs or userspace might still
hold elevated references to the embedded kobjects.

Since kfree(cdl->devs) is called synchronously while references could
still exist, would userspace interaction with the sysfs attributes for
these devices during teardown end up accessing freed memory?

>  	if (!cdl->devs)
>  		return -ENOMEM;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-t264-host1x-v1-0-8d934987de67@nvidia.com?part=3

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/7] drm/tegra: vic: Add Tegra264 support
  2026-06-12  6:32 ` [PATCH 6/7] drm/tegra: vic: Add Tegra264 support Mikko Perttunen
@ 2026-06-12  6:47   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-06-12  6:47 UTC (permalink / raw)
  To: Mikko Perttunen; +Cc: dri-devel, devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Out-of-bounds read when parsing the RISC-V firmware descriptor.

Pre-existing issues:
- [High] Out-of-bounds read and potential crash when parsing internal offsets from the loaded firmware image.
- [High] Use-After-Free in error paths of `vic_load_firmware()` due to dangling pointer.
--

commit e93ea0b6d1fe675fec33102f35c8bdffae0a5687
Author: Mikko Perttunen <mperttunen@nvidia.com>

drm/tegra: vic: Add Tegra264 support

Add support for VIC on Tegra264. The Tegra264 VIC uses a RISC-V based
Falcon microcontroller instead of the traditional Falcon previously,
and has the TRANSCFG register in a different place.

> diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
> --- a/drivers/gpu/drm/tegra/vic.c
> +++ b/drivers/gpu/drm/tegra/vic.c
[ ... ]
> @@ -85,31 +92,50 @@ static int vic_boot(struct vic *vic)
>  			CG_WAKEUP_DLY_CNT(4),
>  		   NV_PVIC_MISC_PRI_VIC_CG);
[ ... ]
> +	} else {
> +		u32 fce_ucode_size, fce_bin_data_offset;
> +		void *hdr;
> +
> +		hdr = vic->falcon.firmware.virt;
> +		fce_bin_data_offset = *(u32 *)(hdr + VIC_UCODE_FCE_DATA_OFFSET);
> +
> +		/* Old VIC firmware needs kernel help with setting up FCE microcode. */
> +		if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) {
> +			hdr = vic->falcon.firmware.virt +
> +				*(u32 *)(hdr + VIC_UCODE_FCE_HEADER_OFFSET);
> +			fce_ucode_size = *(u32 *)(hdr + FCE_UCODE_SIZE_OFFSET);

[Severity: High]
This is a pre-existing issue, but does this code perform an out-of-bounds
read when parsing internal offsets from the loaded firmware image?

It appears that nested offsets are read directly from the firmware image
without verifying that the firmware size is large enough, or that the
offsets point within the valid firmware boundaries. If a malformed or
truncated firmware file is provided, could this arbitrary offset lead to an
out-of-bounds read and a kernel page fault?

> +
> +			falcon_execute_method(&vic->falcon, VIC_SET_FCE_UCODE_SIZE,
> +					      fce_ucode_size);
> +			falcon_execute_method(
> +				&vic->falcon, VIC_SET_FCE_UCODE_OFFSET,
> +				(vic->falcon.firmware.iova + fce_bin_data_offset) >> 8);
> +		}
[ ... ]
> @@ -277,6 +303,8 @@ static int vic_load_firmware(struct vic *vic)
>  
>  	if (!vic->config->supports_sid) {
>  		vic->can_use_context = false;
> +	} else if (vic->config->has_riscv) {
> +		vic->can_use_context = true;
>  	} else if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) {
>  		/*
>  		 * Firmware will access FCE through STREAMID0, so context

[Severity: High]
This is a pre-existing issue, but can the error path in vic_load_firmware()
lead to a use-after-free?

If an error occurs during firmware loading, such as a failure in
falcon_load_firmware(), the cleanup path frees the allocated DMA memory
but seems to leave the firmware pointers dangling:

cleanup:
        if (!client->group)
                dma_free_coherent(vic->dev, size, virt, iova);
        else
                tegra_drm_free(tegra, size, virt, iova);

        mutex_unlock(&lock);
        return err;

If the device attempts to load the firmware again later, it might see
the non-null pointer, return success, and proceed to use the freed DMA
memory. Could this result in IOMMU faults and potential system crashes?

[ ... ]
> @@ -495,6 +537,7 @@ static int vic_probe(struct platform_device *pdev)
>  
>  	vic->falcon.dev = dev;
>  	vic->falcon.regs = vic->regs;
> +	vic->falcon.riscv = vic->config->has_riscv;
>  
>  	err = falcon_init(&vic->falcon);

[Severity: High]
Does enabling RISC-V support here expose an out-of-bounds read when
parsing the RISC-V firmware descriptor?

In falcon_parse_firmware_desc(), the descriptor data is cast to
struct falcon_fw_riscv_desc and fields at large offsets are read without
a preceding length check on the firmware size:

struct falcon_fw_riscv_desc *desc =
        (struct falcon_fw_riscv_desc *)falcon->firmware.desc_firmware->data;

falcon->firmware.code.offset = desc->code_offset;

If a truncated descriptor file is provided by userspace, could this
cause a buffer over-read and lead to a kernel page fault?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-t264-host1x-v1-0-8d934987de67@nvidia.com?part=6

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-06-12  6:47 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-12  6:32 [PATCH 0/7] Host1x/VIC support on Tegra264 Mikko Perttunen
2026-06-12  6:32 ` [PATCH 1/7] dt-bindings: display: tegra: Changes to support Tegra264 Mikko Perttunen
2026-06-12  6:40   ` sashiko-bot
2026-06-12  6:32 ` [PATCH 2/7] dt-bindings: display: tegra: Add Tegra264 compatible for VIC Mikko Perttunen
2026-06-12  6:32 ` [PATCH 3/7] gpu: host1x: Correctly parse linear ranges of context devices Mikko Perttunen
2026-06-12  6:45   ` sashiko-bot
2026-06-12  6:32 ` [PATCH 4/7] gpu: host1x: Add Tegra264 support Mikko Perttunen
2026-06-12  6:43   ` sashiko-bot
2026-06-12  6:32 ` [PATCH 5/7] drm/tegra: falcon: Add support for RISC-V external boot Mikko Perttunen
2026-06-12  6:44   ` sashiko-bot
2026-06-12  6:32 ` [PATCH 6/7] drm/tegra: vic: Add Tegra264 support Mikko Perttunen
2026-06-12  6:47   ` sashiko-bot
2026-06-12  6:32 ` [PATCH 7/7] arm64: tegra: Add Host1x and VIC on Tegra264 Mikko Perttunen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox