From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D5CD470130; Fri, 4 Sep 2026 10:45:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518723; cv=none; b=iQnrT4eDqz/6vGftdvfvk5uhokVQWGhoGJ7sQJIpXh7HHWS58ULfDtBajzUjYH/g2/F+Lxo/cLJqKKQJn5993F/i66AzwM3I20z0AGnj3aAjEdFamOBRQMrxpIKSSpQpboHW9KSZ+I1DPQvpHfxHUp8cE5w+9tPqQew5WgZ8qWw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518723; c=relaxed/simple; bh=ScjQCmJqu66W5maE8eMUSbpYSWVqT/TO89ycN7X6uU4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Uq7V3r1vPeQaTgKwCi2cRWOk+Em6Hpf56A8mKN7oUNOTRb4r5B5xWDjn8nrIPjArtJTiYk9+7OVoRhnWeJoNoHTlp4b4nh6iFk0UvhvH/eyvZmHeqDYQUFJ9+2E75VKBH+fc8gmQdH4ojB3lL6ZAoValTZI8RTlk96C6u8z5I8Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Cflxm78z; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Cflxm78z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85B8E1F00A3E; Fri, 4 Sep 2026 10:45:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518721; bh=Y3WFbhYTWczQCYOlTAjPPPmhWM8d8ALyu3lGu1XHIBs=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Cflxm78zPmElmE79iVcRd1zqdWwKbB4Zuq5lic8TpSsLVgJl4AqcQcagMqfeRPj85 svKzabACAzvErzQkWT5N8s5+IxHwcDEiVqY689SsTuv2KhZ9GUlFY0F397vVXjWez9 hcwtkLVZYSwarBuibgpTXgdnRSgBQboRTa8mw2PC3YnNJoDdtZlTAHFUk2PwEY9r7h ybXL0oUr0EwOMc9koSzfmcziqzqzxXoRTO50bqSnjxc3+UmGN3sdKnOUw7Di4qeALO A5he+y5G5OuiUxq/Rf/KF6CoGPjEQngWPPqY38JqnTCSgH0/ipUKCgpVBGQuhNylsg 50lpEBsavz90Q== From: Thierry Reding Date: Fri, 04 Sep 2026 12:44:52 +0200 Subject: [PATCH v6 01/12] dt-bindings: reserved-memory: Document Tegra VPR Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-1-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3632; i=treding@nvidia.com; h=from:subject:message-id; bh=lz5bdbUU9mR9/O2pGRVuSC+tGOj+4+d05JhFJg7QQcs=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE51zTFtK6El9Uth1TluaNXciidz0p6cGBHQ NSYqEB7AryJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOQAKCRDdI6zXfz6z oSJ9D/9ZyCFmV1msw3xlBtwgra24KMR9ILpX76qpP+kK/qxdJvKDzwFdwwQRA1uMjJNDCW3mT3q zbfvq/xX3Y0eVt2VK4WRewsIq2wWSVufBxpNWS8TFruIMf11mLI8TCxIpFsR+dsYmZXY6OL99vV SyNSKWOG6qCGYK+2RzJt4nfu1fxdW1xryTIyVso9W0Q3cmJAVar0WEtyodRdSx2uvFK4+Ex6pTG luJH1DEukYK0ylguH0nqIN3LgWIp6JefXc2/v9JWfDpR87IOTqYpHQC7l4iI/NleUABkrCcal0p fc0vRk/G+CL6agZUAHz9rfVmH9hG5OqceR4PjZZNyU6WXnV6NeRVO3p2zDzth9bFgPZojE4GUKG z2SkJcI/G++md69sTsESemWU13EWwEXg0M3k+sInpMyi6R72Mr4vCs2JQwhMs3lsh1LZcifjFPk b7V2nRhgoSWQZwDE96l8InInujIRlVwAiDDr5N8IgyqMHQ4sWWxl/lklqubJ+wj1bIVSmFkzzNw ulTGoFPU8Bui/9xo7Lf5jTgCIY2YvmjmXxx+HuaCBsgxifZddSQE5jVO+j1E85TyzS7tCttrju6 QgpkuWQrqwiH317BklyAntuKRIk81U8JfN6LZEcs2eelmldYc+GqPmyMr9vvSfWtQvLzu0khEGv 7N/GuHEDDe6KEGg== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding The Video Protection Region (VPR) found on NVIDIA Tegra chips is a region of memory that is protected from CPU accesses. It is used to decode and play back DRM protected content. It is a standard reserved memory region that can exist in two forms: static VPR where the base address and size are fixed (uses the "reg" property to describe the memory) and a resizable VPR where only the size is known upfront and the OS can allocate it wherever it can be accomodated. Reviewed-by: Rob Herring (Arm) Signed-off-by: Thierry Reding --- Changes in v4: - move oneOf into allOf for a bit more tidiness - fix example "reg" property Changes in v3: - add examples for fixed and resizable VPR --- .../nvidia,tegra-video-protection-region.yaml | 75 ++++++++++++++++++= ++++ 1 file changed, 75 insertions(+) diff --git a/Documentation/devicetree/bindings/reserved-memory/nvidia,tegra= -video-protection-region.yaml b/Documentation/devicetree/bindings/reserved-= memory/nvidia,tegra-video-protection-region.yaml new file mode 100644 index 000000000000..862bfd391378 --- /dev/null +++ b/Documentation/devicetree/bindings/reserved-memory/nvidia,tegra-video-= protection-region.yaml @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reserved-memory/nvidia,tegra-video-prot= ection-region.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVIDIA Tegra Video Protection Region (VPR) + +maintainers: + - Thierry Reding + - Jon Hunter + +description: | + NVIDIA Tegra chips have long supported a mechanism to protect a single, + contiguous memory region from non-secure memory accesses. Typically this + region is used for decoding and playback of DRM protected content. Vario= us + devices, such as the display controller and multimedia engines (video + decoder) can access this region in a secure way. Access from the CPU is + generally forbidden. + + Two variants exist for VPR: one is fixed in both the base address and si= ze, + while the other is resizable. Fixed VPR can be described by just a "reg" + property specifying the base address and size, whereas the resizable VPR + is defined by a size/alignment pair of properties. For resizable VPR the + memory is reusable by the rest of the system when it's unused for VPR and + therefore the "reusable" property must be specified along with it. For a + fixed VPR, the memory is permanently protected, and therefore it's not + reusable and must also be marked as "no-map" to prevent any (including + speculative) accesses to it. + +allOf: + - $ref: reserved-memory.yaml + - oneOf: + - required: + - compatible + - reg + + - required: + - compatible + - size + +properties: + compatible: + const: nvidia,tegra-video-protection-region + +dependencies: + size: [alignment, reusable] + alignment: [size, reusable] + reusable: [alignment, size] + + reg: [no-map] + no-map: [reg] + +unevaluatedProperties: false + +examples: + - | + /* resizable VPR */ + protected { + compatible =3D "nvidia,tegra-video-protection-region"; + + size =3D <0x0 0x70000000>; + alignment =3D <0x0 0x100000>; + reusable; + }; + + - | + /* fixed VPR */ + protected@a8000000 { + compatible =3D "nvidia,tegra-video-protection-region"; + + /* fixed VPR */ + reg =3D <0xa8000000 0x70000000>; + no-map; + }; --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7FC8B4734CC; Fri, 4 Sep 2026 10:45:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518726; cv=none; b=b1W00e4GAQIQsuDIwLIxZ2cOI5W/HZVyL1Hk1fe0e9sUAvt4e/UEAnxhUTQGGHr/0YZ+MxQP4zoWZdD1UVbKXD5cn4QsD1NXOAG56BDkSI4/+WZmHWFfbbjXWUMn3jup5k0E8qNmTe21c9jV9tGAjZLgC+46hW6jHHtdx4Kc4wA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518726; c=relaxed/simple; bh=KZt42RcI2xZOV6ZL4xNzHGcUviEo1o5J+l+Mdce427o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iprRD7E4LlG2llYGpBNpq+cK8sJtX1hCC8AkvtbNi3wBfJLb1h9f2Q/701mmDkTQHKRu1gspjvhP8JedEwvfsAYgk8XslS0I+W1uoMwPYQ54UMOdcch2okNz8pDE1VVjlvKM+n4QnMCh9IAV8P9OUnWJCFxm03CgHkYlJs1dKiI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=W7qjQCNS; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="W7qjQCNS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5888C1F00A3F; Fri, 4 Sep 2026 10:45:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518724; bh=eBlEuAoqOked/LKJu9mRAOEywcTF2CIu7f/dTPjyTCg=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=W7qjQCNSCGZXXbyc8J6OTl+dQX2qqTPLVjOZKbya9DaDtLYXNDq7yOSjCiH1Fzmgo j56j7wBwCKgUFodXzPAzL44OFOVSiFiFB0CvB/ZPoNY++4LLfUpv/1blCs5hrACui9 7s3xQ8px/dRmqO1WqB7SNO1OwaM8sT6TH0S7lQdEJ5iufiYOMh563huoUusBqCgBCB zhHSeRVxDESEqeAASr3hnpXE5pStPPx3KVcFlwkWCZcMWP/CilLTYfN9qTVoErlRHl 4e5cB+aYiwobAfiBrDJkRzORM9Qlzq/j4AcH/+K0EYc4RubGDf6QCNgHP2XBX7SfFv lmBN6OJRScywQ== From: Thierry Reding Date: Fri, 04 Sep 2026 12:44:53 +0200 Subject: [PATCH v6 02/12] dt-bindings: display: tegra: Document memory regions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-2-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3649; i=treding@nvidia.com; h=from:subject:message-id; bh=pBYGfO+OoRCfoGlySA1v5aSrpzUlJ6EhDp5j2u2Nips=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE6g4z7jq+Sip+gg86QNRWNnQFHfWBE9B9un WUw4njXGJ+JAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOgAKCRDdI6zXfz6z oTHMD/9TaZE5hzVAIbzqNa7syKW4k6S0ycYYYrVebi+lRO2QXDPm/tiDrM/ofrEIhvjWjXhW6Sd vhsLe4VBQt5yWfvAQpdM7PkubSeMTlUl/kdcw18kKnGBzhK8BLC1EzF6+JsNcBHxlCj005NiZnv EGUWrm6j4L7rV0ZB56H/YkwhfZakABtZzFtWy1Yfq7pOhVfJsrSkvNJBqJuH9DAAmuGIHEckjee 5ExquwU8/hHHEod/bY8sGI4eDSLUOlotFszxJwKNPVm1uTrYp7Nm5G/2AysJTTQFUJi3ZDtQL23 EEv7fLVyDGez4estd42id989nAFMj9+W74/fntP858iqMU1Nto0lx8CN5vLdGFgbl31BK4xjPk2 CMDIGbPh9gAr0h5ODf9C2XizTrcP0s7kJL7pDwKFcW96yuRRWeFt4AzlYmVjYYoy4iD8S57QLM0 iszSa/8npHYY5cwXNF1+27CG7wfaeEoD86ohEqnukcb5BtUvO7yLGGPT1FSakUf9b95savaDHDQ 48J3/vfeH9HEU7THe9IdVTzFGFEZCQamYrYCA/dkcc9Ba3fMbJhJiWd6yXSueej1R/H/jm0d34t 633FWGP86kmFzarMQXxJcNsP0IMtCM02qoW1TN0rPTFHOzlA16p6cgHvrJm95lWm0j/lYcXDkZc FajeSlJPG5eUtcA== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding Add the memory-region and memory-region-names properties to the bindings for the display controllers and the host1x engine found on various Tegra generations. These memory regions are used to access firmware-provided framebuffer memory as well as the video protection region. Reviewed-by: Rob Herring (Arm) Signed-off-by: Thierry Reding --- Changes in v4: - typofix Changes in v3: - document properties for VIC --- .../devicetree/bindings/display/tegra/nvidia,tegra124-vic.yaml | 8 ++++++= ++ .../devicetree/bindings/display/tegra/nvidia,tegra186-dc.yaml | 10 ++++++= ++++ .../devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml | 10 ++++++= +++- .../bindings/display/tegra/nvidia,tegra20-host1x.yaml | 7 +++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra12= 4-vic.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra12= 4-vic.yaml index bdf981781bd5..fdd3fe9e2547 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.y= aml +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra124-vic.y= aml @@ -68,6 +68,14 @@ properties: - const: dma-mem # read - const: write =20 + memory-region: + items: + - description: reference to the video protection memory region + + memory-region-names: + items: + - const: protected + dma-coherent: true =20 additionalProperties: false diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra18= 6-dc.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186= -dc.yaml index ce4589466a18..881bfbf4764d 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dc.ya= ml +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra186-dc.ya= ml @@ -57,6 +57,16 @@ properties: - const: dma-mem # read-0 - const: read-1 =20 + memory-region: + minItems: 1 + maxItems: 2 + + memory-region-names: + items: + enum: [ framebuffer, protected ] + minItems: 1 + maxItems: 2 + nvidia,outputs: description: A list of phandles of outputs that this display controller can drive. diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20= -dc.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-d= c.yaml index 69be95afd562..3bf06dcd6198 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml @@ -65,7 +65,15 @@ properties: items: - description: phandle to the core power domain =20 - memory-region: true + memory-region: + minItems: 1 + maxItems: 2 + + memory-region-names: + items: + enum: [ framebuffer, protected ] + minItems: 1 + maxItems: 2 =20 nvidia,head: $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20= -host1x.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra= 20-host1x.yaml index 8312b7699cbe..420a1fe5ee80 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x= .yaml +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x= .yaml @@ -98,6 +98,13 @@ properties: items: - description: phandle to the HEG or core power domain =20 + memory-region: + maxItems: 1 + + memory-region-names: + items: + - const: protected + required: - compatible - interrupts --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0130646DFF1; Fri, 4 Sep 2026 10:45:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518729; cv=none; b=tYuKW29Buo8rgmcZt6iTCFpIg5vwSvY1vZFHnUYEau1WgFSLPuDc5huAmHrvFJl/f+CVomU+nngTONCUO162KyfKgomjiWV42RS+dsVfZxeAXyZaAj0qNMJ3GmWlEFyf46UFdIfglDEwXxVN1TAOdAyfZ6YHDVjvYvvYF3vdOpg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518729; c=relaxed/simple; bh=D4Xh9zc5N/4RWPWjcg0XK0nxc0XsnOaquGDBNqbZDwM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rX5ecesVC0TG4EU7no+S5QuOZWka3PxcOVzgH2apuEoUp6ctLijPy0EomDt6b8UyI1dZxmtw4Bh2MB2tUfMTmc72raLP4vZGqwxd7mg9QHTnDUkw++Z53fl5RTFvdB5//efKgO7k5N+vwSg/KO/rbsw2Ydt3drY8ZcHzL3Ua0ro= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=P4VteYfZ; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="P4VteYfZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 211151F00A3E; Fri, 4 Sep 2026 10:45:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518726; bh=hagYf35q6G2UhsHzty44d2izTZaC/NeM9Zitkk0WHRQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=P4VteYfZoOUKRz6lqankTJMKJHc22APwmujZJPl/o9mFh+IaXlyFuO4ak0voN5g1+ SkPOsetnsV8OgScpk2tWZMqM6V6brZ2/wcoAJdD37U/u1/ZUhg5SWVOjIeHELTS65P pbrK8W62YAb2sNPLRs8sJuv4H8SIWeVvm/qt2Bop5lmROPJTj6ET2fTuqE1+ltqHmJ cdFluDoQEkGzlkB2wggIhYLNLCP+idVVB06/yEMa5e2gQXMUSkDDSzsSzyojU8FSGA q3Le5bnorB5CtElF/RC4Yo0O8r1V1S75q7G6ZZomHcMbEjcxVMbnTKjkjyZ8sS5iWJ jw0cjbyxhhxxA== From: Thierry Reding Date: Fri, 04 Sep 2026 12:44:54 +0200 Subject: [PATCH v6 03/12] dt-bindings: gpu: host1x: Document memory-regions for NVDEC Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-3-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1123; i=treding@nvidia.com; h=from:subject:message-id; bh=96od8SnVSYMiavrRwbh7Ehk1YxWlsQuy9Uk4ZKu5YoI=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE6a7RpJI/GCW4mTGRJ87hxtCRDZnRUuKBN7 pMhWoYQXcOJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOgAKCRDdI6zXfz6z occEEACxZ8dNEU7BnEN2Ha6fyLYWa+f1AwIxLCAG071sdb02B+kE1t9bISlQZt9JywhEH3ommb6 efRnWfcpz3n38v0h0WnFrjzBJgURRzhc3NWBBpF4on5vJuXUFd14lhkleafdS1eTlcX+2jhKsX1 seoHP+vg0Ks6FKmpTL0OKgtrKgy6ku+wkPNhK2pUylTPM4v6NP9j5OEKOCJ2TkFjwRUx1/i6viq j2hDpWCI+onyBKR5P5Lf90rVaBhYDO8zZpivHAvfwexg/kCj+UCVg0GE6cwNIo6e3AOYZS4fYUC E9H4MftsWwewlBj1Zq2KjRC3hyTfWS5DLPp59ZRTbgeLWg8iA5wuGJ/ED+CIHYUvticQ93nMVA1 n7gvWqthSmuAunsNZx8nmg0jwJYFVmG38lGOYm2wYbwE9brDWT2neM6V2lM3zvfaNDffWqDy3mq hYEZq1xglKDRgNdZ+JPDMHDHHc0dL+1HqbX46xkB0bO/vni8UXpBZTLR/vikYgRGc6l+a0/Bxs+ 6/BcZttVbk+FEyNWKKHRCbF9oeSxsA6iPh/5W7ER4DU5e8yF0DlSE0KEpIkxMbhHTPVwqvQewrW zHc6+V4hT2sFlQ1D1Y7fcOVlrGyML932LvpQOio2aw9cbloake8bpTwzaOZi7hyrxZ99VMjAQLt EEsWSIg7v53KUNg== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding The video protection region is a reserved memory region that can be used for secure video playback. NVDEC can access this region to decode images into securely. Reviewed-by: Rob Herring (Arm) Signed-off-by: Thierry Reding --- .../devicetree/bindings/gpu/host1x/nvidia,tegra234-nvdec.yaml | 8 ++++= ++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra234-n= vdec.yaml b/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra234-nv= dec.yaml index 4eb325cfd296..bcaaabca945d 100644 --- a/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra234-nvdec.ya= ml +++ b/Documentation/devicetree/bindings/gpu/host1x/nvidia,tegra234-nvdec.ya= ml @@ -60,6 +60,14 @@ properties: - const: dma-mem - const: write =20 + memory-region: + items: + - description: reference to the video protection memory region + + memory-region-names: + items: + - const: protected + nvidia,memory-controller: $ref: /schemas/types.yaml#/definitions/phandle description: --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 276A8477291; Fri, 4 Sep 2026 10:45:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518732; cv=none; b=iTm7hdMNWWhLjWv7aDfjtvWgwmE9JJG8eMG5wLbMw2J7tX7CLSTQXcRycNVNBOlPsg3h8Y9hymmNba9q/QMdDXSQrPd9W0GvyKYIUaymBKTfL7RpPTRpv6ITSzHdXcuIcK2qp8aaL0c8idU4r25P7//9OV6GUsi2x+E7uNwpEfo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518732; c=relaxed/simple; bh=VaL/uV3xEkx2Mhht9nr2MPOiNG6aXOb30NSjxY/Ts6w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LlrssejNSVFS1QJbl7ux2c52tFiC5OiCw+p6tA/4UyyFCWT6kY6y9EbrfwVVvfCQKkw403AO+FGjwcDq753kH9ISlgL34v1Uw2W7guisik5rt4JWVIvfQ59jaNO60Wt6UXL3xNxj3beWOfMjrH9BKkwLr4o+uzzwSoYUovHkhzQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ge/Wyc+a; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ge/Wyc+a" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EA0FA1F00ADF; Fri, 4 Sep 2026 10:45:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518729; bh=ywgp/pHfl+lA6AvsB1zv7ftqiWMvHJVARqEHp5d3uMA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=ge/Wyc+aaEqvFnsoCBLmmHxDP2ZrFsI76uOFZedKIyr3ObjIeJehqTg/E/e4qyHqz RS2fdjU20oGmEzZbwFbjGznSL0/Jc0/BbBAKwE+1TGN77/9r/ctsXXwNjpFK3h5N8E 9//1N6WjKRUGuCSZLU2UPtMWn5MH8udTFO77aWBnc9Blk8heAf2sjncGA4/OUqaWiw hviqgWQK+x/0ZyeqTGloK7D8LR+vbsJzC5suRNfxpI/nrfbY2i2LJ8mxekylPof/SP QllQE4G4a05osclFK3ydp7vEZeEjmnTYfutnB68stAiHS9QQrGqYmvRiVEUGEauaI/ YP2HaE6K0j+mQ== From: Thierry Reding Date: Fri, 04 Sep 2026 12:44:55 +0200 Subject: [PATCH v6 04/12] arm64/mm: Export set_direct_map_*_noflush() APIs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-4-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1083; i=treding@nvidia.com; h=from:subject:message-id; bh=aIM9S+b4eUaYPFPTqciGrMGQP2g0bdZA73J57AFYD/0=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE6y9LZb0fTu1fD2MuKJlskXvqXRscG5DRpw 2HGzz+KC/WJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOgAKCRDdI6zXfz6z oZ+tEACbMm5y/9flV4B7lKc8c7sppUYfz2sbPsDFHHFGgAEXu0hrxqgbkreSsnbS8Y9VM3SHYU6 BIhWV65aiGSz9zanzQqW0gUp6Ik+a9ZDiQ42QrejAoXtHqLtiJIBCvBGPElSqa4nFWQKrt54t2u VoIWmYskkNKk4ySyAoyMQdiLxvfqDiqPcuDYOKjmHq9u3hZL5FYTCfWMsH86RPe3xq3cWhIAdgp CSJTdwjOtQkEk3XCT5nyw5+bW4h7LEBJ4UzuNfeT8TYCoHw1bt8gO33t8GR5XgTajrdjVC6OhrD ruXH+RxCak8NyrklGIImjHCjsflgXqYRWVoOG8MejJ7Kbck+ql3IpUlTuFBn8DBYhYmr7h5aEXG dIyUpdgttoGOllBhebafHIEs1QTAPwh39wkOefhQCLmY4NrgJhp6iORWs93GZqDVMwr2wp/37mH nV6fa/DQn7PtV82lupwtW7dizZAARJAj38jqpSk2fNBy8n0V9JOQl+4O9Lodc0vIJSE1GPEmuLG ktMY7hPZQs7PBDvedNWcLwkxqHaLWxIRj1QXn8BqTft/3FZA05MqDViAtIWTTa5df/rTUg1UW51 MkEw02uH/BB7iJWaabxssoUEhygxoSsbRbPaCkAyHPyd6ADUyywmWGqqCq9xvJiGo1Y8sPiLj9P TCgI7/FYwlN/EDA== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding Drivers that use this may want to be built as a module, so export them. Signed-off-by: Thierry Reding --- arch/arm64/mm/pageattr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index 132938b32eb1..9253c529f8aa 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -262,6 +262,7 @@ int set_direct_map_invalid_noflush(struct page *page, u= nsigned int numpages) return update_range_prot((unsigned long)page_address(page), PAGE_SIZE * numpages, set_mask, clear_mask); } +EXPORT_SYMBOL(set_direct_map_invalid_noflush); =20 int set_direct_map_default_noflush(struct page *page, unsigned int numpage= s) { @@ -274,6 +275,7 @@ int set_direct_map_default_noflush(struct page *page, u= nsigned int numpages) return update_range_prot((unsigned long)page_address(page), PAGE_SIZE * numpages, set_mask, clear_mask); } +EXPORT_SYMBOL(set_direct_map_default_noflush); =20 static int __set_memory_enc_dec(unsigned long addr, int numpages, --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 53A1E47A892; Fri, 4 Sep 2026 10:45:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518735; cv=none; b=PqSlHSvwcqt3CCMgGz3zaQykbNIJIrUFCcPAkssHWhXS+MWGXWH/RG5ABlzXihmYLeLNvKJwljR/Gh/Pyq8vF9Kxajn1TwCglhAkDF+H8LH8iyOddfFvLA18328pVe0ae+NKnCqT34qTFYgRvvf2NwGQ7wXLNkvPzxijElMCPT8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518735; c=relaxed/simple; bh=oJmc2yMjXHZBAgsG3MI/UFS/Acfo/2sOqteRP01Z7dM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TM5TaUuHFREHUHMZrR3osZU1gls9PhG4a9tTEJu5A1TYdwvUPUPcp5+RQZCIjY6eQIYKX1YahoIDAGxSykQZViMg0ueMHCq6h2utg7z6fEteo/BvI1Ia1XuiYg1IBSZFWFxCQnnMIh/4zIQqTNmA6dEcM7bMDxwFQFTY+AKUDPQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=isV2IgZu; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="isV2IgZu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BACE11F00A3F; Fri, 4 Sep 2026 10:45:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518732; bh=tvyd01m5FmUtu3q6l/t0/X1UQi3FbzSuZHwJCHFz3QM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=isV2IgZuqaEj8L6w5TATquMIISnjgvRvBLrttVMb2J3/qELjt9chFPiUY34MdPhYP U28wPbZT8ogHrGtyUr5RJLQSczYHZExyBqdqMTuDI4gEZeqEhLhF7nUfxbbgN5LSLg WpGf0U5aqCH3nfFsuGuAY5TAdMaRGNYw4DPjF1ZLmFN3bIn6UXfe4cqWr+MNfTnNvu S6KbiqTp0Jv0ibjBYHeuTnW7BAKozymnTvHSpJwEHw8uX/NLpZSTc44eFq0eoqawMc D9BkZU83noFXqptzh6Me0L7ADkDCNvLNKqKkWO6JZ37eeSuyw+i+hWbz0qXVlN6AGu 3HNhAB4yeUGRQ== From: Thierry Reding Date: Fri, 04 Sep 2026 12:44:56 +0200 Subject: [PATCH v6 05/12] bitmap: Add bitmap_allocate() function Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-5-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2300; i=treding@nvidia.com; h=from:subject:message-id; bh=wRtcGoPPtBVnuqzylzx/Ya02XdoWLRjgy09wPiiWfTU=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE6FB7y46zRAFj+W91sU31vLRZ9vxOWfwPV5 Zl4kuw26HOJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOgAKCRDdI6zXfz6z oeAMEACJJndPxZkKMt6p/5hvrc40QBNDQZ+kF6WmhtnFd/6EVpvs0pjUb8O3if3mkq4TtTKowKz kIuYwA01ot+/ztJA5scT5H/tCqLx/Qds237aUUTv/IzEoq2K4YW/FlTvmXelPijG5HS9T+GeFXV RxODMakq1BUp1WBx0Fvx3tiI40Ukv9zyhQFgNYpIld1ACRlTawrq/ce0NYFwF5wGFaPKkbsEIO3 SOwvT5W5s5BuxLJknJq4AaldPvitW5S1LIvagCvP3/wQcvXSXufgOm2MlU3JOi4viyWwRu/L2+C u50xLPvsNEVbWot1lKc75AvkNCcJCtowBhIl8x4HKN+ilKWv8A3go2jvHFSqTIOLCbJmV1DCO5F RTJIpj0JWZPUkl6xqHfiWzgFvJJTmV/So6PtCwG/dbYDI5ngKGDvuEB0RCu4aOfMpiQuiyRs18f SN4t3ERyRKbWzjXimIPHFupQdwDQVNb/5niYY7HikDSTPJCaZTf0B+qjNaNhchJg+AbXBtp+LWN P1a8VilssiEkbeQ8/uw8IMefrUeaSKo9DQyKqMeWYyGE7jWqGUaTQxkTCPSmW+oxhEOq+xpjKac +RjQa8xpetUONC0UCwaBtDLZywDwGF1t7Itd05IGfD+dCnNPAW/gg0w+Wz2AIRM2lKYSNKwYNJx MloyP4fy9QyiMYw== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding This is similar to bitmap_allocate_region() but allows allocation of non-power of two pages/bits. While at it, reimplement bitmap_allocate_region() in terms of this new helper to remove a sliver of code duplication. Signed-off-by: Thierry Reding --- include/linux/bitmap.h | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 7df1573a409c..c2ab02985b5f 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -716,10 +716,10 @@ void bitmap_release_region(unsigned long *bitmap, uns= igned int pos, int order) } =20 /** - * bitmap_allocate_region - allocate bitmap region + * bitmap_allocate - allocate bitmap region * @bitmap: array of unsigned longs corresponding to the bitmap * @pos: beginning of bit region to allocate - * @order: region size (log base 2 of number of bits) to allocate + * @len: number of bits to allocate * * Allocate (set bits in) a specified region of a bitmap. * @@ -727,16 +727,31 @@ void bitmap_release_region(unsigned long *bitmap, uns= igned int pos, int order) * free (not all bits were zero). */ static __always_inline -int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int or= der) +int bitmap_allocate(unsigned long *bitmap, unsigned int pos, unsigned int = len) { - unsigned int len =3D BIT(order); - if (find_next_bit(bitmap, pos + len, pos) < pos + len) return -EBUSY; bitmap_set(bitmap, pos, len); return 0; } =20 +/** + * bitmap_allocate_region - allocate bitmap region + * @bitmap: array of unsigned longs corresponding to the bitmap + * @pos: beginning of bit region to allocate + * @order: region size (log base 2 of number of bits) to allocate + * + * Allocate (set bits in) a specified region of a bitmap. + * + * Returns: 0 on success, or %-EBUSY if specified region wasn't + * free (not all bits were zero). + */ +static __always_inline +int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int or= der) +{ + return bitmap_allocate(bitmap, pos, BIT(order)); +} + /** * bitmap_find_free_region - find a contiguous aligned mem region * @bitmap: array of unsigned longs corresponding to the bitmap --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B5CC346F4BB; Fri, 4 Sep 2026 10:45:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518737; cv=none; b=qdBKee5JvVZ2koVYn7Jl6IR93qvoan7MkMoADMLmgdK1TiJO3Q9Q1wodxnjRaqr0vmDFaU+vatyluGzH7/ejz/DA1qdzTeYoxhiOrCR8Y87qhP1zE5wiLIlmyCTjt/HUP8ljQubMxBBqUWHDfGWT1xEYFjqtvWDNMPFBZvnotx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518737; c=relaxed/simple; bh=A2htvo3cu/cGMuF45yPyefAhCfBrP0w5q4RQKQbR6vM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ye1udRtLOv96fc2AJYwU1aLCaCgekHvUt3eYg2KOMSdUZEgUWOKfYTpfIf+1gWeMp3Y9EA0jTl+i3jQ/jTAcD0G5p9qFJjLMdEKvJB86MGSx1WYKTjCLJ6bOOqs/H+q3cuFs5X19JinlxGYddu77FSbFJ1kbYeOb+cahBf32vB4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SP5bfIG8; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SP5bfIG8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 836DA1F00A3E; Fri, 4 Sep 2026 10:45:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518735; bh=kC3CPrr3PAY7P/aChmlLF9PhF6B4gfio4q7V2fdfYsc=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=SP5bfIG8u6MRQNywxnJUOh6EF6Ed7XpEvhzfAE1agnxOQUrgZenSUyYiBRrnUlZbM jeabei0jiWAmeF7c3Gn9saxPOUP7pZ5iqkH7ZmyYIEpQJjpbHja2MhP5Dpj/oGo/TQ Rb6q1b6xAq4lsrzhFgI/p3pwuefX/K175ft/Eztv+5FOn1sLQD23M1mmOYKhL1J0jj wMDfTyZ1rBdn4BFr6lAPrAzM5Blm6BxHxXkx4Hy0m+wanRE30eEj+UBbsUUL/taWGT gZBJEclpTDXns6tyVt2TiBet4agLrRtaQneYUTIzCZmGqmQL7OE/IXk0IixV1Pb34i Tyhus9nqR5Cww== From: Thierry Reding Date: Fri, 04 Sep 2026 12:44:57 +0200 Subject: [PATCH v6 06/12] of: Export of_node_to_nid() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-6-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=531; i=treding@nvidia.com; h=from:subject:message-id; bh=XVM1jxgviVEtDinHenIJ2Kw8sOhFectSaf+1DVtDVAo=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE6BHc3U4JQE7eU7NgsnGt5czLULWf+jkgKq OsJ4G0rIHSJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOgAKCRDdI6zXfz6z oZMoD/9xguhdwCrD8iOdtsVTh6dfItXp4r9Hbp1ZfBZm4OHIQI81YR3MZrSb2bzObPQJoXC4dRy ZIYhPvqOvoILsZRMwWhqyyJXQRnmIDPlqWdvNybGETu1FibVSDZxMnudxPMRKtEBRG2es5Vt/// s7wdiWgHfZzbpnobQGL0B1q6ZLLcxoK2kkAKKKzEbMnrPameUnFH66Yi8tyqRG1XlNz6JEwt8z0 NXNjwPRMwYMiqVSATbrGIa51QKepW1D0NeQtsAXGk/WDjMaXbdly0QpUt7RANZcBjUtNvA0Ko2N pe5d7gaALs7yKIUTgy/AC0WmqCkC6s2jaYTcZ+/cHl7P3+tsvIox+SfFKW5/bGSZOwAZ9hLDu4w d68AplnyPNl8NsOCcwDct6dphMpBzWFuOO2z44y6Ee7CJrcOMqaT8eRU3SUhQttDVB/pCVAcU3y rHmnZZgQwAnjDHNl+Sk8APIDNYxsv/m+KNLs2gPv2ezugy6xYbkHwnLf2j+fnaP6gTlKewgZA2Z 4d8idRFEPqFLEYXsKG3rVDE+bywdW/uY33dz1euxG81qYT9tZKrGxRvCtWG/oQ9mWoogNlUTqvt OY8mocLptFLj7WMCtzyy7tPXOeq7oT4GS2flTTf+lc2cgg3pX7Rpg1QesoC5/nD7fEZFe3GyOGL 6CeFVyhYcyTff3g== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding Drivers buildable as a module may want to use this, so export it. Signed-off-by: Thierry Reding --- drivers/of/of_numa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index 230d5f628c1b..da2e9bd1717c 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c @@ -171,6 +171,7 @@ int of_node_to_nid(struct device_node *device) =20 return NUMA_NO_NODE; } +EXPORT_SYMBOL(of_node_to_nid); =20 int __init of_numa_init(void) { --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0221D46D579; Fri, 4 Sep 2026 10:45:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518741; cv=none; b=I+rgngM0CDH680/1/nYHCheuwOkcFgu2a1JXymbez7XoCzBB7mkbBIOZ4gz2I5vF3ohpU3Lht2iTFsKzB8vo7K+P3EUZA1+e7jpithdyl14V/efoMgefZDbIFGpSgTN6f2nCV7eF8nE9ry3HpHdaaXBKw9OtZS5EZp+wIOwMUM0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518741; c=relaxed/simple; bh=HmDZm2lDx5I7ds4AUc/GlLZK1YHhHb4aHjuyJlBvC1Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iNd9Qov89iU5N36NTEB/yrSJThXnBiGV5pn2KhaZljvcXmzDe4ZKDid5t7PKlz3MMPtjiW+EJZ3qHGl++HPTIM2PLCxeuTAcLLpLWjXr1FCxkyyvH9wRluLeE2tqYecrROACknPCTs+xEtzlFDcrfKay6zgEA+qsIcEmWpTFuPk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IPOmoLYA; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IPOmoLYA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 51F3B1F00ACA; Fri, 4 Sep 2026 10:45:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518738; bh=5vNNvzKdHsOvV9OyhJTU/lOueTFevJJO4XmoYOQ+eTg=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=IPOmoLYAsIj3FJJW1IqX+/l6C4WsfKJvtAb4ioQHEWQimGrkjT3/UDN9eS/XSsazP QnpcT5dLz251vFGtth6XVSzuO3S8HHwoQkmScXOo/yrpOo18RNAPMpKZ6t8TjfChEO 927FWdOsqLjOJJV7pYWYy7x0tqhx03vfSemHrrCMDtsQiLu1MtFPi8e2JmOUclWhH8 5yXFANh7s+CEDhUPH0kgrTyLpa0aegEyCiQdE2X1tJ4EWEqcUge3+dH+ARHfjM4UTS k/ongUpu3rtV2/rM+1xv7P7fnLD517TXmoy8XL9bFVoXS8BzDjr0AWoKXwsvvKqwNt hJqFW0ow9F6OA== From: Thierry Reding Date: Fri, 04 Sep 2026 12:44:58 +0200 Subject: [PATCH v6 07/12] mm/cma: Introduce cma_alloc_at() API Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-7-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=11699; i=treding@nvidia.com; h=from:subject:message-id; bh=g3+Web5AipUed1NoZ7SwnVTMq8b6YiuYb269+8LMDXw=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE6zic+A28EOvvjRlHYgr0bkc1hg/XFjhwuR 58+1xN4tUeJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOgAKCRDdI6zXfz6z oUbcD/4+HDzO44GDVKd8Xfif1Nth0zgLdLG9tJ7rK14JFcNlVH+y/LTxAjade3W5hl3uKhaIOdc qso8AWeMpzAse9Scgy+/AWG39dtQ7GclINBLTE7jg9HkAdTAPePfeJC2jvNMzbPfGfVgflwzDgo /pTjUcDN257WOqkZtx1dbh7NtC5Llej64onoQXse5ucTIuylefWWrK/6d7peF7ZMP3vNFqSSeT2 FjgcZDBJA9o6KeTc/TlFcjGR8+stmDjOgt2OD/Bm5izczhwyPtsSqbiDVSgM/G17lSmGv7ZeduH anjq5SF4geSTVLaiE0++gi8pc9cuvUzc4TyJzgD/kc1ybjFRmpdhfkkPvlGOeY1gzvQVGea6NT3 7vGw7wuAVZM80T4JJJJTrluFCrfYeCv7g9Y/pI9MEeuPauS3FlwpBYnUTOGk5nz/QQKQZo0fylm r+UIv3vnK5jQ7ozx0XX+f06q8acg5ei1qSKrtGRL/4LQ6lisPOPInpMC83qANdxwz3/Mk9s/kSa kJ356dsAQqFG05EOyQOyritpq+mdv0zTcR3lDfyyRx+URbNXUPiVQddq2lcUWoJRiOi4p3bewF5 x7qpq9Z8tE2ljsepTBYvxNJUreNddRCXHRrymarty6Jb6t2ZaHQbHyZhyM018vOFFHQz/Ck8fuV TPBoSmPG44LYgtA== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding This API can be used to allocate a number of CMA pages starting at a fixed offset. This is useful, for example, if the CMA area is used as backing storage for a nested allocator that has stricter requirements than CMA itself. In order to reuse most of the existing code, the cma_range_alloc() function is enhanced to take as inputs a range of pages to look for a free region. If this range encompasses the entire CMA range, the behavior is as before, but the range can also be specified to match the offset and size passed in from cma_alloc_at(), in which case that is the range that will be allocated (or allocation will fail if the range is not available). Suggested-by: Marek Szyprowski Signed-off-by: Thierry Reding Acked-by: Marek Szyprowski --- Changes in v6: - refactor cma_range_alloc() so it can be reused for _at() code paths --- include/linux/cma.h | 4 +++ include/trace/events/cma.h | 77 ++++++++++++++++++++++++++++++++++++++-- mm/cma.c | 88 +++++++++++++++++++++++++++++++++++-------= ---- 3 files changed, 146 insertions(+), 23 deletions(-) diff --git a/include/linux/cma.h b/include/linux/cma.h index 8555d38a97b1..844404459a42 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h @@ -49,11 +49,15 @@ extern int cma_init_reserved_mem(phys_addr_t base, phys= _addr_t size, struct cma **res_cma); extern struct page *cma_alloc(struct cma *cma, unsigned long count, unsign= ed int align, bool no_warn); +extern struct page *cma_alloc_at(struct cma *cma, unsigned long offset, + unsigned long count, bool no_warn); extern bool cma_release(struct cma *cma, const struct page *pages, unsigne= d long count); =20 struct page *cma_alloc_frozen(struct cma *cma, unsigned long count, unsigned int align, bool no_warn); struct page *cma_alloc_frozen_compound(struct cma *cma, unsigned int order= ); +struct page *cma_alloc_at_frozen(struct cma *cma, unsigned long offset, + unsigned long count, bool no_warn); bool cma_release_frozen(struct cma *cma, const struct page *pages, unsigned long count); =20 diff --git a/include/trace/events/cma.h b/include/trace/events/cma.h index 37195edf2498..4e0ab63e303f 100644 --- a/include/trace/events/cma.h +++ b/include/trace/events/cma.h @@ -38,13 +38,17 @@ TRACE_EVENT(cma_release, =20 TRACE_EVENT(cma_alloc_start, =20 - TP_PROTO(const char *name, unsigned long request_count, unsigned long ava= ilable_count, + TP_PROTO(const char *name, unsigned long start, unsigned long end, + unsigned long request_count, unsigned long available_count, unsigned long total_count, unsigned int align), =20 - TP_ARGS(name, request_count, available_count, total_count, align), + TP_ARGS(name, start, end, request_count, available_count, total_count, + align), =20 TP_STRUCT__entry( __string(name, name) + __field(unsigned long, start) + __field(unsigned long, end) __field(unsigned long, request_count) __field(unsigned long, available_count) __field(unsigned long, total_count) @@ -53,14 +57,18 @@ TRACE_EVENT(cma_alloc_start, =20 TP_fast_assign( __assign_str(name); + __entry->start =3D start; + __entry->end =3D end; __entry->request_count =3D request_count; __entry->available_count =3D available_count; __entry->total_count =3D total_count; __entry->align =3D align; ), =20 - TP_printk("name=3D%s request_count=3D%lu available_count=3D%lu total_coun= t=3D%lu align=3D%u", + TP_printk("name=3D%s start=3D%lu end=3D%lu request_count=3D%lu available_= count=3D%lu total_count=3D%lu align=3D%u", __get_str(name), + __entry->start, + __entry->end, __entry->request_count, __entry->available_count, __entry->total_count, @@ -132,6 +140,69 @@ TRACE_EVENT(cma_alloc_busy_retry, __entry->align) ); =20 +TRACE_EVENT(cma_alloc_at_start, + + TP_PROTO(const char *name, unsigned long pfn, + unsigned long request_count, unsigned long available_count, + unsigned long total_count), + + TP_ARGS(name, pfn, request_count, available_count, total_count), + + TP_STRUCT__entry( + __string(name, name) + __field(unsigned long, pfn) + __field(unsigned long, request_count) + __field(unsigned long, available_count) + __field(unsigned long, total_count) + ), + + TP_fast_assign( + __assign_str(name); + __entry->pfn =3D pfn; + __entry->request_count =3D request_count; + __entry->available_count =3D available_count; + __entry->total_count =3D total_count; + ), + + TP_printk("name=3D%s pfn=3D%lx, request_count=3D%lu available_count=3D%lu= total_count=3D%lu", + __get_str(name), + __entry->pfn, + __entry->request_count, + __entry->available_count, + __entry->total_count) +); + +TRACE_EVENT(cma_alloc_at_finish, + + TP_PROTO(const char *name, unsigned long pfn, const struct page *page, + unsigned long count, int errorno), + + TP_ARGS(name, pfn, page, count, errorno), + + TP_STRUCT__entry( + __string(name, name) + __field(unsigned long, pfn) + __field(const struct page *, page) + __field(unsigned long, count) + __field(int, errorno) + ), + + TP_fast_assign( + __assign_str(name); + __entry->pfn =3D pfn; + __entry->page =3D page; + __entry->count =3D count; + __entry->errorno =3D errorno; + ), + + TP_printk("name=3D%s pfn=3D0x%lx page=3D%p count=3D%lu errorno=3D%d", + __get_str(name), + __entry->pfn, + __entry->page, + __entry->count, + __entry->errorno) +); + #endif /* _TRACE_CMA_H */ =20 /* This part must be outside protection */ diff --git a/mm/cma.c b/mm/cma.c index a10ea37a261d..f92d3a188209 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -783,25 +783,32 @@ static void cma_debug_show_areas(struct cma *cma) spin_unlock_irq(&cma->lock); } =20 +/* + * Searches the CMA memrange, from @start to @end, for a free region of + * @count bits. If @end is less or equal to @start, will search the entire + * memrange. + */ static int cma_range_alloc(struct cma *cma, struct cma_memrange *cmr, - unsigned long count, unsigned int align, - struct page **pagep, gfp_t gfp) + unsigned long start, unsigned long end, + unsigned long count, unsigned int align, + struct page **pagep, gfp_t gfp) { unsigned long bitmap_maxno, bitmap_no, bitmap_count; - unsigned long start, pfn, mask, offset; - int ret =3D -EBUSY; + unsigned long pfn, mask, offset; struct page *page =3D NULL; + int ret =3D -EBUSY; =20 mask =3D cma_bitmap_aligned_mask(cma, align); offset =3D cma_bitmap_aligned_offset(cma, cmr, align); - bitmap_maxno =3D cma_bitmap_maxno(cma, cmr); + bitmap_maxno =3D (end > start) ? end : cma_bitmap_maxno(cma, cmr); bitmap_count =3D cma_bitmap_pages_to_bits(cma, count); =20 if (bitmap_count > bitmap_maxno) goto out; =20 - for (start =3D 0; ; start =3D bitmap_no + mask + 1) { + while (true) { spin_lock_irq(&cma->lock); + /* * If the request is larger than the available number * of pages, stop right away. @@ -810,6 +817,7 @@ static int cma_range_alloc(struct cma *cma, struct cma_= memrange *cmr, spin_unlock_irq(&cma->lock); break; } + bitmap_no =3D bitmap_find_next_zero_area_off(cmr->bitmap, bitmap_maxno, start, bitmap_count, mask, offset); @@ -835,10 +843,11 @@ static int cma_range_alloc(struct cma *cma, struct cm= a_memrange *cmr, =20 bitmap_set(cmr->bitmap, bitmap_no, bitmap_count); cma->available_count -=3D count; + /* - * It's safe to drop the lock here. We've marked this region for - * our exclusive use. If the migration fails we will take the - * lock again and unmark it. + * It's safe to drop the lock here. We've marked this region + * for our exclusive use. If the migration fails we will take + * the lock again and unmark it. */ spin_unlock_irq(&cma->lock); =20 @@ -856,37 +865,45 @@ static int cma_range_alloc(struct cma *cma, struct cm= a_memrange *cmr, __func__, pfn, page); =20 trace_cma_alloc_busy_retry(cma->name, pfn, page, count, align); + start =3D bitmap_no + mask + 1; } + out: if (!ret) *pagep =3D page; + return ret; } =20 -static struct page *__cma_alloc_frozen(struct cma *cma, - unsigned long count, unsigned int align, gfp_t gfp) +static struct page *__cma_alloc_frozen(struct cma *cma, unsigned long star= t, + unsigned long end, unsigned long count, + unsigned int align, gfp_t gfp) { struct page *page =3D NULL; int ret =3D -ENOMEM, r; unsigned long i; - const char *name =3D cma ? cma->name : NULL; + + /* cma_alloc_at() and friends will only work with single-range CMA */ + if (WARN_ON_ONCE(start > 0 && cma->nranges !=3D 1)) + return page; =20 if (!cma || !cma->count) return page; =20 - pr_debug("%s(cma %p, name: %s, count %lu, align %d)\n", __func__, - (void *)cma, cma->name, count, align); + pr_debug("%s(cma %p, name: %s, start %lu, end %lu, count %lu, align %d)\n= ", + __func__, (void *)cma, cma->name, start, end, count, align); =20 if (!count) return page; =20 - trace_cma_alloc_start(name, count, cma->available_count, cma->count, alig= n); + trace_cma_alloc_start(cma->name, start, end, count, + cma->available_count, cma->count, align); =20 for (r =3D 0; r < cma->nranges; r++) { page =3D NULL; =20 - ret =3D cma_range_alloc(cma, &cma->ranges[r], count, align, - &page, gfp); + ret =3D cma_range_alloc(cma, &cma->ranges[r], start, end, + count, align, &page, gfp); if (ret !=3D -EBUSY || page) break; } @@ -908,7 +925,7 @@ static struct page *__cma_alloc_frozen(struct cma *cma, } =20 pr_debug("%s(): returned %p\n", __func__, page); - trace_cma_alloc_finish(name, page ? page_to_pfn(page) : 0, + trace_cma_alloc_finish(cma->name, page ? page_to_pfn(page) : 0, page, count, align, ret); if (page) { count_vm_event(CMA_ALLOC_SUCCESS); @@ -926,14 +943,22 @@ struct page *cma_alloc_frozen(struct cma *cma, unsign= ed long count, { gfp_t gfp =3D GFP_KERNEL | (no_warn ? __GFP_NOWARN : 0); =20 - return __cma_alloc_frozen(cma, count, align, gfp); + return __cma_alloc_frozen(cma, 0, 0, count, align, gfp); } =20 struct page *cma_alloc_frozen_compound(struct cma *cma, unsigned int order) { gfp_t gfp =3D GFP_KERNEL | __GFP_COMP | __GFP_NOWARN; =20 - return __cma_alloc_frozen(cma, 1 << order, order, gfp); + return __cma_alloc_frozen(cma, 0, 0, 1 << order, order, gfp); +} + +struct page *cma_alloc_at_frozen(struct cma *cma, unsigned long offset, + unsigned long count, bool no_warn) +{ + gfp_t gfp =3D GFP_KERNEL | (no_warn ? __GFP_NOWARN : 0); + + return __cma_alloc_frozen(cma, offset, offset + count, count, 0, gfp); } =20 /** @@ -959,6 +984,29 @@ struct page *cma_alloc(struct cma *cma, unsigned long = count, } EXPORT_SYMBOL_GPL(cma_alloc); =20 +/** + * cma_alloc_at() - allocate pages from contiguous area at fixed offset + * @cma: Contiguous memory region for which the allocation is performe= d. + * @offset: Index of the first page to allocate. + * @count: Requested number of pages (in PAGE_SIZE order). + * @no_warn: Avoid printing message about failed allocation. + * + * This function allocates a part of the contiguous memory on a specific + * contiguous memory area. + */ +struct page *cma_alloc_at(struct cma *cma, unsigned long offset, + unsigned long count, bool no_warn) +{ + struct page *page; + + page =3D cma_alloc_at_frozen(cma, offset, count, no_warn); + if (page) + set_pages_refcounted(page, count); + + return page; +} +EXPORT_SYMBOL_GPL(cma_alloc_at); + static struct cma_memrange *find_cma_memrange(struct cma *cma, const struct page *pages, unsigned long count) { --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4383547DD72; Fri, 4 Sep 2026 10:45:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518743; cv=none; b=mzTY2cBA4HWiudfxQtdxbkg5T74fScGzcqb+elYCbJXYZ+lbqfHKhDj8Y6zx7hsQkZgxNpUuTosLWTObvhxHWbczHAd9Wb4XuHo3UlSyKCrOBqyIrjvYarDRG7ysiEtBhPmMP9lZiVXZZG56QYEcVg20rzvv0+KOcVslYxx8S58= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518743; c=relaxed/simple; bh=jgi1JGrUvwRr0PDo4wjIkRwRy5XaraZLoXWlTBSaki0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=B8I5sy97f/0YE2jmD6lBaXfICzYdn9L/ydUNc5Q+BgSmRSrkjYdNzSSAlRrnd2KPcEGYbwYwmj1s2NzCBVHK5/E7CU7MjYaQNBw8+A19BXMyhEWva+Wqylb9US0qzjDDILXguX5UMsUHRqZO4SQlEI0auSY3Y8SyrouJADfErgw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MJ07LRTm; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MJ07LRTm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 16AF31F00A3D; Fri, 4 Sep 2026 10:45:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518740; bh=URDYUrqbvoFrys39J8mEIELRy5W+29S6/Co77OGahWQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=MJ07LRTmfws8dXur0isr7LB/HULUxkMqgSEAyRbIOmKqouVwpQ60B2f+U8uXM5gcN 0e4rmcdkfnZ1f/cgp+89IGLqQeroCxFS7+p8ooIVtBQV/gxf7yM0MorJ/2W3l60ERD SqPP8/rtWDfUGWUZdJEkAnHQEBxvRcWfTbEdpPj1xkmjAEcmQ84sXaM03P15lX2dIN 5VIPwRCT2W5u7oHyh+uqVSCN8zxCw71ovjataEu9cUYRGZv4qUUVuiVPd8YliRaimJ 8n32Ozp6KtRjSV9ii433WdtqaxYPsEu3Oguidc0Wr4taDVXHAvxPHnJRkbEh+VmmwD jWI3To2QfeVRQ== From: Thierry Reding Date: Fri, 04 Sep 2026 12:44:59 +0200 Subject: [PATCH v6 08/12] dma-buf: heaps: Add debugfs support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-8-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3268; i=treding@nvidia.com; h=from:subject:message-id; bh=PTbCupvjHWmMcXwEcqCBr5NgDg7Tooca+dUOmGKhZ1w=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE6C4dwHTnCbC5FbKmwaT00Do0hU8YNS/+jY a0Lv2wvQJmJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOgAKCRDdI6zXfz6z od3iEACHrxrMF5hDeTgSv/upZk6DbDhcOknfUoMDoE7ao2NckqEMBYrL7W4jHqK4OEK7Zz+Dy56 l74sJCpjbOE+EkqXP/sHP7Dcowfz3/rUTKNLWMrH4GjEGlu7zCzUfqe9PlPOhT/f5oe6tVL3Q+l 4fnwRm1olqNLtZKAaffoZQDNLjIFBhQaOkiSocS72I+SMAGt3LOPJmfGNW8bruRDtRjbPbhwrFM WqgBdknbnk87TQzuuv/Zudx5uvzXPtUuPjijyUjN+8gaRNGNhWwHmP99qSG5d/B5fdFRKj+I5QI dTZRvzzxb/PUNF880+qE3wRTxd/6djnnZtAnFfPGRiDbcN12cApJdAYSaVOm5kRCMx0A6V11rQR uDMvgB/adcG3P3T5x6/CVrw+KXHOR/VCGHa16YGbjq/ajwJsGyl6NAVG9vtaG5LfS6pcjlH6HRh m6VudFk+pfDpMD0nWlqiHyk1i1i3f3N17D3B0rtg2YGGRqWhikWK9gci3YyCRCr21+wBfRL9zMv qlj3Zcw1JoK3hGRi76bXm+p0EULU2PMdnR+MA7z83OdT7phjtBsH8aJTKXrKZIGuBDwClD5mp2h 9YZqhM/c6XIMG0xogYOIiMIxQZuqifr6ZvL2iC3/JdsepRVwO+hgJzwNBTj6zC5KHqX60d1rizd XXb+4oFnVut6Zsw== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding Add a callback to struct dma_heap_ops that heap providers can implement to show information about the state of the heap in debugfs. A top-level directory named "dma_heap" is created in debugfs and individual files will be named after the heaps. Reviewed-by: Maxime Ripard Signed-off-by: Thierry Reding --- Changes in v5: - fix failure handling during debugfs root directory creation - add more cleanup to the newly introduced dma_heap_exit() --- drivers/dma-buf/dma-heap.c | 52 ++++++++++++++++++++++++++++++++++++++++++= ++++ include/linux/dma-heap.h | 2 ++ 2 files changed, 54 insertions(+) diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index 8a6c2b6e0cc6..65c80dac6500 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -7,6 +7,7 @@ */ =20 #include +#include #include #include #include @@ -225,6 +226,40 @@ const char *dma_heap_get_name(struct dma_heap *heap) } EXPORT_SYMBOL_NS_GPL(dma_heap_get_name, "DMA_BUF_HEAP"); =20 +#ifdef CONFIG_DEBUG_FS +static int dma_heap_debug_show(struct seq_file *s, void *unused) +{ + struct dma_heap *heap =3D s->private; + int err =3D 0; + + if (heap->ops && heap->ops->show) + err =3D heap->ops->show(s, heap); + + return err; +} +DEFINE_SHOW_ATTRIBUTE(dma_heap_debug); + +static struct dentry *dma_heap_debugfs_dir; + +static void dma_heap_init_debugfs(void) +{ + dma_heap_debugfs_dir =3D debugfs_create_dir("dma_heap", NULL); +} + +static void dma_heap_exit_debugfs(void) +{ + debugfs_remove_recursive(dma_heap_debugfs_dir); +} +#else +static void dma_heap_init_debugfs(void) +{ +} + +static void dma_heap_exit_debugfs(void) +{ +} +#endif + /** * dma_heap_add - adds a heap to dmabuf heaps * @exp_info: information needed to register this heap @@ -299,6 +334,13 @@ struct dma_heap *dma_heap_add(const struct dma_heap_ex= port_info *exp_info) =20 /* Add heap to the list */ list_add(&heap->list, &heap_list); + +#ifdef CONFIG_DEBUG_FS + if (heap->ops && heap->ops->show) + debugfs_create_file(heap->name, 0444, dma_heap_debugfs_dir, + heap, &dma_heap_debug_fops); +#endif + mutex_unlock(&heap_list_lock); =20 return heap; @@ -335,6 +377,16 @@ static int dma_heap_init(void) } dma_heap_class->devnode =3D dma_heap_devnode; =20 + dma_heap_init_debugfs(); + return 0; } subsys_initcall(dma_heap_init); + +static void __exit dma_heap_exit(void) +{ + dma_heap_exit_debugfs(); + class_destroy(dma_heap_class); + unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS); +} +__exitcall(dma_heap_exit); diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h index 648328a64b27..1c9bed1f4dde 100644 --- a/include/linux/dma-heap.h +++ b/include/linux/dma-heap.h @@ -12,6 +12,7 @@ #include =20 struct dma_heap; +struct seq_file; =20 /** * struct dma_heap_ops - ops to operate on a given heap @@ -24,6 +25,7 @@ struct dma_heap_ops { unsigned long len, u32 fd_flags, u64 heap_flags); + int (*show)(struct seq_file *s, struct dma_heap *heap); }; =20 /** --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 773A448094F; Fri, 4 Sep 2026 10:45:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518749; cv=none; b=KoQVulTqeixTuL/2KqBkJDYbdOqVviD/vbI70EA9EyVyS5RCO4AqOnR/LF0CRmxXxV1g3QDX+SE8FPyoJbV0RpXqHqvU3u8MMRpXjT5wumvFoVBRFjtuebWtwFO7icAavsyeLVMYlC/cBHJg+zyUlMbI2Wamzp/JVNDzZgRNzwY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518749; c=relaxed/simple; bh=4UQGsKse/1XBGbINJ3ESIk5UgeXQqJVDZzbrPp1+deA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j97yF5PxqcJpnco+bXqTQMkK+G7buNgdhKUH9A/5iIdrLAydTCPmbiR6SfTZ2Z3JTrv063C0QLYipsgCoANju3jFG2+Zj3xtJnhw7r3d+F/MdXqSXR8cLjC9+ZYfVRc7ue9lDw+N/f0+PUg29jed1OzG44B0hHUIJW4ztMaBxwU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DjYLlOOR; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DjYLlOOR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D4E031F00A3F; Fri, 4 Sep 2026 10:45:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518743; bh=W6722AL723dTuRkbTw9SUzwXfCeSFvC8MFbz4kro58I=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=DjYLlOORHXEZyuvETbwNAZlzHsltEB0E0/EjTVoqKYboy0sC3AZx0Z9hQhrk1eYAp u2KNTNAhKdtXZjnygmobaUTUXVmxDLuc3WucWrEKvIibqt4c3vH1ZNe6H4r8ArWT0O zy6QHY3diu4qLN6E3cie9dC+WEQ3MBWSwiMBtPFvPqaf63TFxjrDcEbgQWnh08PBFh rRxdG9LUTACzbPvA0Leqo2MBphIA2STnEYYUNvRHb3h6xfYsyAn8AI/0U6xXQ/7/3/ R0cmfUfd0nf/LzL4VIEZcwunWBCKgJCiy1gZajDZvzbL/iZQJuFn+vi8nvBYrRFaHK YS+kHCxXgdQGw== From: Thierry Reding Date: Fri, 04 Sep 2026 12:45:00 +0200 Subject: [PATCH v6 09/12] dma-buf: heaps: Add support for Tegra VPR Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-9-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=43445; i=treding@nvidia.com; h=from:subject:message-id; bh=ynUqNDTHBxqZaJRROW/jrpxxVutbil/TJP/xhH6ufvc=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE7CWSkt7JwLLhGoopsId2jWiVLEa9G3XMF5 QDKVWEaTwuJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOwAKCRDdI6zXfz6z oSbHEACTbt07quMSZ6mk7p9sokKQDXAOFNTY2XgsHUNRibWp82NGsiwzZHl/aEkzmdRPYHeLzJU mNvdZn54nplMPAxYKQkXAWQGXaoytvDlm7kVr8XxZC+ABLHWl24aVaggaNaROmyTVNqhdxtCawA zt96AYR4LDWG453K2gvxQpuvcrRuHz3nfhsKiSMoLSINfAasm44+jPc0jqCYoaMvouIQnqyA+yH UWSV4AYVCmX9jHleGXYZqbv8b/gg4e2LKKoWNISH6axwNQAs8MFhS9Cz84ILkAFO83WCRV5sEfP X295Duz2ZaqqY7DCCmojV9ntNA3Tc+jwguBgMthJDhinppgAPvmWrygydkuweMPD62HZzFGMAlF ghmEuEk1/c8Ap4/RGsNApzkHLAra5vBtnfUALnRaXr5xypuKYMKgg0SoBNoqZJ2/ojb/FfHxdt1 aj7gk0cs0xxI+LYednEChrzyMKNSGekPoUQcpkIxgMYooD52AQu77v3jOanEnb8ADUoySjKHSlG WGXXThhEd4cCLkuKpPjKiwEpBYkWuKQ/ZVMHSwouV+PH83FfRChAjvmK+8zPchGL/xuoqG9zdS4 +gMDv5cGwD0q8F3qlkpnskhIdak3MnEQ2HWQAk1PAFW1mOWhz6TIu7b0iUZE27k0wpF7+lmfGnY ORusTDsXl7CzdMw== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding NVIDIA Tegra SoCs commonly define a Video-Protection-Region, which is a region of memory dedicated to content-protected video decode and playback. This memory cannot be accessed by the CPU and only certain hardware devices have access to it. Expose the VPR as a DMA heap so that applications and drivers can allocate buffers from this region for use-cases that require this kind of protected memory. VPR has a few very critical peculiarities. First, it must be a single contiguous region of memory (there is a single pair of registers that set the base address and size of the region), which is configured by calling back into the secure monitor. The memory region also needs to quite large for some use-cases because it needs to fit multiple video frames (8K video should be supported), so VPR sizes of ~2 GiB are expected. However, some devices cannot afford to reserve this amount of memory for a particular use-case, and therefore the VPR must be resizable. Unfortunately, resizing the VPR is slightly tricky because the GPU found on Tegra SoCs must be in reset during the VPR resize operation. This is currently implemented by freezing all userspace processes and calling invoking the GPU's freeze() implementation, resizing and the thawing the GPU and userspace processes. This is quite heavy-handed, so eventually it might be better to implement thawing/freezing in the GPU driver in such a way that they block accesses to the GPU so that the VPR resize operation can happen without suspending all userspace. In order to balance the memory usage versus the amount of resizing that needs to happen, the VPR is divided into multiple chunks. Each chunk is implemented as a section of the CMA area that is completely allocated on first use to guarantee the contiguity of the VPR. Once all buffers from a chunk have been freed, the subsection is freed and the memory returned to the system. The Tegra VPR driver is split into two pieces: one tiny part of the driver is always built-in and sets up the CMA area during early boot, whereas the second, larger, part provides the DMA heap implementation and can be built as a module. Note that tearing down VPR is tricky and usually not necessary, so it can currently not be unloaded. Signed-off-by: Thierry Reding --- Changes in v6: - split code into a small core and the main chunk so the latter can be built as a module Changes in v5: - use newly introduced cma_alloc_at() and work with a single CMA area - setup CMA early and initialize VPR later during boot - remove some unused variables - use kalloc_objs() Changes in v4: - address Sashiko and checkpatch comments - fully remove from linear map while chunks are allocated - improve error handling - remove freezer support Changes in v3: - use set_memory_device() and set_memory_normal() helpers - use kzalloc_obj() instead of kzalloc() with sizeof() Changes in v2: - cluster allocations to reduce the number of resize operations - support cross-chunk allocation --- drivers/dma-buf/heaps/Kconfig | 12 + drivers/dma-buf/heaps/Makefile | 10 + drivers/dma-buf/heaps/tegra-vpr-init.c | 133 ++++ drivers/dma-buf/heaps/tegra-vpr.c | 1210 ++++++++++++++++++++++++++++= ++++ drivers/dma-buf/heaps/tegra-vpr.h | 73 ++ include/trace/events/tegra_vpr.h | 57 ++ 6 files changed, 1495 insertions(+) diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig index bb729e91545c..28d2c0800fb5 100644 --- a/drivers/dma-buf/heaps/Kconfig +++ b/drivers/dma-buf/heaps/Kconfig @@ -20,3 +20,15 @@ config DMABUF_HEAPS_CMA Choose this option to enable dma-buf CMA heap. This heap is backed by the Contiguous Memory Allocator (CMA). If your system has these regions, you should say Y here. + +config DMABUF_HEAPS_TEGRA_VPR + tristate "NVIDIA Tegra Video-Protected-Region DMA-BUF Heap" + depends on DMABUF_HEAPS && DMA_CMA + help + Choose this option to enable Video-Protected-Region (VPR) support on + a range of NVIDIA Tegra devices. Access to VPR memory is limited to + a subset of hardware engines and specifically disallowed from the + CPU. The region can be fixed, in which case no linear mapping exists + for the memory, or it can be resizable on systems that want to reuse + the memory for other uses when content-protected video is not played + back. diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile index 974467791032..481fcb78f757 100644 --- a/drivers/dma-buf/heaps/Makefile +++ b/drivers/dma-buf/heaps/Makefile @@ -1,3 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) +=3D system_heap.o obj-$(CONFIG_DMABUF_HEAPS_CMA) +=3D cma_heap.o + +# +# The reserved-memory bits always need to be built-in so that the CMA +# initialization runs during early boot. The VPR driver itself can be +# built as a module. +# +ifneq ($(CONFIG_DMABUF_HEAPS_TEGRA_VPR),) +obj-y +=3D tegra-vpr-init.o +obj-$(CONFIG_DMABUF_HEAPS_TEGRA_VPR) +=3D tegra-vpr.o +endif diff --git a/drivers/dma-buf/heaps/tegra-vpr-init.c b/drivers/dma-buf/heaps= /tegra-vpr-init.c new file mode 100644 index 000000000000..65e917713c6d --- /dev/null +++ b/drivers/dma-buf/heaps/tegra-vpr-init.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DMA-BUF restricted heap exporter for NVIDIA Video-Protection-Region (VP= R) + * + * Copyright (C) 2024-2026 NVIDIA Corporation + */ + +#define pr_fmt(fmt) "tegra-vpr: " fmt + +#include "tegra-vpr.h" + +#include +#include + +static DEFINE_MUTEX(vpr_lock); +static LIST_HEAD_GUARDED(vpr_list, vpr_lock); + +static int __init tegra_vpr_node_init(unsigned long offset, + struct reserved_mem *rmem) +{ + struct cma *cma; + int err; + + if (!IS_ALIGNED(rmem->base, SZ_1M)) { + pr_err("%s: base is not aligned to 1 MiB\n", rmem->name); + return -EINVAL; + } + + if (!IS_ALIGNED(rmem->size, SZ_1M)) { + pr_err("%s: size is not aligned to 1 MiB\n", rmem->name); + return -EINVAL; + } + + err =3D cma_init_reserved_mem(rmem->base, rmem->size, 0, rmem->name, + &cma); + if (err < 0) { + pr_err("%s: failed to initialize CMA: %d\n", __func__, err); + return err; + } + + rmem->priv =3D cma; + + return 0; +} + +static struct tegra_vpr *tegra_vpr_lookup(struct cma *cma) +{ + struct tegra_vpr *vpr; + + mutex_lock(&vpr_lock); + + list_for_each_entry(vpr, &vpr_list, list) { + if (vpr->cma =3D=3D cma) { + mutex_unlock(&vpr_lock); + return vpr; + } + } + + mutex_unlock(&vpr_lock); + + return ERR_PTR(-EPROBE_DEFER); +} + +static int tegra_vpr_device_init(struct reserved_mem *rmem, struct device = *dev) +{ + const struct dev_pm_ops *pm =3D dev->driver->pm; + struct tegra_vpr_device *node; + struct cma *cma =3D rmem->priv; + struct tegra_vpr *vpr; + + vpr =3D tegra_vpr_lookup(cma); + if (IS_ERR(vpr)) + return PTR_ERR(vpr); + + if (!pm || !pm->freeze || !pm->thaw) + return -EINVAL; + + node =3D kzalloc_obj(*node, GFP_KERNEL); + if (!node) + return -ENOMEM; + + INIT_LIST_HEAD(&node->node); + node->dev =3D dev; + + mutex_lock(&vpr->lock); + list_add_tail(&node->node, &vpr->devices); + mutex_unlock(&vpr->lock); + + return 0; +} + +static void tegra_vpr_device_release(struct reserved_mem *rmem, + struct device *dev) +{ + struct tegra_vpr_device *node, *tmp; + struct cma *cma =3D rmem->priv; + struct tegra_vpr *vpr; + + vpr =3D tegra_vpr_lookup(cma); + if (IS_ERR(vpr)) { + dev_WARN(dev, "failed to find VPR for CMA '%s'\n", + cma_get_name(cma)); + return; + } + + mutex_lock(&vpr->lock); + + list_for_each_entry_safe(node, tmp, &vpr->devices, node) { + if (node->dev =3D=3D dev) { + list_del(&node->node); + kfree(node); + } + } + + mutex_unlock(&vpr->lock); +} + +static const struct reserved_mem_ops tegra_vpr_rmem_ops =3D { + .node_init =3D tegra_vpr_node_init, + .device_init =3D tegra_vpr_device_init, + .device_release =3D tegra_vpr_device_release, +}; + +RESERVEDMEM_OF_DECLARE(tegra_vpr, "nvidia,tegra-video-protection-region", + &tegra_vpr_rmem_ops); + +void tegra_vpr_add(struct tegra_vpr *vpr) +{ + mutex_lock(&vpr_lock); + list_add_tail(&vpr->list, &vpr_list); + mutex_unlock(&vpr_lock); +} +EXPORT_SYMBOL(tegra_vpr_add); diff --git a/drivers/dma-buf/heaps/tegra-vpr.c b/drivers/dma-buf/heaps/tegr= a-vpr.c new file mode 100644 index 000000000000..d8cff7e07ea0 --- /dev/null +++ b/drivers/dma-buf/heaps/tegra-vpr.c @@ -0,0 +1,1210 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DMA-BUF restricted heap exporter for NVIDIA Video-Protection-Region (VP= R) + * + * Copyright (C) 2024-2026 NVIDIA Corporation + */ + +#define pr_fmt(fmt) "tegra-vpr: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tegra-vpr.h" + +MODULE_IMPORT_NS("DMA_BUF_HEAP"); +MODULE_IMPORT_NS("DMA_BUF"); + +#define CREATE_TRACE_POINTS +#include + +#define TEGRA_VPR_MAX_CHUNKS 64 + +struct tegra_vpr_buffer { + struct list_head attachments; + struct tegra_vpr *vpr; + struct list_head list; + + /** + * @lock: Protects concurrent access to the list of attachments. + */ + struct mutex lock; + + struct page **pages; + pgoff_t num_pages; + phys_addr_t start; + phys_addr_t limit; + size_t size; + int pageno; + int order; + + DECLARE_BITMAP(chunks, TEGRA_VPR_MAX_CHUNKS); +}; + +struct tegra_vpr_attachment { + struct device *dev; + struct sg_table sgt; + struct list_head list; +}; + +#define ARM_SMCCC_TE_FUNC_PROGRAM_VPR 0x3 + +#define ARM_SMCCC_VENDOR_SIP_TE_PROGRAM_VPR_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_SIP, \ + ARM_SMCCC_TE_FUNC_PROGRAM_VPR) + +static int tegra_vpr_set(phys_addr_t base, phys_addr_t size) +{ + struct arm_smccc_res res; + + arm_smccc_smc(ARM_SMCCC_VENDOR_SIP_TE_PROGRAM_VPR_FUNC_ID, base, size, + 0, 0, 0, 0, 0, &res); + + return res.a0; +} + +static int tegra_vpr_get_extents(struct tegra_vpr *vpr, phys_addr_t *base, + phys_addr_t *size) +{ + phys_addr_t start =3D ~0, limit =3D 0; + unsigned int i; + + for (i =3D 0; i < vpr->num_chunks; i++) { + struct tegra_vpr_chunk *chunk =3D &vpr->chunks[i]; + + if (chunk->active) { + if (chunk->start < start) + start =3D chunk->start; + + if (chunk->limit > limit) + limit =3D chunk->limit; + } + } + + if (limit > start) { + *size =3D limit - start; + *base =3D start; + } else { + *base =3D *size =3D 0; + } + + return 0; +} + +static int tegra_vpr_resize(struct tegra_vpr *vpr) +{ + struct tegra_vpr_device *node; + phys_addr_t base, size; + int err, status =3D 0; + + err =3D tegra_vpr_get_extents(vpr, &base, &size); + if (err < 0) { + pr_err("%s(): failed to get VPR extents: %d\n", __func__, err); + return err; + } + + list_for_each_entry(node, &vpr->devices, node) { + err =3D pm_generic_freeze(node->dev); + if (err < 0) { + pr_err("failed to freeze %s: %d\n", + dev_name(node->dev), err); + status =3D err; + goto thaw; + } + } + + trace_tegra_vpr_set(base, size); + + err =3D tegra_vpr_set(base, size); + if (err < 0) { + pr_err("failed to secure VPR: %d\n", err); + status =3D err; + } + +thaw: + list_for_each_entry_continue_reverse(node, &vpr->devices, node) { + err =3D pm_generic_thaw(node->dev); + if (err < 0) { + pr_err("failed to thaw %s: %d\n", + dev_name(node->dev), err); + continue; + } + } + + return status; +} + +static int tegra_vpr_chunk_init(struct tegra_vpr *vpr, + struct tegra_vpr_chunk *chunk, + phys_addr_t start, size_t size, + unsigned int order, const char *name) +{ + chunk->start =3D start; + chunk->limit =3D start + size; + chunk->size =3D size; + chunk->vpr =3D vpr; + + chunk->offset =3D (start - vpr->base) >> PAGE_SHIFT; + chunk->num_pages =3D size >> PAGE_SHIFT; + chunk->num_buffers =3D 0; + + /* CMA area is not reserved yet */ + chunk->start_page =3D NULL; + chunk->virt =3D 0; + + return 0; +} + +static void tegra_vpr_chunk_free(struct tegra_vpr_chunk *chunk) +{ +} + +static inline bool tegra_vpr_chunk_is_last(const struct tegra_vpr_chunk *c= hunk) +{ + phys_addr_t limit =3D chunk->vpr->base + chunk->vpr->size; + + return chunk->limit =3D=3D limit; +} + +static inline bool tegra_vpr_chunk_is_leaf(const struct tegra_vpr_chunk *c= hunk) +{ + const struct tegra_vpr_chunk *next =3D chunk + 1; + + if (tegra_vpr_chunk_is_last(chunk)) + return true; + + return !next->active; +} + +static int tegra_vpr_chunk_alloc(struct tegra_vpr_chunk *chunk) +{ + chunk->start_page =3D cma_alloc_at(chunk->vpr->cma, chunk->offset, + chunk->num_pages, false); + if (!chunk->start_page) + return -ENOMEM; + + chunk->virt =3D (unsigned long)page_to_virt(chunk->start_page); + + return 0; +} + +static int tegra_vpr_chunk_activate(struct tegra_vpr_chunk *chunk) +{ + int err; + + trace_tegra_vpr_chunk_activate(chunk->start, chunk->limit); + + err =3D set_direct_map_invalid_noflush(chunk->start_page, + chunk->num_pages); + if (err) + return err; + + flush_tlb_kernel_range(chunk->virt, chunk->virt + chunk->size); + chunk->invalid =3D false; + chunk->active =3D true; + + return 0; +} + +static int tegra_vpr_chunk_deactivate(struct tegra_vpr_chunk *chunk) +{ + int err; + + if (!chunk->active) + return 0; + + /* do not deactivate if there are buffers left in this chunk */ + if (WARN_ON(chunk->num_buffers > 0)) + return -EBUSY; + + trace_tegra_vpr_chunk_deactivate(chunk->start, chunk->limit); + + err =3D set_direct_map_default_noflush(chunk->start_page, + chunk->num_pages); + if (err) + return err; + + flush_tlb_kernel_range(chunk->virt, chunk->virt + chunk->size); + chunk->invalid =3D false; + chunk->active =3D false; + + return 0; +} + +static void tegra_vpr_chunk_release(struct tegra_vpr_chunk *chunk) +{ + if (!WARN_ON(chunk->active || chunk->invalid)) { + cma_release(chunk->vpr->cma, chunk->start_page, + chunk->num_pages); + chunk->start_page =3D NULL; + chunk->virt =3D 0; + } +} + +static bool tegra_vpr_chunk_overlaps(struct tegra_vpr_chunk *chunk, + unsigned int start, unsigned int limit) +{ + unsigned int first =3D chunk->offset; + unsigned int last =3D chunk->offset + chunk->num_pages - 1; + + if (last < start || first >=3D limit) + return false; + + return true; +} + +static int tegra_vpr_activate_chunks(struct tegra_vpr *vpr, + struct tegra_vpr_buffer *buffer) +{ + DECLARE_BITMAP(dirty, vpr->num_chunks); + unsigned int i, bottom, top; + int err =3D 0, ret; + + bitmap_zero(dirty, vpr->num_chunks); + + /* activate any inactive chunks that overlap this buffer */ + for_each_set_bit(i, buffer->chunks, vpr->num_chunks) { + struct tegra_vpr_chunk *chunk =3D &vpr->chunks[i]; + + if (chunk->active) + continue; + + err =3D tegra_vpr_chunk_alloc(chunk); + if (err < 0) + goto deactivate; + + err =3D tegra_vpr_chunk_activate(chunk); + if (err < 0) { + tegra_vpr_chunk_release(chunk); + goto deactivate; + } + + set_bit(i, vpr->active); + set_bit(i, dirty); + } + + /* + * Activating chunks above may have created holes, but since the VPR + * can only ever be a single contiguous region, make sure to activate + * any missing chunks. + */ + for_each_clear_bitrange(bottom, top, vpr->active, vpr->num_chunks) { + /* inactive chunks at the bottom or the top are harmless */ + if (bottom =3D=3D 0 || top =3D=3D vpr->num_chunks) + continue; + + for (i =3D bottom; i < top; i++) { + struct tegra_vpr_chunk *chunk =3D &vpr->chunks[i]; + + err =3D tegra_vpr_chunk_alloc(chunk); + if (err < 0) + goto deactivate; + + err =3D tegra_vpr_chunk_activate(chunk); + if (err < 0) { + tegra_vpr_chunk_release(chunk); + goto deactivate; + } + + set_bit(i, vpr->active); + set_bit(i, dirty); + } + } + + /* if any chunks have been activated, VPR needs to be resized */ + if (!bitmap_empty(dirty, vpr->num_chunks)) { + err =3D tegra_vpr_resize(vpr); + if (err < 0) { + pr_err("failed to grow VPR: %d\n", err); + goto deactivate; + } + } + + /* increment buffer count for each chunk */ + for_each_set_bit(i, buffer->chunks, vpr->num_chunks) + vpr->chunks[i].num_buffers++; + + return 0; + +deactivate: + /* deactivate any of the previously inactive chunks on failure */ + for_each_set_bit(i, dirty, vpr->num_chunks) { + struct tegra_vpr_chunk *chunk =3D &vpr->chunks[i]; + + ret =3D tegra_vpr_chunk_deactivate(chunk); + if (WARN_ON(ret < 0)) { + pr_err("failed to deactivate chunk #%u: %d\n", i, ret); + } else { + tegra_vpr_chunk_release(chunk); + clear_bit(i, vpr->active); + } + } + + return err; +} + +/* + * Retrieve the range of pages within the activate region of the VPR. + */ +static bool tegra_vpr_get_active_range(struct tegra_vpr *vpr, + unsigned int *first, + unsigned int *last) +{ + unsigned long i, j; + + i =3D find_first_bit(vpr->active, vpr->num_chunks); + if (i >=3D vpr->num_chunks) + return false; + + j =3D find_last_bit(vpr->active, vpr->num_chunks); + if (j >=3D vpr->num_chunks) + return false; + + *first =3D vpr->chunks[i].offset; + *last =3D vpr->chunks[j].offset + vpr->chunks[j].num_pages; + + return true; +} + +/* + * Try to find and allocate a free region within a specific page range. + * Returns the page number if successful, -ENOSPC otherwise. + * + * This function mimics bitmap_find_free_region() but restricts the search + * to a specific range to enable allocation within individual chunks. + */ +static int tegra_vpr_find_free_region_in_range(struct tegra_vpr *vpr, + unsigned int start_page, + unsigned int end_page, + unsigned int num_pages, + unsigned int align) +{ + unsigned int pos, next =3D ALIGN(start_page, align); + + /* Scan through aligned positions, trying to allocate at each one */ + for (pos =3D next; pos + num_pages <=3D end_page; pos =3D next) { + next =3D find_next_bit(vpr->bitmap, pos + num_pages, pos); + + if (next >=3D pos + num_pages) { + bitmap_set(vpr->bitmap, pos, num_pages); + return pos; + } + + next =3D find_next_zero_bit(vpr->bitmap, vpr->num_pages, next); + next =3D ALIGN(next, align); + } + + return -ENOSPC; +} + +static int tegra_vpr_find_free_region(struct tegra_vpr *vpr, + unsigned int num_pages, + unsigned long align) +{ + return tegra_vpr_find_free_region_in_range(vpr, 0, vpr->num_pages - 1, + num_pages, align); +} + +static int tegra_vpr_find_free_region_clustered(struct tegra_vpr *vpr, + unsigned int num_pages, + unsigned int align) +{ + unsigned int target, first, last; + int pageno; + + /* + * If there are no allocations, abort the clustered allocation scheme + * and use the generic allocation scheme instead. + */ + if (vpr->first > vpr->last) + return -ENOSPC; + + /* + * First, try to allocate within the currently allocated region. This + * keeps allocations tightly packed and minimizes the VPR size needed. + */ + pageno =3D tegra_vpr_find_free_region_in_range(vpr, vpr->first, + vpr->last + 1, num_pages, + align); + if (pageno >=3D 0) + return pageno; + + /* + * If not enough free space exists within the currently allocated + * region, check to see if the allocation fits anywhere within the + * active region, avoiding the need to resize the VPR. + */ + if (tegra_vpr_get_active_range(vpr, &first, &last)) { + pageno =3D tegra_vpr_find_free_region_in_range(vpr, first, last, + num_pages, align); + if (pageno >=3D 0) + return pageno; + } + + /* + * If not enough free space exists within the currently active region, + * try to allocate adjacent to it to grow it contiguously and ensure + * optimal packing. + */ + + /* + * Calculate where the allocation should start to end right at the + * first allocated page, with proper alignment. + */ + if (vpr->first >=3D num_pages) { + target =3D ALIGN_DOWN(vpr->first - num_pages, align); + + if (!bitmap_allocate(vpr->bitmap, target, num_pages)) + return target; + } + + /* Try after the last allocation */ + target =3D ALIGN(vpr->last + 1, align); + + if (target + num_pages <=3D vpr->num_pages && + !bitmap_allocate(vpr->bitmap, target, num_pages)) + return target; + + /* + * Couldn't allocate at the ideal adjacent position, search for any + * available space before the first allocated page. + */ + pageno =3D tegra_vpr_find_free_region_in_range(vpr, 0, vpr->first, + num_pages, align); + if (pageno >=3D 0) + return pageno; + + /* + * Couldn't allocate at the ideal adjacent position, search + * for any available space after the last allocated page. + */ + pageno =3D tegra_vpr_find_free_region_in_range(vpr, vpr->last + 1, + vpr->num_pages, num_pages, + align); + if (pageno >=3D 0) + return pageno; + + return -ENOSPC; +} + +/* + * Find a free region, preferring locations near existing allocations to + * minimize VPR fragmentation. The allocation strategy is to first allocate + * within or adjacent to the existing region to keep allocations clustered. + * Otherwise fall back to a generic allocation using the first available + * space. + * + * This approach focuses on page-level allocation first, then the chunk + * system determines which chunks need to be activated based on where the + * pages ended up. + */ +static int tegra_vpr_allocate_region(struct tegra_vpr *vpr, + unsigned int num_pages, + unsigned int align) +{ + int pageno; + + /* + * For non-resizable VPR (no chunks), use simple first-fit allocation. + * Clustering optimization is only beneficial for resizable VPR where + * keeping allocations together minimizes the active VPR size. + */ + if (!vpr->resizable) + return tegra_vpr_find_free_region(vpr, num_pages, align); + + /* + * Check if there are any existing allocations in the bitmap. If so, + * try to allocate near them to minimize fragmentation. + */ + pageno =3D tegra_vpr_find_free_region_clustered(vpr, num_pages, align); + if (pageno >=3D 0) + return pageno; + + /* + * If there are no existing allocations, or no space adjacent to them, + * fall back to the first available space anywhere in the VPR. + */ + pageno =3D tegra_vpr_find_free_region(vpr, num_pages, align); + if (pageno >=3D 0) + return pageno; + + return -ENOSPC; +} + +static struct tegra_vpr_buffer * +tegra_vpr_buffer_allocate(struct tegra_vpr *vpr, size_t size) +{ + unsigned int num_pages =3D size >> PAGE_SHIFT; + unsigned int order =3D get_order(size); + struct tegra_vpr_buffer *buffer; + unsigned long first, last; + int pageno, err; + + /* + * Quick sanity check that we're not trying to allocate a buffer that + * has no chance of fitting into the VPR. + */ + if (size > vpr->size) + return ERR_PTR(-EINVAL); + + /* + * "order" defines the alignment and size, so this may result in + * fragmented memory depending on the allocation patterns. However, + * since this is used primarily for video frames, it is expected that + * a number of buffers of the same size will be allocated, so + * fragmentation should be negligible. + */ + pageno =3D tegra_vpr_allocate_region(vpr, num_pages, 1); + if (pageno < 0) + return ERR_PTR(pageno); + + first =3D find_first_bit(vpr->bitmap, vpr->num_pages); + last =3D find_last_bit(vpr->bitmap, vpr->num_pages); + + buffer =3D kzalloc_obj(*buffer, GFP_KERNEL); + if (!buffer) { + err =3D -ENOMEM; + goto release; + } + + INIT_LIST_HEAD(&buffer->attachments); + INIT_LIST_HEAD(&buffer->list); + mutex_init(&buffer->lock); + buffer->start =3D vpr->base + (pageno << PAGE_SHIFT); + buffer->limit =3D buffer->start + size; + buffer->size =3D size; + buffer->num_pages =3D num_pages; + buffer->pageno =3D pageno; + buffer->order =3D order; + + /* track which chunks this buffer overlaps */ + if (vpr->resizable) { + unsigned int limit =3D buffer->pageno + buffer->num_pages; + pgoff_t i; + + /* + * Memory is backed by struct page, so track which ones we + * use. + */ + buffer->pages =3D kvmalloc_array(buffer->num_pages, + sizeof(*buffer->pages), + GFP_KERNEL); + if (!buffer->pages) { + err =3D -ENOMEM; + goto free; + } + + for (i =3D 0; i < buffer->num_pages; i++) + buffer->pages[i] =3D &vpr->start_page[pageno + i]; + + for (i =3D 0; i < vpr->num_chunks; i++) { + struct tegra_vpr_chunk *chunk =3D &vpr->chunks[i]; + + if (tegra_vpr_chunk_overlaps(chunk, pageno, limit)) + set_bit(i, buffer->chunks); + } + + /* activate chunks if necessary */ + err =3D tegra_vpr_activate_chunks(vpr, buffer); + if (err < 0) { + kfree(buffer->pages); + goto free; + } + + /* track first and last allocated pages */ + if (buffer->pageno < vpr->first) + vpr->first =3D buffer->pageno; + + if (limit - 1 > vpr->last) + vpr->last =3D limit - 1; + } + + return buffer; + +free: + kfree(buffer); +release: + bitmap_clear(vpr->bitmap, pageno, num_pages); + return ERR_PTR(err); +} + +static void tegra_vpr_buffer_release(struct tegra_vpr_buffer *buffer) +{ + struct tegra_vpr *vpr =3D buffer->vpr; + struct tegra_vpr_buffer *entry; + unsigned int i; + + /* + * Decrement buffer count for each overlapping chunk. Note that chunks + * are not deactivated here yet, that's done in tegra_vpr_recycle() + * instead. + */ + for_each_set_bit(i, buffer->chunks, vpr->num_chunks) { + if (!WARN_ON(vpr->chunks[i].num_buffers =3D=3D 0)) + vpr->chunks[i].num_buffers--; + } + + /* track first and last allocated pages */ + if (list_is_first(&buffer->list, &vpr->buffers) && + list_is_last(&buffer->list, &vpr->buffers)) { + /* if there are no remaining buffers after this, reset */ + vpr->first =3D ~0U; + vpr->last =3D 0U; + } else if (list_is_first(&buffer->list, &vpr->buffers)) { + entry =3D list_next_entry(buffer, list); + vpr->first =3D entry->pageno; + } else if (list_is_last(&buffer->list, &vpr->buffers)) { + entry =3D list_prev_entry(buffer, list); + vpr->last =3D entry->pageno + entry->num_pages - 1; + } + + bitmap_clear(vpr->bitmap, buffer->pageno, buffer->num_pages); + list_del(&buffer->list); + kfree(buffer->pages); + kfree(buffer); +} + +static int tegra_vpr_attach(struct dma_buf *buf, + struct dma_buf_attachment *attachment) +{ + struct tegra_vpr_buffer *buffer =3D buf->priv; + struct tegra_vpr_attachment *attach; + int err; + + attach =3D kzalloc_obj(*attach, GFP_KERNEL); + if (!attach) + return -ENOMEM; + + /* + * For resizable VPR, the memory is backed by struct page, so we can + * use the convenient helper to create the SG table. + */ + if (buffer->pages) { + err =3D sg_alloc_table_from_pages(&attach->sgt, buffer->pages, + buffer->num_pages, 0, + buffer->size, GFP_KERNEL); + if (err < 0) + goto free; + } else { + if (sg_alloc_table(&attach->sgt, 1, GFP_KERNEL)) { + err =3D -ENOMEM; + goto free; + } + + sg_set_page(attach->sgt.sgl, NULL, buffer->size, 0); + sg_dma_address(attach->sgt.sgl) =3D buffer->start; + sg_dma_len(attach->sgt.sgl) =3D buffer->size; + } + + attach->dev =3D attachment->dev; + INIT_LIST_HEAD(&attach->list); + attachment->priv =3D attach; + + mutex_lock(&buffer->lock); + list_add(&attach->list, &buffer->attachments); + mutex_unlock(&buffer->lock); + + return 0; + +free: + kfree(attach); + return err; +} + +static void tegra_vpr_detach(struct dma_buf *buf, + struct dma_buf_attachment *attachment) +{ + struct tegra_vpr_buffer *buffer =3D buf->priv; + struct tegra_vpr_attachment *attach =3D attachment->priv; + + mutex_lock(&buffer->lock); + list_del(&attach->list); + mutex_unlock(&buffer->lock); + + sg_free_table(&attach->sgt); + kfree(attach); +} + +static struct sg_table * +tegra_vpr_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct tegra_vpr_attachment *attach =3D attachment->priv; + struct sg_table *sgt =3D &attach->sgt; + int err; + + err =3D dma_map_sgtable(attachment->dev, sgt, direction, + DMA_ATTR_SKIP_CPU_SYNC); + if (err < 0) + return ERR_PTR(err); + + return sgt; +} + +static void tegra_vpr_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *sgt, + enum dma_data_direction direction) +{ + dma_unmap_sgtable(attachment->dev, sgt, direction, + DMA_ATTR_SKIP_CPU_SYNC); +} + +static void tegra_vpr_recycle(struct tegra_vpr *vpr) +{ + DECLARE_BITMAP(dirty, vpr->num_chunks); + unsigned int i; + int err; + + if (!vpr->resizable) + return; + + bitmap_zero(dirty, vpr->num_chunks); + + /* + * Deactivate any unused chunks from the bottom... + */ + for (i =3D 0; i < vpr->num_chunks; i++) { + struct tegra_vpr_chunk *chunk =3D &vpr->chunks[i]; + + if (!chunk->active) + continue; + + if (chunk->num_buffers > 0) + break; + + err =3D tegra_vpr_chunk_deactivate(chunk); + if (err < 0) { + pr_err("failed to deactivate chunk #%u: %d\n", i, err); + goto activate; + } else { + clear_bit(i, vpr->active); + set_bit(i, dirty); + } + } + + /* + * ... and the top. + */ + for (i =3D 0; i < vpr->num_chunks; i++) { + unsigned int index =3D vpr->num_chunks - i - 1; + struct tegra_vpr_chunk *chunk =3D &vpr->chunks[index]; + + if (!chunk->active) + continue; + + if (chunk->num_buffers > 0) + break; + + err =3D tegra_vpr_chunk_deactivate(chunk); + if (err < 0) { + pr_err("failed to deactivate chunk #%u: %d\n", index, + err); + goto activate; + } else { + clear_bit(index, vpr->active); + set_bit(index, dirty); + } + } + + if (!bitmap_empty(dirty, vpr->num_chunks)) { + err =3D tegra_vpr_resize(vpr); + if (err < 0) { + pr_err("failed to shrink VPR: %d\n", err); + goto activate; + } + } + + /* release the CMA memory associated with deactivated chunks */ + for_each_set_bit(i, dirty, vpr->num_chunks) + tegra_vpr_chunk_release(&vpr->chunks[i]); + + return; + +activate: + for_each_set_bit(i, dirty, vpr->num_chunks) { + err =3D tegra_vpr_chunk_activate(&vpr->chunks[i]); + if (WARN_ON(err < 0)) + pr_err("failed to activate chunk #%u: %d\n", i, err); + + /* + * This may not be fully activated at this point, but we need + * to keep track of it anyway to make sure the CMA region can + * eventually be released. The WARN_ON above tells us when it + * happens: here be dragons. + */ + set_bit(i, vpr->active); + } +} + +static void tegra_vpr_release(struct dma_buf *buf) +{ + struct tegra_vpr_buffer *buffer =3D buf->priv; + struct tegra_vpr *vpr =3D buffer->vpr; + + mutex_lock(&vpr->lock); + + tegra_vpr_buffer_release(buffer); + tegra_vpr_recycle(vpr); + + mutex_unlock(&vpr->lock); +} + +/* + * Prohibit userspace mapping because the CPU cannot access this memory + * anyway. + */ +static int tegra_vpr_begin_cpu_access(struct dma_buf *buf, + enum dma_data_direction direction) +{ + return -EPERM; +} + +static int tegra_vpr_end_cpu_access(struct dma_buf *buf, + enum dma_data_direction direction) +{ + return -EPERM; +} + +static int tegra_vpr_mmap(struct dma_buf *buf, struct vm_area_struct *vma) +{ + return -EPERM; +} + +static const struct dma_buf_ops tegra_vpr_buf_ops =3D { + .attach =3D tegra_vpr_attach, + .detach =3D tegra_vpr_detach, + .map_dma_buf =3D tegra_vpr_map_dma_buf, + .unmap_dma_buf =3D tegra_vpr_unmap_dma_buf, + .release =3D tegra_vpr_release, + .begin_cpu_access =3D tegra_vpr_begin_cpu_access, + .end_cpu_access =3D tegra_vpr_end_cpu_access, + .mmap =3D tegra_vpr_mmap, +}; + +static struct dma_buf *tegra_vpr_allocate(struct dma_heap *heap, + unsigned long len, u32 fd_flags, + u64 heap_flags) +{ + struct tegra_vpr *vpr =3D dma_heap_get_drvdata(heap); + struct tegra_vpr_buffer *buffer, *entry; + size_t size =3D ALIGN(len, vpr->align); + DEFINE_DMA_BUF_EXPORT_INFO(export); + struct dma_buf *buf; + + mutex_lock(&vpr->lock); + + buffer =3D tegra_vpr_buffer_allocate(vpr, size); + if (IS_ERR(buffer)) { + mutex_unlock(&vpr->lock); + return ERR_CAST(buffer); + } + + /* insert in the correct order */ + if (!list_empty(&vpr->buffers)) { + list_for_each_entry(entry, &vpr->buffers, list) { + if (buffer->pageno < entry->pageno) { + list_add_tail(&buffer->list, &entry->list); + break; + } + } + } + + if (list_empty(&buffer->list)) + list_add_tail(&buffer->list, &vpr->buffers); + + buffer->vpr =3D vpr; + + /* + * If a valid buffer was allocated, wrap it in a dma_buf + * and return it. + */ + export.exp_name =3D dma_heap_get_name(heap); + export.ops =3D &tegra_vpr_buf_ops; + export.size =3D buffer->size; + export.flags =3D fd_flags; + export.priv =3D buffer; + + buf =3D dma_buf_export(&export); + if (IS_ERR(buf)) { + tegra_vpr_buffer_release(buffer); + tegra_vpr_recycle(vpr); + } + + mutex_unlock(&vpr->lock); + return buf; +} + +static void tegra_vpr_debugfs_show_buffers(struct tegra_vpr *vpr, + struct seq_file *s) +{ + struct tegra_vpr_buffer *buffer; + char buf[16]; + + mutex_lock(&vpr->lock); + + list_for_each_entry(buffer, &vpr->buffers, list) { + string_get_size(buffer->size, 1, STRING_UNITS_2, buf, + sizeof(buf)); + seq_printf(s, " %pap-%pap (%s)\n", &buffer->start, + &buffer->limit, buf); + } + + mutex_unlock(&vpr->lock); +} + +static void tegra_vpr_debugfs_show_chunks(struct tegra_vpr *vpr, + struct seq_file *s) +{ + struct tegra_vpr_buffer *buffer; + unsigned int i; + char buf[16]; + + for (i =3D 0; i < vpr->num_chunks; i++) { + const struct tegra_vpr_chunk *chunk =3D &vpr->chunks[i]; + + string_get_size(chunk->size, 1, STRING_UNITS_2, buf, + sizeof(buf)); + seq_printf(s, " %pap-%pap (%s) (%s, %u buffers)\n", + &chunk->start, &chunk->limit, buf, + chunk->active ? "active" : "inactive", + chunk->num_buffers); + } + + list_for_each_entry(buffer, &vpr->buffers, list) { + string_get_size(buffer->size, 1, STRING_UNITS_2, buf, + sizeof(buf)); + seq_printf(s, "%pap-%pap (%s, chunks: %*pbl)\n", + &buffer->start, &buffer->limit, buf, + vpr->num_chunks, buffer->chunks); + } +} + +static int tegra_vpr_debugfs_show(struct seq_file *s, struct dma_heap *hea= p) +{ + struct tegra_vpr *vpr =3D dma_heap_get_drvdata(heap); + phys_addr_t limit =3D vpr->base + vpr->size; + char buf[16]; + + string_get_size(vpr->size, 1, STRING_UNITS_2, buf, sizeof(buf)); + seq_printf(s, "%pap-%pap (%s)\n", &vpr->base, &limit, buf); + + if (!vpr->resizable) + tegra_vpr_debugfs_show_buffers(vpr, s); + else + tegra_vpr_debugfs_show_chunks(vpr, s); + + return 0; +} + +static const struct dma_heap_ops tegra_vpr_heap_ops =3D { + .allocate =3D tegra_vpr_allocate, + .show =3D tegra_vpr_debugfs_show, +}; + +static int tegra_vpr_setup_chunks(struct tegra_vpr *vpr, const char *name) +{ + phys_addr_t start, limit; + unsigned int order, i =3D 0; + size_t max_size; + int err; + + /* Memory is backed by struct page, so track the first one. */ + vpr->start_page =3D phys_to_page(vpr->base); + + /* This seems a reasonable value, so hard-code it for now. */ + vpr->num_chunks =3D 4; + + vpr->chunks =3D kzalloc_objs(*vpr->chunks, vpr->num_chunks); + if (!vpr->chunks) + return -ENOMEM; + + vpr->active =3D bitmap_zalloc(vpr->num_chunks, GFP_KERNEL); + if (!vpr->active) { + err =3D -ENOMEM; + goto free; + } + + max_size =3D PAGE_SIZE << (get_order(vpr->size) - ilog2(vpr->num_chunks)); + order =3D get_order(vpr->align); + + /* + * Allocate CMA areas for VPR. All areas will be roughtly the same + * size, with the last area taking up the rest. + */ + start =3D vpr->base; + limit =3D vpr->base + vpr->size; + + pr_debug("VPR: %pap-%pap (%lu pages, %u chunks, %lu MiB)\n", &start, + &limit, vpr->num_pages, vpr->num_chunks, + (unsigned long)vpr->size / 1024 / 1024); + + for (i =3D 0; i < vpr->num_chunks; i++) { + size_t size =3D limit - start; + phys_addr_t end; + + size =3D min_t(size_t, size, max_size); + end =3D start + size - 1; + + err =3D tegra_vpr_chunk_init(vpr, &vpr->chunks[i], start, size, + order, name); + if (err < 0) { + pr_err("failed to create VPR chunk: %d\n", err); + goto free; + } + + pr_debug(" %2u: %pap-%pap (%lu MiB)\n", i, &start, &end, + size / 1024 / 1024); + start +=3D size; + } + + vpr->first =3D ~0U; + vpr->last =3D 0U; + + return 0; + +free: + while (i--) + tegra_vpr_chunk_free(&vpr->chunks[i]); + + kfree(vpr->active); + kfree(vpr->chunks); + return err; +} + +static void tegra_vpr_free_chunks(struct tegra_vpr *vpr) +{ + unsigned int i; + + for (i =3D 0; i < vpr->num_chunks; i++) + tegra_vpr_chunk_free(&vpr->chunks[i]); + + kfree(vpr->chunks); +} + +static int tegra_vpr_setup_static(struct tegra_vpr *vpr) +{ + phys_addr_t start, limit; + + start =3D vpr->base; + limit =3D vpr->base + vpr->size; + + pr_debug("VPR: %pap-%pap (%lu pages, %lu MiB)\n", &start, &limit, + vpr->num_pages, (unsigned long)vpr->size / 1024 / 1024); + + return 0; +} + +static int tegra_vpr_add_heap(struct reserved_mem *rmem, + struct device_node *np) +{ + struct dma_heap_export_info info =3D {}; + unsigned long first, last; + struct dma_heap *heap; + struct tegra_vpr *vpr; + int err; + + vpr =3D kzalloc_obj(*vpr, GFP_KERNEL); + if (!vpr) + return -ENOMEM; + + INIT_LIST_HEAD(&vpr->list); + INIT_LIST_HEAD(&vpr->buffers); + INIT_LIST_HEAD(&vpr->devices); + mutex_init(&vpr->lock); + + vpr->resizable =3D !of_property_read_bool(np, "no-map"); + vpr->dev_node =3D of_node_get(np); + vpr->align =3D PAGE_SIZE; + vpr->base =3D rmem->base; + vpr->size =3D rmem->size; + vpr->num_pages =3D vpr->size >> PAGE_SHIFT; + vpr->nid =3D of_node_to_nid(np); + vpr->cma =3D rmem->priv; + + vpr->bitmap =3D bitmap_zalloc(vpr->num_pages, GFP_KERNEL); + if (!vpr->bitmap) { + err =3D -ENOMEM; + goto free; + } + + first =3D find_first_bit(vpr->bitmap, vpr->num_pages); + last =3D find_last_bit(vpr->bitmap, vpr->num_pages); + + if (vpr->resizable) + err =3D tegra_vpr_setup_chunks(vpr, rmem->name); + else + err =3D tegra_vpr_setup_static(vpr); + + if (err < 0) + goto free; + + info.name =3D vpr->dev_node->name; + info.ops =3D &tegra_vpr_heap_ops; + info.priv =3D vpr; + + heap =3D dma_heap_add(&info); + if (IS_ERR(heap)) { + err =3D PTR_ERR(heap); + goto cleanup; + } + + tegra_vpr_add(vpr); + + return 0; + +cleanup: + if (vpr->resizable) + tegra_vpr_free_chunks(vpr); +free: + bitmap_free(vpr->bitmap); + kfree(vpr); + return err; +} + +static int tegra_vpr_init(void) +{ + const char *compatible =3D "nvidia,tegra-video-protection-region"; + struct device_node *parent; + struct reserved_mem *rmem; + int err; + + parent =3D of_find_node_by_path("/reserved-memory"); + if (!parent) + return 0; + + for_each_child_of_node_scoped(parent, child) { + if (!of_device_is_compatible(child, compatible)) + continue; + + rmem =3D of_reserved_mem_lookup(child); + if (!rmem) + continue; + + err =3D tegra_vpr_add_heap(rmem, child); + if (err < 0) + pr_err("failed to add VPR heap for %pOF: %d\n", child, + err); + + /* only a single VPR heap is supported */ + break; + } + + of_node_put(parent); + return 0; +} +module_init(tegra_vpr_init); + +MODULE_DESCRIPTION("NVIDIA Tegra Video-Protection-Region DMA-BUF heap driv= er"); +MODULE_LICENSE("GPL"); diff --git a/drivers/dma-buf/heaps/tegra-vpr.h b/drivers/dma-buf/heaps/tegr= a-vpr.h new file mode 100644 index 000000000000..ba2afba8cc61 --- /dev/null +++ b/drivers/dma-buf/heaps/tegra-vpr.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * DMA-BUF restricted heap exporter for NVIDIA Video-Protection-Region (VP= R) + * + * Copyright (C) 2024-2026 NVIDIA Corporation + */ + +#ifndef DMA_BUF_HEAPS_TEGRA_VPR_H +#define DMA_BUF_HEAPS_TEGRA_VPR_H + +#include +#include + +struct tegra_vpr_device { + struct list_head node; + struct device *dev; +}; + +struct tegra_vpr; + +struct tegra_vpr_chunk { + phys_addr_t start; + phys_addr_t limit; + size_t size; + + struct tegra_vpr *vpr; + bool invalid; + bool active; + + struct page *start_page; + unsigned int offset; + unsigned long virt; + pgoff_t num_pages; + + unsigned int num_buffers; +}; + +struct tegra_vpr { + struct list_head list; + + struct device_node *dev_node; + unsigned long align; + phys_addr_t base; + phys_addr_t size; + int nid; + + struct list_head buffers; + unsigned long *bitmap; + pgoff_t num_pages; + + /* resizable VPR */ + struct cma *cma; + unsigned long *active; + struct tegra_vpr_chunk *chunks; + unsigned int num_chunks; + struct page *start_page; + bool resizable; + + unsigned int first; + unsigned int last; + + struct list_head devices; + + /** + * @lock: Protects concurrent access to the allocation bitmap, as well + * as the buffers and devices lists. + */ + struct mutex lock; +}; + +void tegra_vpr_add(struct tegra_vpr *vpr); + +#endif diff --git a/include/trace/events/tegra_vpr.h b/include/trace/events/tegra_= vpr.h new file mode 100644 index 000000000000..f8ceb17679fe --- /dev/null +++ b/include/trace/events/tegra_vpr.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#if !defined(_TRACE_TEGRA_VPR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_TEGRA_VPR_H + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM tegra_vpr + +#include + +TRACE_EVENT(tegra_vpr_chunk_activate, + TP_PROTO(phys_addr_t start, phys_addr_t limit), + TP_ARGS(start, limit), + TP_STRUCT__entry( + __field(phys_addr_t, start) + __field(phys_addr_t, limit) + ), + TP_fast_assign( + __entry->start =3D start; + __entry->limit =3D limit; + ), + TP_printk("%pap-%pap", &__entry->start, + &__entry->limit) +); + +TRACE_EVENT(tegra_vpr_chunk_deactivate, + TP_PROTO(phys_addr_t start, phys_addr_t limit), + TP_ARGS(start, limit), + TP_STRUCT__entry( + __field(phys_addr_t, start) + __field(phys_addr_t, limit) + ), + TP_fast_assign( + __entry->start =3D start; + __entry->limit =3D limit; + ), + TP_printk("%pap-%pap", &__entry->start, + &__entry->limit) +); + +TRACE_EVENT(tegra_vpr_set, + TP_PROTO(phys_addr_t base, phys_addr_t size), + TP_ARGS(base, size), + TP_STRUCT__entry( + __field(phys_addr_t, start) + __field(phys_addr_t, limit) + ), + TP_fast_assign( + __entry->start =3D base; + __entry->limit =3D base + size; + ), + TP_printk("%pap-%pap", &__entry->start, &__entry->limit) +); + +#endif /* _TRACE_TEGRA_VPR_H */ + +#include --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65882472F87; Fri, 4 Sep 2026 10:45:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518749; cv=none; b=jq6jKMhL3vPApBplfshW7yJsGgAXCcPTC4cwzstoGNbsJsTNQYZxny/+Hs5luNXUl79GtgCDpr/KzakjY3w0epbgiJpaUPepCozGupPO0+LFad6IUJ1VsV1QeHk61GaCnumViFZ7xeYrBXq2bxQwMTUHrokcdp8kVK19dQ77wDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518749; c=relaxed/simple; bh=5EtoJr2asw/bScq7iQsbmEz9QkSjIOA5+gLk9QdMxBE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iwq6a/E7mfz6+yzk0J64IxGgkCo07VhpjEMEHULJFlBiXEq6rHCkpmnfzGywfdzKBQcd6dkdC7Zunzx9uBzDs2B3Qoo+s8N3VHlrj8cpstpHDnzYcoNXLEGK5JVsjqsh/M7x5ejpYrgbish+dcsIiOXTjHLTt6BX/znhXuoTuOc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mdrJ1ddH; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mdrJ1ddH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D04A31F00A3D; Fri, 4 Sep 2026 10:45:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518746; bh=3Jc01ta292IyzRQJ7S0gkfePZTtvrNXCh0bWGk/zJv0=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=mdrJ1ddHAZh0RBFuHKXNfw3fkqkJfmCIOGiJfKTBKm8OhvRyljaX/bBYspXvWQfAb LZBgyRMCh4PrSUIsSvJcJr+0kn+kgqiozuNwWW62jfsITEaPYWqkTxPZttIYwp20qy mDmGrTg3ZtGgFBwGXvX65BhBnuX2jKZ/CPBu1c7J45zFWyEyMf/oqA2RCDQnIfXuh8 N9RlPLyDqzPhOjtsWnOGZX4FQgQRZ2ncNLVHaRMP0tcqDuSU8v9WOSVKr2CP/ONTxl kNhPuylaE7OHka7lwRhqI27ZX1m4J+yYlCfnMk9dsl7PBD3Zk3rnuQAaEUZvpLSCjj /+cOz8R91wZug== From: Thierry Reding Date: Fri, 04 Sep 2026 12:45:01 +0200 Subject: [PATCH v6 10/12] arm64: tegra: Add VPR placeholder node on Tegra234 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-10-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2272; i=treding@nvidia.com; h=from:subject:message-id; bh=tluD4wsCTEuKp0Tp27V1iO02LeJ7xPXs3NTBGtUc+lo=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE7Lt5Anz8aJt2DvjvvqhhLimK66QEmLFp5x boZgxc2ZwiJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOwAKCRDdI6zXfz6z oZ5hD/43CrJtfKpYLCkCb21+kPu526QvefmWAv6kxTjJ9/mrrSYYAYf25vuyeaAPXr9nyDWryjU zq/NsLx+qpynIFU4tV7MxGzjJMYkE6IopYEG7NT6qlIvAq0gPENEhJgSMejC6r0m7s011hz4zqd urzSwLnSUQ6B2wPveIp6PR8IdzXeNtQsxfcq6SfDCx3QDuJZlvL5EAxNDTKs7sBo0T2pLi9fXLZ gwoTvwaZUkqNZdbWET3UY8VzOIEAYg/H+4FxEy6moXbB+lgXHjUP08KaIwGq3axDOVDtnR32Vmr stBa9pFdA8F6T8gs22ScTlAYBVUnJcsjn0KWFfj2v5Jm/PbS6taE2EmstYVgknXM9ilQFm4lHal 9ItIzTg+7NcvCIZsaYk0y/CgWSM4MtjblPjPTIAZFJnL/aqnNmW5Fy7l3wdUpeaAnjDsqPShQ9p SpDCMU0shuMtgu6a9lwAETKx0kJYj2kGnMQbDD7ncJJm/p/XE4OoEeGrS26DcbVWuuFyaeEXwM1 UNOD8mHOzMbZRw88rmbxfGlFs7YR/XPDF7Mqg6JmDb80LQNFb/+jD2A9YjO13QZJ+xIWw/5qSbf Bao6LbbQfVCtnpfkyVNioEs26TBqiyVbXh0QDdpQKUCcC8yJjlw0YI1DpmOfIZTH+eV/RBXAA7n cR6eJAxszH9IjsQ== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding This node contains two sets of properties, one for the case where the VPR is resizable (in which case the VPR region will be dynamically allocated at boot time) and another case where the VPR is fixed in size and initialized by early firmware. The firmware running on the device is responsible for updating the node with the real physical address for the fixed VPR case and remove the properties needed only for resizable VPR. Similarly, if the VPR is resizable, the firmware should remove the "reg" property since it is no longer needed. Signed-off-by: Thierry Reding --- Changes in v3: - comment out fixed VPR properties, assume resizable by default - rename node to "protected" --- arch/arm64/boot/dts/nvidia/tegra234.dtsi | 39 ++++++++++++++++++++++++++++= ++++ 1 file changed, 39 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts= /nvidia/tegra234.dtsi index 5e29316a4d75..6c4739efc8a5 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -29,6 +29,45 @@ aliases { i2c8 =3D &dp_aux_ch3_i2c; }; =20 + reserved-memory { + #address-cells =3D <2>; + #size-cells =3D <2>; + ranges; + + vpr: protected { + compatible =3D "nvidia,tegra-video-protection-region"; + status =3D "disabled"; + + /* + * Two variants exist for this. For fixed VPR, the + * firmware is supposed to update the "reg" property + * with the fixed memory region configured as VPR. + * + * For resizable VPR we don't care about the exact + * address and instead want a reserved region to be + * allocated with a certain size and alignment at + * boot time. + * + * The below assumes resizable VPR by default. If the + * firmwares sets up fixed VPR, it is responsible for + * adding the missing "reg" property, removing any of + * the unused properties, as well as adding a unit- + * address matching the "reg" property. + */ + + /* fixed VPR */ + /* + reg =3D <0x0 0x0 0x0 0x0>; + no-map; + */ + + /* resizable VPR */ + size =3D <0x0 0x70000000>; + alignment =3D <0x0 0x100000>; + reusable; + }; + }; + bus@0 { compatible =3D "simple-bus"; =20 --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E0F6D4071DE; Fri, 4 Sep 2026 10:45:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518752; cv=none; b=g07lsdj0rD/QfhunR14ETHdyzK35KJjJx+bRl2Ag7q6S/bEdrzo24rYlJ50eKCxs/1guUWNYVZz1rb1v8JJPNMe4jTXCDqGVVT+1Y4DYehVF/PYUPm5fi7+l9T2UbLAOjZyV2smssfHQibvoiLgZcqHL5SjqIhXoluAVf+gSHMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518752; c=relaxed/simple; bh=M/R66TK9cvXJNZGsNZJnMU04s2BAQALQxYjf0kzv07A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FMGgQ33TMwYgEnw+RS0qrJvoR9my39RgMUxkOElHJnbZC9tv0GvF9Z3BhHMQ/O8vl1BB6TyD9eZ0SV4zu+zxEhsQ3X4WJTVikfjcO1JNVnM3ZiTWU3ZGGc1nGf7/b4AHszlfKlDAD56UWpSxeHJRC/B67XCjrZB+7zs+auUrdYU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eIcZYSNz; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eIcZYSNz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 98C051F00ACA; Fri, 4 Sep 2026 10:45:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518749; bh=YsqfU4rnOxCjbdNELUfPy2EP2mOE10vhuCcFu2B7Ivw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=eIcZYSNz+EMU1wJDbnZ7IB4nUkt6pmqiN9ypT7xdXDKBetutOJBe6ISblfxsuhABO 8gu9ZrpfWEV8GuQQaIkVaMrKKTsBcPI1a9LVKBPB6lp4vFb4p6MUt1o8J+f8Q9JQ+5 i1zu5i2VpZDULgo04uuwuPTweSqZrxltdhEJW978nE2aEbSz4ONKWizPqUykM5cINR 3Eb4qo29Q25adrLfYNlJiAtOTc4+PdXD6tmqo+3aZAtdCE2rvKqnUXcieI52wq03YJ TckMPq3pX9hclABWT2q5hTtbU0BdWb1968ZkMkzAaazhu2nK5fftv2/tqDszxW0Iii /VFNdlKvValtg== From: Thierry Reding Date: Fri, 04 Sep 2026 12:45:02 +0200 Subject: [PATCH v6 11/12] arm64: tegra: Hook up VPR to host1x Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-11-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1002; i=treding@nvidia.com; h=from:subject:message-id; bh=uOEc0ecGZ8h9g47cFlkUo3cheaRQXqI5mvM+m7jx2j8=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE7YpgB+UW4bihyCTOissm5QATEBPRPgX85W J6eTpZr/RqJAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOwAKCRDdI6zXfz6z oQ2TD/sHzBA2pRG369bC31+gXcK7TapnCz45reqcz4nihHa3IPi+ER91aVZ02HHKlgS8XCmhR5H NQCQtM9uARyGfjdGOuPIYCIeSUJ2tUpUscrh0pzM1PlO2B5R/o/IuOvBpaYXDXo8utSe5muX4xM 1gx8QtCKLfBq/Qp6R5ac6C/ybJtthKei5x8m8FH2opPQ+Kw7ZhODt0tIA6Kyz3EUuyXr1oOaLSl d1uHqpDMyBFcRo9v38nbm9Gu9tcHcee4LYaCWSjp2e27lqDB5ynyOxYPiVqhUPDHODEnE40GSF0 HCPOGK8aWmRdKrLYiiZrnyc34ZDX5tukJ9ylMT6Gsoili58f1VQbTP38Vflhxl3r+ijmgi3XmRs ombeMOdZvJxHCvsaXignsftiQQ8DNLv6+zTkTbGznqfjb1New6aYPoS2HRZ0d82MDn9BFWP/6KN NG2PW/g99K10YYoTpZYQ0lyQAa5zfAh/tKEkwb8avEoHXswF5fUp+Dx+pD1cXlev/6LeEiHtJe7 E/UxTdopwiGCS7COTxnXp/OTH4M7HCrZavExIayJrB8QFFTsfsTtCCdXB1doBC4SAKbDYAfuV3+ Spwv2ajjV1+ob6L4xpL2aITbV7myXUR8GNx919nAJ2d/FleBjFqIl4+PTBjwErta9Mb7Y0V92l2 3X0W6eay5myH43Q== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding The host1x needs access to the VPR region, so make sure to reference it via the memory-region property. Signed-off-by: Thierry Reding --- arch/arm64/boot/dts/nvidia/tegra234.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts= /nvidia/tegra234.dtsi index 6c4739efc8a5..c6a5ced069e7 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -4479,6 +4479,9 @@ vic@15340000 { interconnect-names =3D "dma-mem", "write"; iommus =3D <&smmu_niso1 TEGRA234_SID_VIC>; dma-coherent; + + memory-region =3D <&vpr>; + memory-region-names =3D "protected"; }; =20 nvdec@15480000 { @@ -4497,6 +4500,9 @@ nvdec@15480000 { iommus =3D <&smmu_niso1 TEGRA234_SID_NVDEC>; dma-coherent; =20 + memory-region =3D <&vpr>; + memory-region-names =3D "protected"; + nvidia,memory-controller =3D <&mc>; =20 /* --=20 2.55.0 From nobody Sat Sep 26 05:29:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73218470456; Fri, 4 Sep 2026 10:45:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518754; cv=none; b=rEdwpI/yaWE6oWyk1DYG9+pHJvBzBhqicmb7wSDIhjxE2F4RJFX2tXo2ZwSeJnw0KXsxYB1aGKrqsP7Rhnd461We48Eg+2gamo07N95I5CsXmP6NMNDvGiug0n4UXNvUBVaNMUfX8UwjEY7TUmC5CQj9PpHvOMcUS/5UsaJV67M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788518754; c=relaxed/simple; bh=HZxNmsZi+S62DG3AHdYyAcEUJkoueMrh5HNOsoP0nfw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Rck6iZi637AoEXFvzQbVwUNYxzC6vm1EV8KvOVuIdR3qE+qrE7zsVWwMdA+ZBRRSMp4JUTTVeBqGHI4wJVZtbSE6f888Un78Fq54+Y+T1P0DbvW6E1YxxIOplJR6a1cduwKac41j+/N3DBNnwE9ou5v7vikFdC+eGLCt3AFRz5M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YP9DP3WW; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YP9DP3WW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 590C11F00A3D; Fri, 4 Sep 2026 10:45:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788518752; bh=tp5ZGMgCkDYYyYju3vZvBz8YmJ8LdRAUta1tmaeUPO4=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=YP9DP3WWRHbpiBvqdRY47YbL8PcKvkW6ZXkIs1iXMKrHnkCIpHGrZPLBccBF7fo+9 LV2JfjAHdxT74nfkVvRATWOGtmNEYIfha/f9lSFm+oRgKm90U62Knia62E+zDOb5h8 BQHGnIwPgCVW2OaNJzvAXlgTZb2AbvzmXnUwyoIQQbE5eGYFWO1Di0Lr+YUVs2rnf0 r7W6QnGFNrRfOdMjFQ+XjH/4PTzUJexNHgYqqxF0Lu30hod7dzL+Wyz/10mkHaqB/T O/hvZ9CjdZzI1ffSGAwm/du+AWBMSAkXfEGbuPOSnZdgEhDQUX68+TcEIjfSjIePTl aQbfiX0MrZCSg== From: Thierry Reding Date: Fri, 04 Sep 2026 12:45:03 +0200 Subject: [PATCH v6 12/12] arm64: tegra: Add VPR placeholder node on Tegra264 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-tegra-vpr-v6-12-79042cfa8de5@nvidia.com> References: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> In-Reply-To: <20260904-tegra-vpr-v6-0-79042cfa8de5@nvidia.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thierry Reding , Jonathan Hunter , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Sowjanya Komatineni , Luca Ceresoli , Mikko Perttunen , Yury Norov , Rasmus Villemoes , Russell King , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Marek Szyprowski , Robin Murphy , Sumit Semwal , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , =?utf-8?q?Christian_K=C3=B6nig?= , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Catalin Marinas , Will Deacon , Chun Ng , Mark Rutland , Saravana Kannan Cc: Thierry Reding , devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev, linaro-mm-sig@lists.linaro.org, linux-trace-kernel@vger.kernel.org, Thierry Reding X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2208; i=treding@nvidia.com; h=from:subject:message-id; bh=R7+I3znIc+C4CFBfwF3uhHrkIxj2+n+gJD2B2rW3tV0=; b=owEBbQKS/ZANAwAKAd0jrNd/PrOhAcsmYgBqmqE7rP80/4E7a4eMykLVRISmqrRHTPAuxP98w IQWcaSm6L+JAjMEAAEKAB0WIQSI6sMIAUnM98CNyJ/dI6zXfz6zoQUCapqhOwAKCRDdI6zXfz6z oaKNEACHyKhsBTZ1ctuBVdFSOjnEQ57mTqBOSye23UOv+Cr1ljxFp2QbH5hIEcClwoZOO9RCHkp Ta4o8lXpIGEeh0Os6ntBR3KiBB3v0WNaZwRZMwygvkxDFdGVgZv+m77w6UjOiNOOiwCO3J5sAXi Z1LPXrk5DPnIVRNxKPWenoikUckPR8eZDbkLjzC4i1lugL0pzKxtYA/KfhtpKQ3ySP74CCNVlLR lIV7U3WbT+g1GKMvtGNimuiIRl5iPmXfM+hs0uLpc9uWLGhsLMVfGVUTCmjIDDgabJWY1W/ikVx oKbI5FF342XhJ+LD2NO99czozExIVH/xTcwhhijOUOMPZ5WCV20Z2Ct1BlhkN8a3yK8CweWyWvN 0OoosKFHIGaJw/ZXOKhzODb3vrk0W1sMsJMrrRbAWpXoeNWJhh26wKyk5uZ5kypmlSSv6tSUmSS 0i60LJTaLmdfnl5vZnL2nKNBmpjWdZnT9lhXfDn4/v+saokkEIbUkA5QzpPBWsc/EQSwKN79Hjc t6gbLAylaeVwcS6w/AalDjDGEDVGDQ//gIHc4WSypdbJIpT4N2qhlCQaTIHyq3NxEj8C24lCtvz vJBUWMxwp8mg/mGygNuSa9PivjI7QtLST0GOLttf8SYkBQ0Fa3MYv1YSkoYYglsWVF3WDMfY8I5 2up7C/PXiHlgD7Q== X-Developer-Key: i=treding@nvidia.com; a=openpgp; fpr=88EAC3080149CCF7C08DC89FDD23ACD77F3EB3A1 From: Thierry Reding This node contains two sets of properties, one for the case where the VPR is resizable (in which case the VPR region will be dynamically allocated at boot time) and another case where the VPR is fixed in size and initialized by early firmware. The firmware running on the device is responsible for updating the node with the real physical address for the fixed VPR case and remove the properties needed only for resizable VPR. Similarly, if the VPR is resizable, the firmware should remove the "reg" property since it is no longer needed. Signed-off-by: Thierry Reding --- Changes in v3: - comment out fixed VPR properties, assume resizable by default - rename node to "protected" --- arch/arm64/boot/dts/nvidia/tegra264.dtsi | 33 ++++++++++++++++++++++++++++= ++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts= /nvidia/tegra264.dtsi index 964f18b256b1..998f7e28b9cb 100644 --- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi @@ -24,6 +24,39 @@ shmem_bpmp: shmem@86070000 { reg =3D <0x0 0x86070000 0x0 0x2000>; no-map; }; + + vpr: protected { + compatible =3D "nvidia,tegra-video-protection-region"; + status =3D "disabled"; + + /* + * Two variants exist for this. For fixed VPR, the + * firmware is supposed to update the "reg" property + * with the fixed memory region configured as VPR. + * + * For resizable VPR we don't care about the exact + * address and instead want a reserved region to be + * allocated with a certain size and alignment at + * boot time. + * + * The below assumes resizable VPR by default. If the + * firmwares sets up fixed VPR, it is responsible for + * adding the missing "reg" property, removing any of + * the unused properties, as well as adding a unit- + * address matching the "reg" property. + */ + + /* fixed VPR */ + /* + reg =3D <0x0 0x0 0x0 0x0>; + no-map; + */ + + /* resizable VPR */ + size =3D <0x0 0x70000000>; + alignment =3D <0x0 0x100000>; + reusable; + }; }; =20 /* SYSTEM MMIO */ --=20 2.55.0